summaryrefslogtreecommitdiff
path: root/psi
diff options
context:
space:
mode:
authorKen Sharp <ken.sharp@artifex.com>2022-08-26 10:07:22 +0100
committerKen Sharp <ken.sharp@artifex.com>2022-08-26 10:07:22 +0100
commitee290c1aebaa172c812f21024af2dbf721fa5865 (patch)
tree3a622d1ebddf5406e0a84ece0fb8a4cd79928f09 /psi
parent19c421c10385b89da8564d664c2c5679c7558035 (diff)
downloadghostpdl-ee290c1aebaa172c812f21024af2dbf721fa5865.tar.gz
graphics library - prevent seg fault in .tempfile
Coverity ID #380524 A seg fault can be reproduced on Windows using this PostScript: (d:\\temp) (w+) .tempfile The problem occurs because on Windows gp_file_name_is_absolute permits either '\' or '/' to be used as a separator, but gp_file_name_separator can (obviously) only return one separator, in this case '/'. This means the loop stripping the prefix fails to find any separator and exits with plen = -1, which causes a seg fault in the memcpy below. The first part of the fix is to check plen and if it's less than 0 exit with an error. The remainder of the commit changes from using the separator string to calling gp_file_name_check_separator instead. This has two benefits; firstly it means that on Windows both separators can be detected, secondly for OS's where the separator is more than a single byte we can still detect it, which we could not before. Ghostscript itself never uses .tempfile with a filename, so this can only occur with PostScript input.
Diffstat (limited to 'psi')
-rw-r--r--psi/zfile.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/psi/zfile.c b/psi/zfile.c
index fe3f7e9f9..e4a2a3e17 100644
--- a/psi/zfile.c
+++ b/psi/zfile.c
@@ -772,18 +772,25 @@ ztempfile(i_ctx_t *i_ctx_p)
if (gp_file_name_is_absolute(pstr, strlen(pstr))) {
int plen = strlen(pstr);
const char *sep = gp_file_name_separator();
-#ifdef DEBUG
int seplen = strlen(sep);
- if (seplen != 1)
+
+ /* This should not be possible if gp_file_name_is_absolute is true I think
+ * But let's avoid the problem.
+ */
+ if (plen < seplen)
return_error(gs_error_Fatal);
-#endif
+
+ plen -= seplen;
/* strip off the file name prefix, leave just the directory name
* so we can check if we are allowed to write to it
*/
for ( ; plen >=0; plen--) {
- if (pstr[plen] == sep[0])
+ if ( gs_file_name_check_separator(&pstr[plen], seplen, &pstr[plen]))
break;
}
+ if (plen < 0)
+ return_error(gs_error_Fatal);
+
memcpy(fname, pstr, plen);
fname[plen] = '\0';
if (check_file_permissions(i_ctx_p, fname, strlen(fname),