gnu: ghostscript: Update replacement to 9.24 [security fixes].
The following CVEs are fixed with this release: CVE-2018-15908, CVE-2018-15909, CVE-2018-15910, CVE-2018-15911, CVE-2018-16509, CVE-2018-16510, CVE-2018-16511, CVE-2018-16513, CVE-2018-16539, CVE-2018-16540, CVE-2018-16541, CVE-2018-16542, CVE-2018-16543. * gnu/packages/patches/ghostscript-CVE-2018-10194.patch: Delete file. * gnu/packages/patches/ghostscript-CVE-2018-16509.patch, gnu/packages/patches/ghostscript-bug-699708.patch: New files. * gnu/local.mk (dist_patch_DATA): Adjust accordingly. * gnu/packages/ghostscript.scm (ghostscript/fixed): Update to 9.24. [source](patches): Remove 'ghostscript-CVE-2018-10194.patch' and 'ghostscript-runpath.patch'. Add 'ghostscript-CVE-2018-16509.patch' and 'ghostscript-bug-699708.patch'. [arguments]: Add LDFLAGS to #:configure-flags, and a phase to create output directory.
This commit is contained in:
parent
910a20e2b8
commit
0084744b3a
|
@ -726,7 +726,8 @@ dist_patch_DATA = \
|
||||||
%D%/packages/patches/geoclue-config.patch \
|
%D%/packages/patches/geoclue-config.patch \
|
||||||
%D%/packages/patches/ghc-8.0-fall-back-to-madv_dontneed.patch \
|
%D%/packages/patches/ghc-8.0-fall-back-to-madv_dontneed.patch \
|
||||||
%D%/packages/patches/ghc-dont-pass-linker-flags-via-response-files.patch \
|
%D%/packages/patches/ghc-dont-pass-linker-flags-via-response-files.patch \
|
||||||
%D%/packages/patches/ghostscript-CVE-2018-10194.patch \
|
%D%/packages/patches/ghostscript-CVE-2018-16509.patch \
|
||||||
|
%D%/packages/patches/ghostscript-bug-699708.patch \
|
||||||
%D%/packages/patches/ghostscript-no-header-id.patch \
|
%D%/packages/patches/ghostscript-no-header-id.patch \
|
||||||
%D%/packages/patches/ghostscript-no-header-uuid.patch \
|
%D%/packages/patches/ghostscript-no-header-uuid.patch \
|
||||||
%D%/packages/patches/ghostscript-no-header-creationdate.patch \
|
%D%/packages/patches/ghostscript-no-header-creationdate.patch \
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
;;; Copyright © 2017 Efraim Flashner <efraim@flashner.co.il>
|
;;; Copyright © 2017 Efraim Flashner <efraim@flashner.co.il>
|
||||||
;;; Copyright © 2017 Leo Famulari <leo@famulari.name>
|
;;; Copyright © 2017 Leo Famulari <leo@famulari.name>
|
||||||
;;; Copyright © 2018 Tobias Geerinckx-Rice <me@tobias.gr>
|
;;; Copyright © 2018 Tobias Geerinckx-Rice <me@tobias.gr>
|
||||||
|
;;; Copyright © 2018 Marius Bakke <mbakke@fastmail.com>
|
||||||
;;;
|
;;;
|
||||||
;;; This file is part of GNU Guix.
|
;;; This file is part of GNU Guix.
|
||||||
;;;
|
;;;
|
||||||
|
@ -38,8 +39,10 @@
|
||||||
#:use-module ((guix licenses) #:prefix license:)
|
#:use-module ((guix licenses) #:prefix license:)
|
||||||
#:use-module (guix packages)
|
#:use-module (guix packages)
|
||||||
#:use-module (guix download)
|
#:use-module (guix download)
|
||||||
|
#:use-module (guix utils)
|
||||||
#:use-module (guix build-system gnu)
|
#:use-module (guix build-system gnu)
|
||||||
#:use-module (guix build-system trivial))
|
#:use-module (guix build-system trivial)
|
||||||
|
#:use-module (srfi srfi-1))
|
||||||
|
|
||||||
(define-public lcms
|
(define-public lcms
|
||||||
(package
|
(package
|
||||||
|
@ -255,11 +258,39 @@ output file formats and printers.")
|
||||||
(hidden-package
|
(hidden-package
|
||||||
(package
|
(package
|
||||||
(inherit ghostscript)
|
(inherit ghostscript)
|
||||||
|
(version "9.24")
|
||||||
(source
|
(source
|
||||||
(origin
|
(origin
|
||||||
(inherit (package-source ghostscript))
|
(inherit (package-source ghostscript))
|
||||||
(patches (append (origin-patches (package-source ghostscript))
|
(uri (string-append "https://github.com/ArtifexSoftware/"
|
||||||
(search-patches "ghostscript-CVE-2018-10194.patch"))))))))
|
"ghostpdl-downloads/releases/download/gs"
|
||||||
|
(string-delete #\. version)
|
||||||
|
"/ghostscript-" version ".tar.xz"))
|
||||||
|
(sha256
|
||||||
|
(base32
|
||||||
|
"1mk922rnml93w2g42yxiyn8xqanc50cm65irrgh0b6lp4kgifjfl"))
|
||||||
|
(patches (search-patches "ghostscript-CVE-2018-16509.patch"
|
||||||
|
"ghostscript-bug-699708.patch"
|
||||||
|
"ghostscript-no-header-creationdate.patch"
|
||||||
|
"ghostscript-no-header-id.patch"
|
||||||
|
"ghostscript-no-header-uuid.patch"))))
|
||||||
|
(arguments
|
||||||
|
(substitute-keyword-arguments (package-arguments ghostscript)
|
||||||
|
((#:configure-flags flags)
|
||||||
|
;; Notice that we removed the 'ghostscript-runpath' patch above.
|
||||||
|
;; The reason is that it conflicts with an upstream change that
|
||||||
|
;; takes LDFLAGS into account.
|
||||||
|
`(cons (string-append "LDFLAGS=-Wl,-rpath="
|
||||||
|
(assoc-ref %outputs "out") "/lib")
|
||||||
|
,flags))
|
||||||
|
((#:phases phases)
|
||||||
|
`(modify-phases ,phases
|
||||||
|
(add-before 'configure 'create-output-directory
|
||||||
|
(lambda* (#:key outputs #:allow-other-keys)
|
||||||
|
;; Unfortunately the configure script refuses to function if
|
||||||
|
;; the directory specified as -rpath does not already exist.
|
||||||
|
(mkdir-p (string-append (assoc-ref outputs "out") "/lib"))
|
||||||
|
#t)))))))))
|
||||||
|
|
||||||
(define-public ghostscript/x
|
(define-public ghostscript/x
|
||||||
(package/inherit ghostscript
|
(package/inherit ghostscript
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
Fix CVE-2018-10194:
|
|
||||||
|
|
||||||
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-10194
|
|
||||||
https://bugs.ghostscript.com/show_bug.cgi?id=699255
|
|
||||||
|
|
||||||
Patch copied from upstream source repository:
|
|
||||||
|
|
||||||
https://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=39b1e54b2968620723bf32e96764c88797714879
|
|
||||||
|
|
||||||
From 39b1e54b2968620723bf32e96764c88797714879 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ken Sharp <ken.sharp@artifex.com>
|
|
||||||
Date: Wed, 18 Apr 2018 15:46:32 +0100
|
|
||||||
Subject: [PATCH] pdfwrite - Guard against trying to output an infinite number
|
|
||||||
|
|
||||||
Bug #699255 " Buffer overflow on pprintg1 due to mishandle postscript file data to pdf"
|
|
||||||
|
|
||||||
The file uses an enormous parameter to xyxhow, causing an overflow in
|
|
||||||
the calculation of text positioning (value > 1e39).
|
|
||||||
|
|
||||||
Since this is basically a nonsense value, and PostScript only supports
|
|
||||||
real values up to 1e38, this patch follows the same approach as for
|
|
||||||
a degenerate CTM, and treats it as 0.
|
|
||||||
|
|
||||||
Adobe Acrobat Distiller throws a limitcheck error, so we could do that
|
|
||||||
instead if this approach proves to be a problem.
|
|
||||||
---
|
|
||||||
devices/vector/gdevpdts.c | 7 ++++++-
|
|
||||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/devices/vector/gdevpdts.c b/devices/vector/gdevpdts.c
|
|
||||||
index 848ad781f..172fe6bc3 100644
|
|
||||||
--- a/devices/vector/gdevpdts.c
|
|
||||||
+++ b/devices/vector/gdevpdts.c
|
|
||||||
@@ -103,9 +103,14 @@ append_text_move(pdf_text_state_t *pts, double dw)
|
|
||||||
static int
|
|
||||||
set_text_distance(gs_point *pdist, double dx, double dy, const gs_matrix *pmat)
|
|
||||||
{
|
|
||||||
- int code = gs_distance_transform_inverse(dx, dy, pmat, pdist);
|
|
||||||
+ int code;
|
|
||||||
double rounded;
|
|
||||||
|
|
||||||
+ if (dx > 1e38 || dy > 1e38)
|
|
||||||
+ code = gs_error_undefinedresult;
|
|
||||||
+ else
|
|
||||||
+ code = gs_distance_transform_inverse(dx, dy, pmat, pdist);
|
|
||||||
+
|
|
||||||
if (code == gs_error_undefinedresult) {
|
|
||||||
/* The CTM is degenerate.
|
|
||||||
Can't know the distance in user space.
|
|
||||||
--
|
|
||||||
2.18.0
|
|
||||||
|
|
|
@ -0,0 +1,193 @@
|
||||||
|
Ghostscript 9.24 was released with an incomplete fix for CVE-2018-16509:
|
||||||
|
https://nvd.nist.gov/vuln/detail/CVE-2018-16509
|
||||||
|
https://bugs.chromium.org/p/project-zero/issues/detail?id=1640#c19
|
||||||
|
https://bugs.ghostscript.com/show_bug.cgi?id=699718
|
||||||
|
|
||||||
|
The reproducers no longer work after applying these commits:
|
||||||
|
|
||||||
|
https://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=5812b1b78fc4d36fdc293b7859de69241140d590
|
||||||
|
https://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=e914f1da46e33decc534486598dc3eadf69e6efb
|
||||||
|
https://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=3e5d316b72e3965b7968bb1d96baa137cd063ac6
|
||||||
|
https://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=643b24dbd002fb9c131313253c307cf3951b3d47
|
||||||
|
|
||||||
|
This patch is a "squashed" version of those.
|
||||||
|
|
||||||
|
diff --git a/Resource/Init/gs_setpd.ps b/Resource/Init/gs_setpd.ps
|
||||||
|
index bba3c8c0e..8fa7c51df 100644
|
||||||
|
--- a/Resource/Init/gs_setpd.ps
|
||||||
|
+++ b/Resource/Init/gs_setpd.ps
|
||||||
|
@@ -95,27 +95,41 @@ level2dict begin
|
||||||
|
{ % Since setpagedevice doesn't create new device objects,
|
||||||
|
% we must (carefully) reinstall the old parameters in
|
||||||
|
% the same device.
|
||||||
|
- .currentpagedevice pop //null currentdevice //null .trysetparams
|
||||||
|
+ .currentpagedevice pop //null currentdevice //null
|
||||||
|
+ { .trysetparams } .internalstopped
|
||||||
|
+ {
|
||||||
|
+ //null
|
||||||
|
+ } if
|
||||||
|
dup type /booleantype eq
|
||||||
|
{ pop pop }
|
||||||
|
- { % This should never happen!
|
||||||
|
+ {
|
||||||
|
SETPDDEBUG { (Error in .trysetparams!) = pstack flush } if
|
||||||
|
- cleartomark pop pop pop
|
||||||
|
+ {cleartomark pop pop pop} .internalstopped pop
|
||||||
|
+ % if resetting the entire device state failed, at least put back the
|
||||||
|
+ % security related key
|
||||||
|
+ currentdevice //null //false mark /.LockSafetyParams
|
||||||
|
+ currentpagedevice /.LockSafetyParams .knownget not
|
||||||
|
+ {systemdict /SAFER .knownget not {//false} } if
|
||||||
|
+ .putdeviceparamsonly
|
||||||
|
/.installpagedevice cvx /rangecheck signalerror
|
||||||
|
}
|
||||||
|
ifelse pop pop
|
||||||
|
% A careful reading of the Red Book reveals that an erasepage
|
||||||
|
% should occur, but *not* an initgraphics.
|
||||||
|
erasepage .beginpage
|
||||||
|
- } bind def
|
||||||
|
+ } bind executeonly def
|
||||||
|
|
||||||
|
/.uninstallpagedevice
|
||||||
|
- { 2 .endpage { .currentnumcopies //false .outputpage } if
|
||||||
|
+ {
|
||||||
|
+ {2 .endpage { .currentnumcopies //false .outputpage } if} .internalstopped pop
|
||||||
|
nulldevice
|
||||||
|
} bind def
|
||||||
|
|
||||||
|
(%grestorepagedevice) cvn
|
||||||
|
- { .uninstallpagedevice grestore .installpagedevice
|
||||||
|
+ {
|
||||||
|
+ .uninstallpagedevice
|
||||||
|
+ grestore
|
||||||
|
+ .installpagedevice
|
||||||
|
} bind def
|
||||||
|
|
||||||
|
(%grestoreallpagedevice) cvn
|
||||||
|
diff --git a/psi/zdevice2.c b/psi/zdevice2.c
|
||||||
|
index 0c7080d57..159a0c0d9 100644
|
||||||
|
--- a/psi/zdevice2.c
|
||||||
|
+++ b/psi/zdevice2.c
|
||||||
|
@@ -251,8 +251,8 @@ z2currentgstate(i_ctx_t *i_ctx_p)
|
||||||
|
/* ------ Wrappers for operators that reset the graphics state. ------ */
|
||||||
|
|
||||||
|
/* Check whether we need to call out to restore the page device. */
|
||||||
|
-static bool
|
||||||
|
-restore_page_device(const gs_gstate * pgs_old, const gs_gstate * pgs_new)
|
||||||
|
+static int
|
||||||
|
+restore_page_device(i_ctx_t *i_ctx_p, const gs_gstate * pgs_old, const gs_gstate * pgs_new)
|
||||||
|
{
|
||||||
|
gx_device *dev_old = gs_currentdevice(pgs_old);
|
||||||
|
gx_device *dev_new;
|
||||||
|
@@ -260,9 +260,10 @@ restore_page_device(const gs_gstate * pgs_old, const gs_gstate * pgs_new)
|
||||||
|
gx_device *dev_t2;
|
||||||
|
bool samepagedevice = obj_eq(dev_old->memory, &gs_int_gstate(pgs_old)->pagedevice,
|
||||||
|
&gs_int_gstate(pgs_new)->pagedevice);
|
||||||
|
+ bool LockSafetyParams = dev_old->LockSafetyParams;
|
||||||
|
|
||||||
|
if ((dev_t1 = (*dev_proc(dev_old, get_page_device)) (dev_old)) == 0)
|
||||||
|
- return false;
|
||||||
|
+ return 0;
|
||||||
|
/* If we are going to putdeviceparams in a callout, we need to */
|
||||||
|
/* unlock temporarily. The device will be re-locked as needed */
|
||||||
|
/* by putdeviceparams from the pgs_old->pagedevice dict state. */
|
||||||
|
@@ -271,23 +272,51 @@ restore_page_device(const gs_gstate * pgs_old, const gs_gstate * pgs_new)
|
||||||
|
dev_new = gs_currentdevice(pgs_new);
|
||||||
|
if (dev_old != dev_new) {
|
||||||
|
if ((dev_t2 = (*dev_proc(dev_new, get_page_device)) (dev_new)) == 0)
|
||||||
|
- return false;
|
||||||
|
- if (dev_t1 != dev_t2)
|
||||||
|
- return true;
|
||||||
|
+ samepagedevice = true;
|
||||||
|
+ else if (dev_t1 != dev_t2)
|
||||||
|
+ samepagedevice = false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (LockSafetyParams && !samepagedevice) {
|
||||||
|
+ const int required_ops = 512;
|
||||||
|
+ const int required_es = 32;
|
||||||
|
+
|
||||||
|
+ /* The %grestorepagedevice must complete: the biggest danger
|
||||||
|
+ is operand stack overflow. As we use get/putdeviceparams
|
||||||
|
+ that means pushing all the device params onto the stack,
|
||||||
|
+ pdfwrite having by far the largest number of parameters
|
||||||
|
+ at (currently) 212 key/value pairs - thus needing (currently)
|
||||||
|
+ 424 entries on the op stack. Allowing for working stack
|
||||||
|
+ space, and safety margin.....
|
||||||
|
+ */
|
||||||
|
+ if (required_ops + ref_stack_count(&o_stack) >= ref_stack_max_count(&o_stack)) {
|
||||||
|
+ gs_currentdevice(pgs_old)->LockSafetyParams = LockSafetyParams;
|
||||||
|
+ return_error(gs_error_stackoverflow);
|
||||||
|
+ }
|
||||||
|
+ /* We also want enough exec stack space - 32 is an overestimate of
|
||||||
|
+ what we need to complete the Postscript call out.
|
||||||
|
+ */
|
||||||
|
+ if (required_es + ref_stack_count(&e_stack) >= ref_stack_max_count(&e_stack)) {
|
||||||
|
+ gs_currentdevice(pgs_old)->LockSafetyParams = LockSafetyParams;
|
||||||
|
+ return_error(gs_error_execstackoverflow);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* The current implementation of setpagedevice just sets new
|
||||||
|
* parameters in the same device object, so we have to check
|
||||||
|
* whether the page device dictionaries are the same.
|
||||||
|
*/
|
||||||
|
- return !samepagedevice;
|
||||||
|
+ return samepagedevice ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* - grestore - */
|
||||||
|
static int
|
||||||
|
z2grestore(i_ctx_t *i_ctx_p)
|
||||||
|
{
|
||||||
|
- if (!restore_page_device(igs, gs_gstate_saved(igs)))
|
||||||
|
+ int code = restore_page_device(i_ctx_p, igs, gs_gstate_saved(igs));
|
||||||
|
+ if (code < 0) return code;
|
||||||
|
+
|
||||||
|
+ if (code == 0)
|
||||||
|
return gs_grestore(igs);
|
||||||
|
return push_callout(i_ctx_p, "%grestorepagedevice");
|
||||||
|
}
|
||||||
|
@@ -297,7 +326,9 @@ static int
|
||||||
|
z2grestoreall(i_ctx_t *i_ctx_p)
|
||||||
|
{
|
||||||
|
for (;;) {
|
||||||
|
- if (!restore_page_device(igs, gs_gstate_saved(igs))) {
|
||||||
|
+ int code = restore_page_device(i_ctx_p, igs, gs_gstate_saved(igs));
|
||||||
|
+ if (code < 0) return code;
|
||||||
|
+ if (code == 0) {
|
||||||
|
bool done = !gs_gstate_saved(gs_gstate_saved(igs));
|
||||||
|
|
||||||
|
gs_grestore(igs);
|
||||||
|
@@ -328,11 +359,15 @@ z2restore(i_ctx_t *i_ctx_p)
|
||||||
|
if (code < 0) return code;
|
||||||
|
|
||||||
|
while (gs_gstate_saved(gs_gstate_saved(igs))) {
|
||||||
|
- if (restore_page_device(igs, gs_gstate_saved(igs)))
|
||||||
|
+ code = restore_page_device(i_ctx_p, igs, gs_gstate_saved(igs));
|
||||||
|
+ if (code < 0) return code;
|
||||||
|
+ if (code > 0)
|
||||||
|
return push_callout(i_ctx_p, "%restore1pagedevice");
|
||||||
|
gs_grestore(igs);
|
||||||
|
}
|
||||||
|
- if (restore_page_device(igs, gs_gstate_saved(igs)))
|
||||||
|
+ code = restore_page_device(i_ctx_p, igs, gs_gstate_saved(igs));
|
||||||
|
+ if (code < 0) return code;
|
||||||
|
+ if (code > 0)
|
||||||
|
return push_callout(i_ctx_p, "%restorepagedevice");
|
||||||
|
|
||||||
|
code = dorestore(i_ctx_p, asave);
|
||||||
|
@@ -355,9 +390,12 @@ static int
|
||||||
|
z2setgstate(i_ctx_t *i_ctx_p)
|
||||||
|
{
|
||||||
|
os_ptr op = osp;
|
||||||
|
+ int code;
|
||||||
|
|
||||||
|
check_stype(*op, st_igstate_obj);
|
||||||
|
- if (!restore_page_device(igs, igstate_ptr(op)))
|
||||||
|
+ code = restore_page_device(i_ctx_p, igs, igstate_ptr(op));
|
||||||
|
+ if (code < 0) return code;
|
||||||
|
+ if (code == 0)
|
||||||
|
return zsetgstate(i_ctx_p);
|
||||||
|
return push_callout(i_ctx_p, "%setgstatepagedevice");
|
||||||
|
}
|
|
@ -0,0 +1,160 @@
|
||||||
|
Additional security fix that missed 9.24.
|
||||||
|
|
||||||
|
Taken from upstream:
|
||||||
|
http://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=fb713b3818b52d8a6cf62c951eba2e1795ff9624
|
||||||
|
|
||||||
|
From fb713b3818b52d8a6cf62c951eba2e1795ff9624 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Chris Liddell <chris.liddell@artifex.com>
|
||||||
|
Date: Thu, 6 Sep 2018 09:16:22 +0100
|
||||||
|
Subject: [PATCH] Bug 699708 (part 1): 'Hide' non-replaceable error handlers
|
||||||
|
for SAFER
|
||||||
|
|
||||||
|
We already had a 'private' dictionary for non-standard errors: gserrordict.
|
||||||
|
|
||||||
|
This now includes all the default error handlers, the dictionary is made
|
||||||
|
noaccess and all the prodedures are bound and executeonly.
|
||||||
|
|
||||||
|
When running with -dSAFER, in the event of a Postscript error, instead of
|
||||||
|
pulling the handler from errordict, we'll pull it from gserrordict - thus
|
||||||
|
malicious input cannot trigger problems by the use of custom error handlers.
|
||||||
|
|
||||||
|
errordict remains open and writeable, so files such as the Quality Logic tests
|
||||||
|
that install their own handlers will still 'work', with the exception that the
|
||||||
|
custom error handlers will not be called.
|
||||||
|
|
||||||
|
This is a 'first pass', 'sledgehammer' approach: a nice addition would to allow
|
||||||
|
an integrator to specify a list of errors that are not to be replaced (for
|
||||||
|
example, embedded applications would probably want to ensure that VMerror is
|
||||||
|
always handled as they intend).
|
||||||
|
---
|
||||||
|
Resource/Init/gs_init.ps | 29 ++++++++++++++++++-----------
|
||||||
|
psi/interp.c | 30 +++++++++++++++++++++---------
|
||||||
|
2 files changed, 39 insertions(+), 20 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps
|
||||||
|
index 071c39205..bc8b7951c 100644
|
||||||
|
--- a/Resource/Init/gs_init.ps
|
||||||
|
+++ b/Resource/Init/gs_init.ps
|
||||||
|
@@ -881,7 +881,7 @@ userdict /.currentresourcefile //null put
|
||||||
|
{ not exch pop exit } { pop } ifelse
|
||||||
|
}
|
||||||
|
for exch pop .quit
|
||||||
|
- } bind def
|
||||||
|
+ } bind executeonly def
|
||||||
|
/.errorhandler % <command> <errorname> .errorhandler -
|
||||||
|
{ % Detect an internal 'stopped'.
|
||||||
|
1 .instopped { //null eq { pop pop stop } if } if
|
||||||
|
@@ -926,7 +926,7 @@ userdict /.currentresourcefile //null put
|
||||||
|
$error /globalmode get $error /.nosetlocal get and .setglobal
|
||||||
|
$error /.inerror //false put
|
||||||
|
stop
|
||||||
|
- } bind def
|
||||||
|
+ } bind executeonly def
|
||||||
|
% Define the standard handleerror. We break out the printing procedure
|
||||||
|
% (.printerror) so that it can be extended for binary output
|
||||||
|
% if the Level 2 facilities are present.
|
||||||
|
@@ -976,7 +976,7 @@ userdict /.currentresourcefile //null put
|
||||||
|
ifelse % newerror
|
||||||
|
end
|
||||||
|
flush
|
||||||
|
- } bind def
|
||||||
|
+ } bind executeonly def
|
||||||
|
/.printerror_long % long error printout,
|
||||||
|
% $error is on the dict stack
|
||||||
|
{ % Push the (anonymous) stack printing procedure.
|
||||||
|
@@ -1053,14 +1053,14 @@ userdict /.currentresourcefile //null put
|
||||||
|
{ (Current file position is ) print position = }
|
||||||
|
if
|
||||||
|
|
||||||
|
- } bind def
|
||||||
|
+ } bind executeonly def
|
||||||
|
% Define a procedure for clearing the error indication.
|
||||||
|
/.clearerror
|
||||||
|
{ $error /newerror //false put
|
||||||
|
$error /errorname //null put
|
||||||
|
$error /errorinfo //null put
|
||||||
|
0 .setoserrno
|
||||||
|
- } bind def
|
||||||
|
+ } bind executeonly def
|
||||||
|
|
||||||
|
% Define $error. This must be in local VM.
|
||||||
|
.currentglobal //false .setglobal
|
||||||
|
@@ -1086,11 +1086,15 @@ end
|
||||||
|
/errordict ErrorNames length 3 add dict
|
||||||
|
.forcedef % errordict is local, systemdict is global
|
||||||
|
.setglobal % back to global VM
|
||||||
|
-% For greater Adobe compatibility, we put all non-standard errors in a
|
||||||
|
-% separate dictionary, gserrordict. It does not need to be in local VM,
|
||||||
|
-% because PostScript programs do not access it.
|
||||||
|
+% gserrordict contains all the default error handling methods, but unlike
|
||||||
|
+% errordict it is noaccess after creation (also it is in global VM).
|
||||||
|
+% When running 'SAFER', we'll ignore the contents of errordict, which
|
||||||
|
+% may have been tampered with by the running job, and always use gserrordict
|
||||||
|
+% gserrordict also contains any non-standard errors, for better compatibility
|
||||||
|
+% with Adobe.
|
||||||
|
+%
|
||||||
|
% NOTE: the name gserrordict is known to the interpreter.
|
||||||
|
-/gserrordict 5 dict def
|
||||||
|
+/gserrordict ErrorNames length 3 add dict def
|
||||||
|
% Register an error in errordict. We make this a procedure because we only
|
||||||
|
% register the Level 1 errors here: the rest are registered by "feature"
|
||||||
|
% files. However, ErrorNames contains all of the error names regardless of
|
||||||
|
@@ -1119,8 +1123,11 @@ errordict begin
|
||||||
|
} bind def
|
||||||
|
end % errordict
|
||||||
|
|
||||||
|
-% Put non-standard errors in gserrordict.
|
||||||
|
-gserrordict /unknownerror errordict /unknownerror get put
|
||||||
|
+% Put all the default handlers in gserrordict
|
||||||
|
+gserrordict
|
||||||
|
+errordict {2 index 3 1 roll put} forall
|
||||||
|
+noaccess pop
|
||||||
|
+% remove the non-standard errors from errordict
|
||||||
|
errordict /unknownerror .undef
|
||||||
|
% Define a stable private copy of handleerror that we will always use under
|
||||||
|
% JOBSERVER mode.
|
||||||
|
diff --git a/psi/interp.c b/psi/interp.c
|
||||||
|
index c27b70dca..d41a9d3f5 100644
|
||||||
|
--- a/psi/interp.c
|
||||||
|
+++ b/psi/interp.c
|
||||||
|
@@ -661,16 +661,28 @@ again:
|
||||||
|
return code;
|
||||||
|
if (gs_errorname(i_ctx_p, code, &error_name) < 0)
|
||||||
|
return code; /* out-of-range error code! */
|
||||||
|
- /*
|
||||||
|
- * For greater Adobe compatibility, only the standard PostScript errors
|
||||||
|
- * are defined in errordict; the rest are in gserrordict.
|
||||||
|
+
|
||||||
|
+ /* If LockFilePermissions is true, we only refer to gserrordict, which
|
||||||
|
+ * is not accessible to Postcript jobs
|
||||||
|
*/
|
||||||
|
- if (dict_find_string(systemdict, "errordict", &perrordict) <= 0 ||
|
||||||
|
- (dict_find(perrordict, &error_name, &epref) <= 0 &&
|
||||||
|
- (dict_find_string(systemdict, "gserrordict", &perrordict) <= 0 ||
|
||||||
|
- dict_find(perrordict, &error_name, &epref) <= 0))
|
||||||
|
- )
|
||||||
|
- return code; /* error name not in errordict??? */
|
||||||
|
+ if (i_ctx_p->LockFilePermissions) {
|
||||||
|
+ if (((dict_find_string(systemdict, "gserrordict", &perrordict) <= 0 ||
|
||||||
|
+ dict_find(perrordict, &error_name, &epref) <= 0))
|
||||||
|
+ )
|
||||||
|
+ return code; /* error name not in errordict??? */
|
||||||
|
+ }
|
||||||
|
+ else {
|
||||||
|
+ /*
|
||||||
|
+ * For greater Adobe compatibility, only the standard PostScript errors
|
||||||
|
+ * are defined in errordict; the rest are in gserrordict.
|
||||||
|
+ */
|
||||||
|
+ if (dict_find_string(systemdict, "errordict", &perrordict) <= 0 ||
|
||||||
|
+ (dict_find(perrordict, &error_name, &epref) <= 0 &&
|
||||||
|
+ (dict_find_string(systemdict, "gserrordict", &perrordict) <= 0 ||
|
||||||
|
+ dict_find(perrordict, &error_name, &epref) <= 0))
|
||||||
|
+ )
|
||||||
|
+ return code; /* error name not in errordict??? */
|
||||||
|
+ }
|
||||||
|
doref = *epref;
|
||||||
|
epref = &doref;
|
||||||
|
/* Push the error object on the operand stack if appropriate. */
|
||||||
|
--
|
||||||
|
2.18.0
|
||||||
|
|
Loading…
Reference in New Issue