You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
842 lines
29 KiB
842 lines
29 KiB
From b0222e5e39712999f22084996a6b85a120b9389e Mon Sep 17 00:00:00 2001 |
|
From: Chris Liddell <chris.liddell@artifex.com> |
|
Date: Thu, 20 Sep 2018 16:35:28 +0100 |
|
Subject: [PATCH 1/6] Bug 699795: add operand checking to |
|
.setnativefontmapbuilt |
|
|
|
.setnativefontmapbuilt .forceputs a value into systemdict - it is intended |
|
to be a boolean, but in this case was being called with a compound object |
|
(a dictionary). Such an object, in local VM, being forced into systemdict |
|
would then confuse the garbager, since it could be restored away with the |
|
reference remaining. |
|
|
|
This adds operand checking, so .setnativefontmapbuilt will simply ignore |
|
anything other than a boolean value, and also removes the definition of |
|
.setnativefontmapbuilt after use, since it is only used in two, closely |
|
related places. |
|
--- |
|
Resource/Init/gs_fonts.ps | 11 ++++++++--- |
|
1 file changed, 8 insertions(+), 3 deletions(-) |
|
|
|
diff --git a/Resource/Init/gs_fonts.ps b/Resource/Init/gs_fonts.ps |
|
index 38f0f6c..45b6613 100644 |
|
--- a/Resource/Init/gs_fonts.ps |
|
+++ b/Resource/Init/gs_fonts.ps |
|
@@ -372,9 +372,13 @@ FONTPATH length 0 eq { (%END FONTPATH) .skipeof } if |
|
% of strings: what the system thinks is the ps name, |
|
% and the access path. |
|
/.setnativefontmapbuilt { % set whether we've been run |
|
- systemdict exch /.nativefontmapbuilt exch .forceput |
|
+ dup type /booleantype eq { |
|
+ systemdict exch /.nativefontmapbuilt exch .forceput |
|
+ } |
|
+ {pop} |
|
+ ifelse |
|
} .bind executeonly def |
|
-systemdict /NONATIVEFONTMAP known .setnativefontmapbuilt |
|
+systemdict /NONATIVEFONTMAP known //.setnativefontmapbuilt exec |
|
/.buildnativefontmap { % - .buildnativefontmap <bool> |
|
systemdict /.nativefontmapbuilt .knownget not |
|
{ //false} if |
|
@@ -415,9 +419,10 @@ systemdict /NONATIVEFONTMAP known .setnativefontmapbuilt |
|
} forall |
|
} if |
|
% record that we've been run |
|
- //true .setnativefontmapbuilt |
|
+ //true //.setnativefontmapbuilt exec |
|
} ifelse |
|
} bind def |
|
+currentdict /.setnativefontmapbuilt .forceundef |
|
|
|
% Create the dictionary that registers the .buildfont procedure |
|
% (called by definefont) for each FontType. |
|
-- |
|
2.17.2 |
|
|
|
|
|
From a54c9e61e7d02bbc620bcba9b1c208462a876afb Mon Sep 17 00:00:00 2001 |
|
From: Chris Liddell <chris.liddell@artifex.com> |
|
Date: Sat, 29 Sep 2018 15:34:55 +0100 |
|
Subject: [PATCH 2/6] Bug 699816: Improve hiding of security critical custom |
|
operators |
|
|
|
Make procedures that use .forceput/.forcedef/.forceundef into operators. |
|
|
|
The result of this is that errors get reported against the "top" operator, |
|
rather than the "called" operator within the procedure. |
|
|
|
For example: |
|
/myproc |
|
{ |
|
myop |
|
} bind def |
|
|
|
If 'myop' throws an error, the error handler will be passed the 'myop' |
|
operator. Promoting 'myproc' to a operator means the error handler will be |
|
passed 'myproc'. |
|
--- |
|
Resource/Init/gs_diskn.ps | 2 +- |
|
Resource/Init/gs_dps.ps | 2 +- |
|
Resource/Init/gs_fntem.ps | 2 +- |
|
Resource/Init/gs_fonts.ps | 10 +++++----- |
|
Resource/Init/gs_lev2.ps | 13 +++++++++---- |
|
Resource/Init/gs_pdfwr.ps | 2 +- |
|
Resource/Init/gs_setpd.ps | 25 +++++++++++++++++-------- |
|
Resource/Init/gs_typ32.ps | 14 +++++++++----- |
|
Resource/Init/gs_type1.ps | 2 +- |
|
Resource/Init/pdf_base.ps | 2 +- |
|
Resource/Init/pdf_draw.ps | 10 +++++----- |
|
Resource/Init/pdf_font.ps | 8 ++++---- |
|
Resource/Init/pdf_main.ps | 4 ++-- |
|
Resource/Init/pdf_ops.ps | 8 ++++---- |
|
14 files changed, 61 insertions(+), 43 deletions(-) |
|
|
|
diff --git a/Resource/Init/gs_diskn.ps b/Resource/Init/gs_diskn.ps |
|
index 5540715..26ec0b5 100644 |
|
--- a/Resource/Init/gs_diskn.ps |
|
+++ b/Resource/Init/gs_diskn.ps |
|
@@ -53,7 +53,7 @@ systemdict begin |
|
exch .setglobal |
|
} |
|
if |
|
-} .bind executeonly def % must be bound and hidden for .forceput |
|
+} .bind executeonly odef % must be bound and hidden for .forceput |
|
|
|
% Modify .putdevparams to force regeneration of .searchabledevs list |
|
/.putdevparams { |
|
diff --git a/Resource/Init/gs_dps.ps b/Resource/Init/gs_dps.ps |
|
index cad7056..daf7b0f 100644 |
|
--- a/Resource/Init/gs_dps.ps |
|
+++ b/Resource/Init/gs_dps.ps |
|
@@ -70,7 +70,7 @@ |
|
% Save a copy of the initial gstate. |
|
//systemdict /savedinitialgstate gstate readonly .forceput |
|
.setglobal |
|
-} .bind executeonly def % must be bound and hidden for .forceput |
|
+} .bind executeonly odef % must be bound and hidden for .forceput |
|
|
|
% Initialize local dictionaries and gstate when creating a new context. |
|
% Note that until this completes, we are in the anomalous situation of |
|
diff --git a/Resource/Init/gs_fntem.ps b/Resource/Init/gs_fntem.ps |
|
index 3ceee18..c1f7651 100644 |
|
--- a/Resource/Init/gs_fntem.ps |
|
+++ b/Resource/Init/gs_fntem.ps |
|
@@ -408,7 +408,7 @@ currentdict end def |
|
exit |
|
} loop |
|
exch setglobal |
|
-} .bind executeonly def % must be bound and hidden for .forceput |
|
+} .bind executeonly odef % must be bound and hidden for .forceput |
|
|
|
currentdict end /ProcSet defineresource pop |
|
|
|
diff --git a/Resource/Init/gs_fonts.ps b/Resource/Init/gs_fonts.ps |
|
index 45b6613..89c3ab7 100644 |
|
--- a/Resource/Init/gs_fonts.ps |
|
+++ b/Resource/Init/gs_fonts.ps |
|
@@ -377,8 +377,8 @@ FONTPATH length 0 eq { (%END FONTPATH) .skipeof } if |
|
} |
|
{pop} |
|
ifelse |
|
-} .bind executeonly def |
|
-systemdict /NONATIVEFONTMAP known //.setnativefontmapbuilt exec |
|
+} .bind executeonly odef |
|
+systemdict /NONATIVEFONTMAP known .setnativefontmapbuilt |
|
/.buildnativefontmap { % - .buildnativefontmap <bool> |
|
systemdict /.nativefontmapbuilt .knownget not |
|
{ //false} if |
|
@@ -419,7 +419,7 @@ systemdict /NONATIVEFONTMAP known //.setnativefontmapbuilt exec |
|
} forall |
|
} if |
|
% record that we've been run |
|
- //true //.setnativefontmapbuilt exec |
|
+ //true .setnativefontmapbuilt |
|
} ifelse |
|
} bind def |
|
currentdict /.setnativefontmapbuilt .forceundef |
|
@@ -1103,7 +1103,7 @@ $error /SubstituteFont { } put |
|
|
|
% Check to make sure the font was actually loaded. |
|
dup 3 index .fontknownget |
|
- { dup /PathLoad 4 index //.putgstringcopy exec |
|
+ { dup /PathLoad 4 index .putgstringcopy |
|
4 1 roll pop pop pop //true exit |
|
} if |
|
|
|
@@ -1115,7 +1115,7 @@ $error /SubstituteFont { } put |
|
{ % Stack: origfontname fontdirectory path filefontname |
|
2 index 1 index .fontknownget |
|
{ % Yes. Stack: origfontname fontdirectory path filefontname fontdict |
|
- dup 4 -1 roll /PathLoad exch //.putgstringcopy exec |
|
+ dup 4 -1 roll /PathLoad exch .putgstringcopy |
|
% Stack: origfontname fontdirectory filefontname fontdict |
|
3 -1 roll pop |
|
% Stack: origfontname filefontname fontdict |
|
diff --git a/Resource/Init/gs_lev2.ps b/Resource/Init/gs_lev2.ps |
|
index eee0b9f..a8ed892 100644 |
|
--- a/Resource/Init/gs_lev2.ps |
|
+++ b/Resource/Init/gs_lev2.ps |
|
@@ -163,10 +163,11 @@ end |
|
% Set them again to the new values. From here on, we are safe, |
|
% since a context switch will consult userparams. |
|
.setuserparams |
|
-} .bind executeonly def % must be bound and hidden for .forceput |
|
+} .bind executeonly odef % must be bound and hidden for .forceput |
|
|
|
/setuserparams { % <dict> setuserparams - |
|
- .setuserparams2 |
|
+ {.setuserparams2} stopped |
|
+ {/setuserparams load $error /errorname get signalerror} if |
|
} .bind odef |
|
% Initialize user parameters managed here. |
|
/JobName () .definepsuserparam |
|
@@ -415,7 +416,9 @@ psuserparams /ProcessDSCComment {.checkprocesscomment} put |
|
|
|
% VMReclaim and VMThreshold are user parameters. |
|
/setvmthreshold { % <int> setvmthreshold - |
|
- mark /VMThreshold 2 .argindex .dicttomark .setuserparams2 pop |
|
+ mark /VMThreshold 2 .argindex .dicttomark {.setuserparams2} stopped |
|
+ {pop /setvmthreshold load $error /errorname get signalerror} |
|
+ {pop} ifelse |
|
} odef |
|
/vmreclaim { % <int> vmreclaim - |
|
dup 0 gt { |
|
@@ -427,7 +430,9 @@ psuserparams /ProcessDSCComment {.checkprocesscomment} put |
|
ifelse |
|
} { |
|
% VMReclaim userparam controls enable/disable GC |
|
- mark /VMReclaim 2 index .dicttomark .setuserparams2 pop |
|
+ mark /VMReclaim 2 index .dicttomark {.setuserparams2} stopped |
|
+ {pop /vmreclaim load $error /errorname get signalerror} |
|
+ {pop} ifelse |
|
} ifelse |
|
} odef |
|
-1 setvmthreshold |
|
diff --git a/Resource/Init/gs_pdfwr.ps b/Resource/Init/gs_pdfwr.ps |
|
index fb1c419..58e75d3 100644 |
|
--- a/Resource/Init/gs_pdfwr.ps |
|
+++ b/Resource/Init/gs_pdfwr.ps |
|
@@ -660,7 +660,7 @@ currentdict /.pdfmarkparams .undef |
|
{ |
|
pop |
|
} ifelse |
|
-} .bind executeonly def % must be bound and hidden for .forceput |
|
+} .bind executeonly odef % must be bound and hidden for .forceput |
|
|
|
% Use the DSC processing hook to pass DSC comments to the driver. |
|
% We use a pseudo-parameter named DSC whose value is an array: |
|
diff --git a/Resource/Init/gs_setpd.ps b/Resource/Init/gs_setpd.ps |
|
index 8fa7c51..afb4ffa 100644 |
|
--- a/Resource/Init/gs_setpd.ps |
|
+++ b/Resource/Init/gs_setpd.ps |
|
@@ -608,6 +608,20 @@ NOMEDIAATTRS { |
|
% in the <failed> dictionary with the policy value, |
|
% and we replace the key in the <merged> dictionary with its prior value |
|
% (or remove it if it had no prior value). |
|
+ |
|
+% Making this an operator means we can properly hide |
|
+% the contents - specifically .forceput |
|
+/1Policy |
|
+{ |
|
+ % Roll back the failed request to its previous status. |
|
+ SETPDDEBUG { (Rolling back.) = pstack flush } if |
|
+ 3 index 2 index 3 -1 roll .forceput |
|
+ 4 index 1 index .knownget |
|
+ { 4 index 3 1 roll .forceput } |
|
+ { 3 index exch .undef } |
|
+ ifelse |
|
+} bind executeonly odef |
|
+ |
|
/.policyprocs mark |
|
% These procedures are called with the following on the stack: |
|
% <orig> <merged> <failed> <Policies> <key> <policy> |
|
@@ -631,14 +645,7 @@ NOMEDIAATTRS { |
|
/setpagedevice .systemvar /configurationerror signalerror |
|
} ifelse |
|
} bind |
|
- 1 { % Roll back the failed request to its previous status. |
|
-SETPDDEBUG { (Rolling back.) = pstack flush } if |
|
- 3 index 2 index 3 -1 roll .forceput |
|
- 4 index 1 index .knownget |
|
- { 4 index 3 1 roll .forceput } |
|
- { 3 index exch .undef } |
|
- ifelse |
|
- } .bind executeonly % must be bound and hidden for .forceput |
|
+ 1 /1Policy load |
|
7 { % For PageSize only, just impose the request. |
|
1 index /PageSize eq |
|
{ pop pop 1 index /PageSize 7 put } |
|
@@ -646,6 +653,8 @@ SETPDDEBUG { (Rolling back.) = pstack flush } if |
|
ifelse |
|
} bind |
|
.dicttomark readonly def |
|
+currentdict /1Policy undef |
|
+ |
|
/.applypolicies % <orig> <merged> <failed> .applypolicies |
|
% <orig> <merged'> <failed'> |
|
{ 1 index /Policies get 1 index |
|
diff --git a/Resource/Init/gs_typ32.ps b/Resource/Init/gs_typ32.ps |
|
index b6600b0..9150f71 100644 |
|
--- a/Resource/Init/gs_typ32.ps |
|
+++ b/Resource/Init/gs_typ32.ps |
|
@@ -79,15 +79,19 @@ systemdict /.removeglyphs .undef |
|
.dicttomark /ProcSet defineresource pop |
|
|
|
/.cidfonttypes where { pop } { /.cidfonttypes 6 dict def } ifelse |
|
-.cidfonttypes begin |
|
- |
|
-4 % CIDFontType 4 = FontType 32 |
|
-{ dup /FontType 32 .forceput |
|
+/CIDFontType4 |
|
+{ |
|
+ dup /FontType 32 .forceput |
|
dup /CharStrings 20 dict .forceput |
|
1 index exch .buildfont32 exch pop |
|
-} .bind executeonly def % must be bound and hidden for .forceput |
|
+} .bind executeonly odef |
|
+.cidfonttypes begin |
|
+ |
|
+ |
|
+4 /CIDFontType4 load def % CIDFontType 4 = FontType 32 |
|
|
|
end % .cidfonttypes |
|
+currentdict /CIDFontType4 .forceundef |
|
|
|
% Define the BuildGlyph procedure. |
|
% Since Type 32 fonts are indexed by CID, there is no BuildChar procedure. |
|
diff --git a/Resource/Init/gs_type1.ps b/Resource/Init/gs_type1.ps |
|
index efdae48..2935d9c 100644 |
|
--- a/Resource/Init/gs_type1.ps |
|
+++ b/Resource/Init/gs_type1.ps |
|
@@ -283,7 +283,7 @@ currentdict /closesourcedict .undef |
|
} if |
|
2 copy /WeightVector exch .forceput |
|
.setweightvector |
|
-} .bind executeonly def |
|
+} .bind executeonly odef |
|
end |
|
|
|
% Register the font types for definefont. |
|
diff --git a/Resource/Init/pdf_base.ps b/Resource/Init/pdf_base.ps |
|
index a82a2a3..7ccd4cd 100644 |
|
--- a/Resource/Init/pdf_base.ps |
|
+++ b/Resource/Init/pdf_base.ps |
|
@@ -218,7 +218,7 @@ currentdict /num-chars-dict .undef |
|
} ifelse |
|
} ifelse |
|
} ifelse |
|
-} bind executeonly def |
|
+} bind executeonly odef |
|
/PDFScanRules_true << /PDFScanRules //true >> def |
|
/PDFScanRules_null << /PDFScanRules //null >> def |
|
/.pdfrun { % <file> <opdict> .pdfrun - |
|
diff --git a/Resource/Init/pdf_draw.ps b/Resource/Init/pdf_draw.ps |
|
index d1b6ac9..c239daf 100644 |
|
--- a/Resource/Init/pdf_draw.ps |
|
+++ b/Resource/Init/pdf_draw.ps |
|
@@ -1158,7 +1158,7 @@ currentdict end readonly def |
|
Q |
|
PDFDEBUG { pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%End PaintProc) print dup === flush } if } if |
|
PDFfile exch setfileposition |
|
-} bind executeonly def |
|
+} bind executeonly odef |
|
|
|
/.pdfpaintproc { |
|
%% Get the /m from pdfopdict (must be present) |
|
@@ -1189,7 +1189,7 @@ currentdict end readonly def |
|
{ |
|
switch_to_text_marking_ops |
|
} if |
|
-}bind executeonly def |
|
+}bind executeonly odef |
|
|
|
/resolvepattern { % <patternstreamdict> resolvepattern <patterndict> |
|
% Don't do the resolvestream now: just capture the data |
|
@@ -2353,7 +2353,7 @@ currentdict /last-ditch-bpc-csp undef |
|
}{ |
|
pdfdict /AppearanceNumber 0 .forceput |
|
} ifelse |
|
-}bind executeonly def |
|
+}bind executeonly odef |
|
|
|
/MakeAppearanceName { |
|
pdfdict /AppearanceNumber get |
|
@@ -2382,7 +2382,7 @@ currentdict /last-ditch-bpc-csp undef |
|
DoForm |
|
pdfdict /.PreservePDFForm 3 -1 roll .forceput |
|
grestore |
|
-} bind executeonly def |
|
+} bind executeonly odef |
|
|
|
/DoForm { |
|
%% save the current value, if its true we will set it to false later, in order |
|
@@ -2541,7 +2541,7 @@ currentdict /last-ditch-bpc-csp undef |
|
end |
|
} if |
|
pdfdict /.PreservePDFForm 3 -1 roll .forceput |
|
-} bind executeonly def |
|
+} bind executeonly odef |
|
|
|
/_dops_save 1 array def |
|
|
|
diff --git a/Resource/Init/pdf_font.ps b/Resource/Init/pdf_font.ps |
|
index feaf0d0..535b14a 100644 |
|
--- a/Resource/Init/pdf_font.ps |
|
+++ b/Resource/Init/pdf_font.ps |
|
@@ -718,7 +718,7 @@ currentdict end readonly def |
|
{pop pop pop} |
|
ifelse |
|
|
|
-} bind executeonly def |
|
+} bind executeonly odef |
|
|
|
currentdict /.DoToUnicode? .forceundef |
|
|
|
@@ -1241,7 +1241,7 @@ currentdict /eexec_pdf_param_dict .undef |
|
} bdef |
|
dup currentdict Encoding .processToUnicode |
|
currentdict end .completefont exch pop |
|
-} bind executeonly def |
|
+} bind executeonly odef |
|
/.adjustcharwidth { % <wx> <wy> .adjustcharwidth <wx'> <wy'> |
|
% Enforce the metrics, in glyph space, to the values found in the PDF Font object |
|
% - force wy == 0 (assumed, and not stored in the PDF font) |
|
@@ -2026,7 +2026,7 @@ currentdict /CMap_read_dict undef |
|
} if |
|
/findresource cvx /undefined signalerror |
|
} loop |
|
-} bind executeonly def |
|
+} bind executeonly odef |
|
|
|
/buildCIDType0 { % <CIDFontType0-font-resource> buildCIDType0 <font> |
|
dup /BaseFont get findCIDFont exch pop |
|
@@ -2211,7 +2211,7 @@ currentdict /CMap_read_dict undef |
|
/Type0 //buildType0 |
|
/Type1 //buildType1 |
|
/MMType1 //buildType1 |
|
- /Type3 //buildType3 |
|
+ /Type3 /buildType3 load |
|
/TrueType //buildTrueType |
|
/CIDFontType0 //buildCIDType0 |
|
/CIDFontType2 //buildCIDType2 |
|
diff --git a/Resource/Init/pdf_main.ps b/Resource/Init/pdf_main.ps |
|
index 09f8735..c823e69 100644 |
|
--- a/Resource/Init/pdf_main.ps |
|
+++ b/Resource/Init/pdf_main.ps |
|
@@ -660,7 +660,7 @@ currentdict /runpdfstring .undef |
|
} forall |
|
pop |
|
} ifelse |
|
-} bind executeonly def |
|
+} bind executeonly odef |
|
|
|
currentdict /pdf_collection_files .undef |
|
|
|
@@ -2715,7 +2715,7 @@ currentdict /PDF2PS_matrix_key undef |
|
.setglobal |
|
/RepairedAnError exch def |
|
/Repaired exch def |
|
-} bind executeonly def |
|
+} bind executeonly odef |
|
|
|
% Display the contents of a page (including annotations). |
|
/showpagecontents { % <pagedict> showpagecontents - |
|
diff --git a/Resource/Init/pdf_ops.ps b/Resource/Init/pdf_ops.ps |
|
index c45fc51..8672d61 100644 |
|
--- a/Resource/Init/pdf_ops.ps |
|
+++ b/Resource/Init/pdf_ops.ps |
|
@@ -193,7 +193,7 @@ currentdict /gput_always_allow .undef |
|
pdfformaterror |
|
} ifelse |
|
} if |
|
-} bind executeonly def |
|
+} bind executeonly odef |
|
|
|
% Save PDF gstate |
|
/qstate { % - qstate <qstate> |
|
@@ -451,7 +451,7 @@ currentdict /gput_always_allow .undef |
|
%% a gsave, so we haven't copied it to /self, if we don't do that here |
|
%% then transparent annotations cause an invalid access error. |
|
currentdict //nodict eq {/self dup load end 5 dict begin def} if |
|
-} bind executeonly def |
|
+} bind executeonly odef |
|
/AIS { .setalphaisshape } bind executeonly def |
|
/BM { |
|
/.setblendmode where { |
|
@@ -1077,7 +1077,7 @@ end readonly def |
|
pdfopdict /v {inside_text_v} bind .forceput |
|
pdfopdict /y {inside_text_y} bind .forceput |
|
pdfopdict /re {inside_text_re} bind .forceput |
|
-} bind executeonly def |
|
+} bind executeonly odef |
|
|
|
/switch_to_normal_marking_ops { |
|
pdfopdict /m {normal_m} bind .forceput |
|
@@ -1086,7 +1086,7 @@ end readonly def |
|
pdfopdict /v {normal_v} bind .forceput |
|
pdfopdict /y {normal_y} bind .forceput |
|
pdfopdict /re {normal_re} bind .forceput |
|
-} bind executeonly def |
|
+} bind executeonly odef |
|
|
|
/BT { |
|
currentdict /TextSaveMatrix known { |
|
-- |
|
2.17.2 |
|
|
|
|
|
From 1778db6bc10a8d60dfe986b22d2300326733ddd6 Mon Sep 17 00:00:00 2001 |
|
From: Chris Liddell <chris.liddell@artifex.com> |
|
Date: Thu, 4 Oct 2018 10:42:13 +0100 |
|
Subject: [PATCH 3/6] Bug 699832: add control over hiding error handlers. |
|
|
|
With a previous commit changing error handling in SAFER so the handler gets |
|
passed a name object (rather than executable object), it is less critical to |
|
hide the error handlers. |
|
|
|
This introduces a -dSAFERERRORS option to force only use of the default error |
|
handlers. |
|
|
|
It also adds a .setsafererrors Postscript call, meaning a caller, without |
|
-dSAFERERRORS, can create their own default error handlers (in errordict, as |
|
normal), and then call .setsafererrors meaning their own handlers are always |
|
called. |
|
|
|
With -dSAFERERRORS or after a call to .setsafererrors, .setsafererrors is |
|
removed. |
|
--- |
|
Resource/Init/gs_init.ps | 42 ++++++++++++++++++++++++---------- |
|
psi/interp.c | 49 ++++++++++++++++++++++++---------------- |
|
2 files changed, 59 insertions(+), 32 deletions(-) |
|
|
|
diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps |
|
index b94f873..a627eec 100644 |
|
--- a/Resource/Init/gs_init.ps |
|
+++ b/Resource/Init/gs_init.ps |
|
@@ -188,6 +188,16 @@ currentdict /DELAYSAFER known { /DELAYSAFER //true def /NOSAFER //true def } if |
|
currentdict /PARANOIDSAFER known or % PARANOIDSAFER is equivalent |
|
} |
|
ifelse def |
|
+ |
|
+/SAFERERRORS |
|
+currentdict /NOSAFERERRORS known |
|
+{ |
|
+ //false |
|
+} |
|
+{ |
|
+ currentdict /SAFERERRORS known |
|
+} ifelse def |
|
+ |
|
currentdict /SHORTERRORS known /SHORTERRORS exch def |
|
currentdict /TTYPAUSE known /TTYPAUSE exch def |
|
currentdict /WRITESYSTEMDICT known /WRITESYSTEMDICT exch def |
|
@@ -1137,12 +1147,23 @@ errordict begin |
|
} bind def |
|
end % errordict |
|
|
|
-% 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 |
|
+gserrordict /unknownerror errordict /unknownerror get put |
|
errordict /unknownerror .undef |
|
+ |
|
+/.SAFERERRORLIST ErrorNames def |
|
+/.setsafererrors |
|
+{ |
|
+% Put all the requested handlers in gserrordict |
|
+ gserrordict |
|
+ //.SAFERERRORLIST |
|
+ {dup errordict exch get 2 index 3 1 roll put} forall |
|
+ noaccess pop |
|
+ systemdict /.setsafeerrors .forceundef |
|
+ systemdict /.SAFERERRORLIST .forceundef |
|
+} bind executeonly odef |
|
+ |
|
+SAFERERRORS {.setsafererrors} if |
|
+ |
|
% Define a stable private copy of handleerror that we will always use under |
|
% JOBSERVER mode. |
|
/.GShandleerror errordict /handleerror get def |
|
@@ -1774,18 +1795,15 @@ currentdict /.runlibfile .undef |
|
|
|
% Bind all the operators defined as procedures. |
|
/.bindoperators % binds operators in currentdict |
|
- { % Temporarily disable the typecheck error. |
|
- errordict /typecheck 2 copy get |
|
- errordict /typecheck { pop } put % pop the command |
|
+ { |
|
currentdict |
|
{ dup type /operatortype eq |
|
- { % This might be a real operator, so bind might cause a typecheck, |
|
- % but we've made the error a no-op temporarily. |
|
- .bind |
|
+ { |
|
+ % This might be a real operator, so bind might cause a typecheck |
|
+ {.bind} .internalstopped pop |
|
} |
|
if pop pop |
|
} forall |
|
- put |
|
} def |
|
DELAYBIND not { .bindoperators } if |
|
|
|
diff --git a/psi/interp.c b/psi/interp.c |
|
index 1dec9b6..d60c733 100644 |
|
--- a/psi/interp.c |
|
+++ b/psi/interp.c |
|
@@ -661,27 +661,18 @@ again: |
|
if (gs_errorname(i_ctx_p, code, &error_name) < 0) |
|
return code; /* out-of-range error code! */ |
|
|
|
- /* If LockFilePermissions is true, we only refer to gserrordict, which |
|
- * is not accessible to Postcript jobs |
|
+ /* We refer to gserrordict first, which is not accessible to Postcript jobs |
|
+ * If we're running with SAFERERRORS all the handlers are copied to gserrordict |
|
+ * so we'll always find the default one. If not SAFERERRORS, only gs specific |
|
+ * errors are in gserrordict. |
|
*/ |
|
- 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??? */ |
|
- } |
|
+ if (dict_find_string(systemdict, "gserrordict", &perrordict) <= 0 || |
|
+ (dict_find(perrordict, &error_name, &epref) <= 0 && |
|
+ (dict_find_string(systemdict, "errordict", &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. */ |
|
@@ -694,6 +685,24 @@ again: |
|
} |
|
*osp = *perror_object; |
|
errorexec_find(i_ctx_p, osp); |
|
+ /* If using SAFER, hand a name object to the error handler, rather than the executable |
|
+ * object/operator itself. |
|
+ */ |
|
+ if (i_ctx_p->LockFilePermissions) { |
|
+ code = obj_cvs(imemory, osp, buf + 2, 256, &rlen, (const byte **)&bufptr); |
|
+ if (code < 0) { |
|
+ const char *unknownstr = "--unknown--"; |
|
+ rlen = strlen(unknownstr); |
|
+ memcpy(buf, unknownstr, rlen); |
|
+ } |
|
+ else { |
|
+ buf[0] = buf[1] = buf[rlen + 2] = buf[rlen + 3] = '-'; |
|
+ rlen += 4; |
|
+ } |
|
+ code = name_ref(imemory, buf, rlen, osp, 1); |
|
+ if (code < 0) |
|
+ make_null(osp); |
|
+ } |
|
} |
|
goto again; |
|
} |
|
-- |
|
2.17.2 |
|
|
|
|
|
From a6807394bd94b708be24758287b606154daaaed9 Mon Sep 17 00:00:00 2001 |
|
From: Chris Liddell <chris.liddell@artifex.com> |
|
Date: Tue, 2 Oct 2018 16:02:58 +0100 |
|
Subject: [PATCH 4/6] For hidden operators, pass a name object to error |
|
handler. |
|
|
|
In normal operation, Postscript error handlers are passed the object which |
|
triggered the error: this is invariably an operator object. |
|
|
|
The issue arises when an error is triggered by an operator which is for internal |
|
use only, and that operator is then passed to the error handler, meaning it |
|
becomes visible to the error handler code. |
|
|
|
By converting to a name object, the error message is still valid, but we no |
|
longer expose internal use only operators. |
|
|
|
The change in gs_dps1.ps is related to the above: previously an error in |
|
scheck would throw an error against .gcheck, but as .gcheck is now a hidden |
|
operator, it resulted in a name object being passed to the error handler. As |
|
scheck is a 'real' operator, it's better to use the real operator, rather than |
|
the name of an internal, hidden one. |
|
--- |
|
Resource/Init/gs_dps1.ps | 2 +- |
|
psi/interp.c | 33 ++++++++++++++++++++++++--------- |
|
2 files changed, 25 insertions(+), 10 deletions(-) |
|
|
|
diff --git a/Resource/Init/gs_dps1.ps b/Resource/Init/gs_dps1.ps |
|
index 1182f53..ec5db61 100644 |
|
--- a/Resource/Init/gs_dps1.ps |
|
+++ b/Resource/Init/gs_dps1.ps |
|
@@ -21,7 +21,7 @@ level2dict begin |
|
% ------ Virtual memory ------ % |
|
|
|
/currentshared /.currentglobal load def |
|
-/scheck /.gcheck load def |
|
+/scheck {.gcheck} bind odef |
|
%****** FOLLOWING IS WRONG ****** |
|
/shareddict currentdict /globaldict .knownget not { 20 dict } if def |
|
|
|
diff --git a/psi/interp.c b/psi/interp.c |
|
index d60c733..6dc0dda 100644 |
|
--- a/psi/interp.c |
|
+++ b/psi/interp.c |
|
@@ -677,6 +677,8 @@ again: |
|
epref = &doref; |
|
/* Push the error object on the operand stack if appropriate. */ |
|
if (!GS_ERROR_IS_INTERRUPT(code)) { |
|
+ byte buf[260], *bufptr; |
|
+ uint rlen; |
|
/* Replace the error object if within an oparray or .errorexec. */ |
|
osp++; |
|
if (osp >= ostop) { |
|
@@ -685,23 +687,36 @@ again: |
|
} |
|
*osp = *perror_object; |
|
errorexec_find(i_ctx_p, osp); |
|
- /* If using SAFER, hand a name object to the error handler, rather than the executable |
|
- * object/operator itself. |
|
- */ |
|
- if (i_ctx_p->LockFilePermissions) { |
|
+ |
|
+ if (!r_has_type(osp, t_string) && !r_has_type(osp, t_name)) { |
|
code = obj_cvs(imemory, osp, buf + 2, 256, &rlen, (const byte **)&bufptr); |
|
if (code < 0) { |
|
const char *unknownstr = "--unknown--"; |
|
rlen = strlen(unknownstr); |
|
memcpy(buf, unknownstr, rlen); |
|
+ bufptr = buf; |
|
} |
|
else { |
|
- buf[0] = buf[1] = buf[rlen + 2] = buf[rlen + 3] = '-'; |
|
- rlen += 4; |
|
+ ref *tobj; |
|
+ bufptr[rlen] = '\0'; |
|
+ /* Only pass a name object if the operator doesn't exist in systemdict |
|
+ * i.e. it's an internal operator we have hidden |
|
+ */ |
|
+ code = dict_find_string(systemdict, (const char *)bufptr, &tobj); |
|
+ if (code < 0) { |
|
+ buf[0] = buf[1] = buf[rlen + 2] = buf[rlen + 3] = '-'; |
|
+ rlen += 4; |
|
+ bufptr = buf; |
|
+ } |
|
+ else { |
|
+ bufptr = NULL; |
|
+ } |
|
+ } |
|
+ if (bufptr) { |
|
+ code = name_ref(imemory, buf, rlen, osp, 1); |
|
+ if (code < 0) |
|
+ make_null(osp); |
|
} |
|
- code = name_ref(imemory, buf, rlen, osp, 1); |
|
- if (code < 0) |
|
- make_null(osp); |
|
} |
|
} |
|
goto again; |
|
-- |
|
2.17.2 |
|
|
|
|
|
From a5a9bf8c6a63aa4ac6874234fe8cd63e72077291 Mon Sep 17 00:00:00 2001 |
|
From: Chris Liddell <chris.liddell@artifex.com> |
|
Date: Wed, 10 Oct 2018 23:25:51 +0100 |
|
Subject: [PATCH 5/6] Bug 699938: .loadfontloop must be an operator |
|
|
|
In the fix for Bug 699816, I omitted to make .loadfontloop into an operator, to |
|
better hide .forceundef and .putgstringcopy. |
|
--- |
|
Resource/Init/gs_fonts.ps | 2 +- |
|
1 file changed, 1 insertion(+), 1 deletion(-) |
|
|
|
diff --git a/Resource/Init/gs_fonts.ps b/Resource/Init/gs_fonts.ps |
|
index 89c3ab7..72feff2 100644 |
|
--- a/Resource/Init/gs_fonts.ps |
|
+++ b/Resource/Init/gs_fonts.ps |
|
@@ -1148,7 +1148,7 @@ $error /SubstituteFont { } put |
|
|
|
} loop % end of loop |
|
|
|
- } bind executeonly def % must be bound and hidden for .putgstringcopy |
|
+ } bind executeonly odef % must be bound and hidden for .putgstringcopy |
|
|
|
currentdict /.putgstringcopy .undef |
|
|
|
-- |
|
2.17.2 |
|
|
|
|
|
From 2756f0efae1d3966989b15a6526c5d80848b5015 Mon Sep 17 00:00:00 2001 |
|
From: Chris Liddell <chris.liddell@artifex.com> |
|
Date: Wed, 28 Nov 2018 17:12:08 +0000 |
|
Subject: [PATCH 6/6] Bug 700290: Fix problems with DELAYBIND and font |
|
substitution |
|
|
|
Judicious use of immediate evaluation for .setnativefontmapbuilt and |
|
.putgstringcopy to avoid problems with DELAYBIND |
|
--- |
|
Resource/Init/gs_fonts.ps | 9 ++++----- |
|
1 file changed, 4 insertions(+), 5 deletions(-) |
|
|
|
diff --git a/Resource/Init/gs_fonts.ps b/Resource/Init/gs_fonts.ps |
|
index 72feff2..7a57366 100644 |
|
--- a/Resource/Init/gs_fonts.ps |
|
+++ b/Resource/Init/gs_fonts.ps |
|
@@ -419,7 +419,7 @@ systemdict /NONATIVEFONTMAP known .setnativefontmapbuilt |
|
} forall |
|
} if |
|
% record that we've been run |
|
- //true .setnativefontmapbuilt |
|
+ //true //.setnativefontmapbuilt |
|
} ifelse |
|
} bind def |
|
currentdict /.setnativefontmapbuilt .forceundef |
|
@@ -1103,7 +1103,7 @@ $error /SubstituteFont { } put |
|
|
|
% Check to make sure the font was actually loaded. |
|
dup 3 index .fontknownget |
|
- { dup /PathLoad 4 index .putgstringcopy |
|
+ { dup /PathLoad 4 index //.putgstringcopy |
|
4 1 roll pop pop pop //true exit |
|
} if |
|
|
|
@@ -1115,7 +1115,7 @@ $error /SubstituteFont { } put |
|
{ % Stack: origfontname fontdirectory path filefontname |
|
2 index 1 index .fontknownget |
|
{ % Yes. Stack: origfontname fontdirectory path filefontname fontdict |
|
- dup 4 -1 roll /PathLoad exch .putgstringcopy |
|
+ dup 4 -1 roll /PathLoad exch //.putgstringcopy |
|
% Stack: origfontname fontdirectory filefontname fontdict |
|
3 -1 roll pop |
|
% Stack: origfontname filefontname fontdict |
|
@@ -1149,8 +1149,7 @@ $error /SubstituteFont { } put |
|
} loop % end of loop |
|
|
|
} bind executeonly odef % must be bound and hidden for .putgstringcopy |
|
- |
|
-currentdict /.putgstringcopy .undef |
|
+currentdict /.putgstringcopy .forceundef |
|
|
|
% Define a procedure to load all known fonts. |
|
% This isn't likely to be very useful. |
|
-- |
|
2.17.2 |
|
|
|
|