113 lines
4.5 KiB
Diff
113 lines
4.5 KiB
Diff
From 3920a727fb19e19f597e518610ce2416d08cb75f Mon Sep 17 00:00:00 2001
|
|
From: Chris Liddell <chris.liddell@artifex.com>
|
|
Date: Thu, 20 Aug 2020 17:19:09 +0100
|
|
Subject: [PATCH] Fix pdfwrite "%d" mode with file permissions
|
|
|
|
Firstly, in gx_device_delete_output_file the iodev pointer was being passed
|
|
to the delete_method incorrectly (passing a pointer to that pointer). Thus
|
|
when we attempted to use that to confirm permission to delete the file, it
|
|
crashed. Credit to Ken for finding that.
|
|
|
|
Secondly, due to the way pdfwrite works, when running with an output file per
|
|
page, it creates the current output file immediately it has completed writing
|
|
the previous one. Thus, it has to delete that partial file on exit.
|
|
|
|
Previously, the output file was not added to the "control" permission list,
|
|
so an attempt to delete it would result in an error. So add the output file
|
|
to the "control" as well as "write" list.
|
|
---
|
|
base/gsdevice.c | 2 +-
|
|
base/gslibctx.c | 20 ++++++++++++++------
|
|
2 files changed, 15 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/base/gsdevice.c b/base/gsdevice.c
|
|
index 9131194951..ac78af93fd 100644
|
|
--- a/base/gsdevice.c
|
|
+++ b/base/gsdevice.c
|
|
@@ -1185,7 +1185,7 @@ int gx_device_delete_output_file(const gx_device * dev, const char *fname)
|
|
parsed.len = strlen(parsed.fname);
|
|
}
|
|
if (parsed.iodev)
|
|
- code = parsed.iodev->procs.delete_file((gx_io_device *)(&parsed.iodev), (const char *)parsed.fname);
|
|
+ code = parsed.iodev->procs.delete_file((gx_io_device *)(parsed.iodev), (const char *)parsed.fname);
|
|
else
|
|
code = gs_note_error(gs_error_invalidfileaccess);
|
|
|
|
diff --git a/base/gslibctx.c b/base/gslibctx.c
|
|
index d726c58b5b..ff8fc895ef 100644
|
|
--- a/base/gslibctx.c
|
|
+++ b/base/gslibctx.c
|
|
@@ -647,7 +647,7 @@ gs_add_outputfile_control_path(gs_memory_t *mem, const char *fname)
|
|
char *fp, f[gp_file_name_sizeof];
|
|
const int pipe = 124; /* ASCII code for '|' */
|
|
const int len = strlen(fname);
|
|
- int i;
|
|
+ int i, code;
|
|
|
|
/* Be sure the string copy will fit */
|
|
if (len >= gp_file_name_sizeof)
|
|
@@ -658,8 +658,6 @@ gs_add_outputfile_control_path(gs_memory_t *mem, const char *fname)
|
|
rewrite_percent_specifiers(f);
|
|
for (i = 0; i < len; i++) {
|
|
if (f[i] == pipe) {
|
|
- int code;
|
|
-
|
|
fp = &f[i + 1];
|
|
/* Because we potentially have to check file permissions at two levels
|
|
for the output file (gx_device_open_output_file and the low level
|
|
@@ -671,10 +669,16 @@ gs_add_outputfile_control_path(gs_memory_t *mem, const char *fname)
|
|
if (code < 0)
|
|
return code;
|
|
break;
|
|
+ code = gs_add_control_path(mem, gs_permit_file_control, f);
|
|
+ if (code < 0)
|
|
+ return code;
|
|
}
|
|
if (!IS_WHITESPACE(f[i]))
|
|
break;
|
|
}
|
|
+ code = gs_add_control_path(mem, gs_permit_file_control, fp);
|
|
+ if (code < 0)
|
|
+ return code;
|
|
return gs_add_control_path(mem, gs_permit_file_writing, fp);
|
|
}
|
|
|
|
@@ -684,7 +688,7 @@ gs_remove_outputfile_control_path(gs_memory_t *mem, const char *fname)
|
|
char *fp, f[gp_file_name_sizeof];
|
|
const int pipe = 124; /* ASCII code for '|' */
|
|
const int len = strlen(fname);
|
|
- int i;
|
|
+ int i, code;
|
|
|
|
/* Be sure the string copy will fit */
|
|
if (len >= gp_file_name_sizeof)
|
|
@@ -694,8 +698,6 @@ gs_remove_outputfile_control_path(gs_memory_t *mem, const char *fname)
|
|
/* Try to rewrite any %d (or similar) in the string */
|
|
for (i = 0; i < len; i++) {
|
|
if (f[i] == pipe) {
|
|
- int code;
|
|
-
|
|
fp = &f[i + 1];
|
|
/* Because we potentially have to check file permissions at two levels
|
|
for the output file (gx_device_open_output_file and the low level
|
|
@@ -704,6 +706,9 @@ gs_remove_outputfile_control_path(gs_memory_t *mem, const char *fname)
|
|
the pipe_fopen(), the leading '|' has been stripped.
|
|
*/
|
|
code = gs_remove_control_path(mem, gs_permit_file_writing, f);
|
|
+ if (code < 0)
|
|
+ return code;
|
|
+ code = gs_remove_control_path(mem, gs_permit_file_control, f);
|
|
if (code < 0)
|
|
return code;
|
|
break;
|
|
@@ -711,6 +716,9 @@ gs_remove_outputfile_control_path(gs_memory_t *mem, const char *fname)
|
|
if (!IS_WHITESPACE(f[i]))
|
|
break;
|
|
}
|
|
+ code = gs_remove_control_path(mem, gs_permit_file_control, fp);
|
|
+ if (code < 0)
|
|
+ return code;
|
|
return gs_remove_control_path(mem, gs_permit_file_writing, fp);
|
|
}
|
|
|