basebuilder_pel7x64builder0
3 years ago
22 changed files with 7769 additions and 0 deletions
@ -0,0 +1,22 @@ |
|||||||
|
From 91c9c6d17d445781ee572c281b8b9d75d96f9df8 Mon Sep 17 00:00:00 2001 |
||||||
|
From: "David Kaspar [Dee'Kej]" <dkaspar@redhat.com> |
||||||
|
Date: Fri, 7 Oct 2016 13:57:01 +0200 |
||||||
|
Subject: [PATCH] Make sure 'dvipdf' is being run securely |
||||||
|
|
||||||
|
--- |
||||||
|
lib/dvipdf | 2 +- |
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-) |
||||||
|
|
||||||
|
diff --git a/lib/dvipdf b/lib/dvipdf |
||||||
|
index 802aeab..c92dfb0 100755 |
||||||
|
--- a/lib/dvipdf |
||||||
|
+++ b/lib/dvipdf |
||||||
|
@@ -43,4 +43,4 @@ fi |
||||||
|
|
||||||
|
# We have to include the options twice because -I only takes effect if it |
||||||
|
# appears before other options. |
||||||
|
-exec dvips -Ppdf $DVIPSOPTIONS -q -f "$infile" | $GS_EXECUTABLE $OPTIONS -q -P- -dSAFER -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sstdout=%stderr -sOutputFile="$outfile" $OPTIONS -c .setpdfwrite - |
||||||
|
+exec dvips -R -Ppdf $DVIPSOPTIONS -q -f "$infile" | $GS_EXECUTABLE $OPTIONS -q -P- -dSAFER -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sstdout=%stderr -sOutputFile="$outfile" $OPTIONS -c .setpdfwrite - |
||||||
|
-- |
||||||
|
2.14.3 |
||||||
|
|
@ -0,0 +1,54 @@ |
|||||||
|
From 9a6564bc1a2f2eeaf9faffd4d3b0a5a562855123 Mon Sep 17 00:00:00 2001 |
||||||
|
From: rpm-build <rpm-build> |
||||||
|
Date: Tue, 9 Oct 2018 15:42:09 +0200 |
||||||
|
Subject: [PATCH] Fix to re-enable CUPS filters creation (needed for |
||||||
|
ghostscript-cups) |
||||||
|
|
||||||
|
--- |
||||||
|
Makefile.in | 2 ++ |
||||||
|
configure.ac | 9 +++++++++ |
||||||
|
2 files changed, 11 insertions(+) |
||||||
|
|
||||||
|
diff --git a/Makefile.in b/Makefile.in |
||||||
|
index d6f114a..bdf0ae7 100644 |
||||||
|
--- a/Makefile.in |
||||||
|
+++ b/Makefile.in |
||||||
|
@@ -351,6 +351,8 @@ CUPSSERVERROOT=@CUPSSERVERROOT@ |
||||||
|
CUPSDATA=@CUPSDATA@ |
||||||
|
CUPSPDFTORASTER=@CUPSPDFTORASTER@ |
||||||
|
|
||||||
|
+CUPSINSTTARGET=@CUPSINSTALL@ |
||||||
|
+ |
||||||
|
SHARE_LCUPS=@SHARELCUPS@ |
||||||
|
LCUPS_NAME=cups |
||||||
|
LCUPSSRCDIR=@CUPS_DIR@ |
||||||
|
diff --git a/configure.ac b/configure.ac |
||||||
|
index 8ecaccc..d063c1f 100644 |
||||||
|
--- a/configure.ac |
||||||
|
+++ b/configure.ac |
||||||
|
@@ -1400,6 +1400,10 @@ AC_ARG_WITH([local-cups], AC_HELP_STRING([--with-local-cups], |
||||||
|
[Force using the GS supplied cups code - only useful for debugging]), |
||||||
|
[with_local_cups=yes], [with_local_cups=no]) |
||||||
|
|
||||||
|
+AC_ARG_WITH([install-cups], AC_HELP_STRING([--with-install-cups], |
||||||
|
+ [Install the cups conversion tools]), |
||||||
|
+ [CUPSINSTALL=install-cups], [CUPSINSTALL=]) |
||||||
|
+ |
||||||
|
AC_ARG_WITH([cups-serverbin], AC_HELP_STRING([--with-cups-serverbin], |
||||||
|
[override the "cups-config --serverbin" path]), CUPS_SERVERBIN="$withval", CUPS_SERVERBIN="") |
||||||
|
|
||||||
|
@@ -3029,6 +3033,11 @@ if test x"$THEMAKEFILE" != x"$MAKEFILE" && test x"$CCAUX" = x"$CC"; then |
||||||
|
CONFIG_FILES_LIST="$CONFIG_FILES_LIST" |
||||||
|
fi |
||||||
|
|
||||||
|
+if ( test -d cups ); then |
||||||
|
+AC_OUTPUT(cups/gstopxl) |
||||||
|
+chmod +x cups/gstopxl |
||||||
|
+fi |
||||||
|
+ |
||||||
|
if test "x$AFS" = "x1"; then |
||||||
|
AC_MSG_WARN([Using "native" font scaler which is now deprecated (rather than freetype),]) |
||||||
|
AC_MSG_WARN([Support for this will be removed in a future release]) |
||||||
|
-- |
||||||
|
2.14.4 |
||||||
|
|
@ -0,0 +1,842 @@ |
|||||||
|
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 |
||||||
|
|
@ -0,0 +1,289 @@ |
|||||||
|
From c76bf1cb7cc419534006631ea139ae20801fd824 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Nancy Durgin <nancy.durgin@artifex.com> |
||||||
|
Date: Tue, 18 Sep 2018 11:54:58 -0700 |
||||||
|
Subject: [PATCH 1/3] Undefine some additional internal operators. |
||||||
|
|
||||||
|
.type, .writecvs, .setSMask, .currentSMask |
||||||
|
|
||||||
|
These don't seem to be referenced anywhere outside of the initialization code, |
||||||
|
which binds their usages. Passes cluster if they are removed. |
||||||
|
--- |
||||||
|
Resource/Init/gs_init.ps | 3 ++- |
||||||
|
1 file changed, 2 insertions(+), 1 deletion(-) |
||||||
|
|
||||||
|
diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps |
||||||
|
index 55d6923..4aff036 100644 |
||||||
|
--- a/Resource/Init/gs_init.ps |
||||||
|
+++ b/Resource/Init/gs_init.ps |
||||||
|
@@ -2212,6 +2212,7 @@ SAFER { .setsafeglobal } if |
||||||
|
/.localvmarray /.localvmdict /.localvmpackedarray /.localvmstring /.systemvmarray /.systemvmdict /.systemvmpackedarray /.systemvmstring /.systemvmfile /.systemvmlibfile |
||||||
|
/.systemvmSFD /.settrapparams /.currentsystemparams /.currentuserparams /.getsystemparam /.getuserparam /.setsystemparams /.setuserparams |
||||||
|
/.checkpassword /.locale_to_utf8 /.currentglobal /.gcheck /.imagepath /.currentoutputdevice |
||||||
|
+ /.type /.writecvs /.setSMask /.currentSMask |
||||||
|
|
||||||
|
% Used by a free user in the Library of Congress. Apparently this is used to |
||||||
|
% draw a partial page, which is then filled in by the results of a barcode |
||||||
|
@@ -2230,7 +2231,7 @@ SAFER { .setsafeglobal } if |
||||||
|
% test files/utilities, or engineers expressed a desire to keep them visible. |
||||||
|
% |
||||||
|
%/currentdevice /.sort /.buildfont0 /.buildfont1 /.buildfont2 /.buildfont3 /.buildfont4 /.buildfont9 /.buildfont10 /.buildfont11 |
||||||
|
- %/.buildfotn32 /.buildfont42 /.type9mapcid /.type11mapcid /.swapcolors |
||||||
|
+ %/.buildfont32 /.buildfont42 /.type9mapcid /.type11mapcid /.swapcolors |
||||||
|
%/currentdevice /.quit /.setuseciecolor /.needinput /.setoverprintmode /.special_op /.dicttomark /.knownget |
||||||
|
%/.FAPIavailable /.FAPIpassfont /.FAPIrebuildfont /.FAPIBuildGlyph /.FAPIBuildChar /.FAPIBuildGlyph9 |
||||||
|
%/.tempfile /.numicc_components /.set_outputintent /.max /.min /.vmreclaim /.getpath /.setglobal |
||||||
|
-- |
||||||
|
2.17.2 |
||||||
|
|
||||||
|
|
||||||
|
From f8ccc7dfb990336b1ca55f65f2e1a8ecdcb76adf Mon Sep 17 00:00:00 2001 |
||||||
|
From: Chris Liddell <chris.liddell@artifex.com> |
||||||
|
Date: Tue, 25 Sep 2018 15:38:14 +0100 |
||||||
|
Subject: [PATCH 2/3] Bug 699793: Hide the .needinput operator |
||||||
|
|
||||||
|
This removes the .needinput operator from systemdict, ensuring it can only |
||||||
|
be used in the initialization code, and not called erroneously from random |
||||||
|
Postscript. |
||||||
|
--- |
||||||
|
Resource/Init/gs_init.ps | 20 +++++++++++++++++--- |
||||||
|
1 file changed, 17 insertions(+), 3 deletions(-) |
||||||
|
|
||||||
|
diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps |
||||||
|
index 4aff036..6a5c1df 100644 |
||||||
|
--- a/Resource/Init/gs_init.ps |
||||||
|
+++ b/Resource/Init/gs_init.ps |
||||||
|
@@ -831,12 +831,26 @@ userdict /.currentresourcefile //null put |
||||||
|
/.runstring { |
||||||
|
0 0 .systemvmstring .systemvmSFD cvx { .runexec } execute0 |
||||||
|
} bind def |
||||||
|
+ |
||||||
|
% Define the procedure that the C code uses to set up for executing |
||||||
|
% a string that may be received in pieces. |
||||||
|
+% |
||||||
|
+% Immediate evaluation doesn't work on operators (like .needinput) |
||||||
|
+% so calling .runstringbegin will throw an undefined error if we |
||||||
|
+% undefined .needinput so it cannot be accessed outside the init |
||||||
|
+% code. But, we can store the operator in an array, use immediate |
||||||
|
+% evaluation on the array to get the operator, then undefined the |
||||||
|
+% array (and because they are both of the same name, the operator |
||||||
|
+% get undefined too). |
||||||
|
+% This prevents random Postscript from erroneously calling .needinput |
||||||
|
+% and forcing the interpreter into an invalid state. |
||||||
|
+/.needinput |
||||||
|
+1 .systemvmarray dup 0 /.needinput load put |
||||||
|
+def |
||||||
|
/.runstringbegin { |
||||||
|
- 1 .systemvmarray dup 0 /.needinput load put cvx % { .needinput } in systemvm |
||||||
|
+ 1 .systemvmarray dup 0 //.needinput 0 get put cvx % { .needinput } in systemvm |
||||||
|
0 0 .systemvmstring .systemvmSFD cvx .runexec |
||||||
|
-} bind def |
||||||
|
+} bind executeonly def |
||||||
|
|
||||||
|
% Define a special version of runlibfile that aborts on errors. |
||||||
|
/runlibfile0 |
||||||
|
@@ -2212,7 +2226,7 @@ SAFER { .setsafeglobal } if |
||||||
|
/.localvmarray /.localvmdict /.localvmpackedarray /.localvmstring /.systemvmarray /.systemvmdict /.systemvmpackedarray /.systemvmstring /.systemvmfile /.systemvmlibfile |
||||||
|
/.systemvmSFD /.settrapparams /.currentsystemparams /.currentuserparams /.getsystemparam /.getuserparam /.setsystemparams /.setuserparams |
||||||
|
/.checkpassword /.locale_to_utf8 /.currentglobal /.gcheck /.imagepath /.currentoutputdevice |
||||||
|
- /.type /.writecvs /.setSMask /.currentSMask |
||||||
|
+ /.type /.writecvs /.setSMask /.currentSMask /.needinput |
||||||
|
|
||||||
|
% Used by a free user in the Library of Congress. Apparently this is used to |
||||||
|
% draw a partial page, which is then filled in by the results of a barcode |
||||||
|
-- |
||||||
|
2.17.2 |
||||||
|
|
||||||
|
|
||||||
|
From 34cc326eb2c5695833361887fe0b32e8d987741c Mon Sep 17 00:00:00 2001 |
||||||
|
From: Chris Liddell <chris.liddell@artifex.com> |
||||||
|
Date: Wed, 10 Oct 2018 15:38:10 +0100 |
||||||
|
Subject: [PATCH 3/3] Bug 699927: don't include operator arrays in execstack |
||||||
|
output |
||||||
|
|
||||||
|
When we transfer the contents of the execution stack into the array, take the |
||||||
|
extra step of replacing any operator arrays on the stack with the operator |
||||||
|
that reference them. |
||||||
|
|
||||||
|
This prevents the contents of Postscript defined, internal only operators (those |
||||||
|
created with .makeoperator) being exposed via execstack (and thus, via error |
||||||
|
handling). |
||||||
|
|
||||||
|
This necessitates a change in the resource remapping 'resource', which contains |
||||||
|
a procedure which relies on the contents of the operators arrays being present. |
||||||
|
As we already had internal-only variants of countexecstack and execstack |
||||||
|
(.countexecstack and .execstack) - using those, and leaving thier operation |
||||||
|
including the operator arrays means the procedure continues to work correctly. |
||||||
|
|
||||||
|
Both .countexecstack and .execstack are undefined after initialization. |
||||||
|
|
||||||
|
Also, when we store the execstack (or part thereof) for an execstackoverflow |
||||||
|
error, make the same oparray/operator substitution as above for execstack. |
||||||
|
--- |
||||||
|
Resource/Init/gs_init.ps | 4 ++-- |
||||||
|
Resource/Init/gs_resmp.ps | 2 +- |
||||||
|
psi/int.mak | 2 +- |
||||||
|
psi/interp.c | 14 +++++++++++--- |
||||||
|
psi/interp.h | 2 ++ |
||||||
|
psi/zcontrol.c | 13 ++++++++++--- |
||||||
|
6 files changed, 27 insertions(+), 10 deletions(-) |
||||||
|
|
||||||
|
diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps |
||||||
|
index 6a5c1df..5bec480 100644 |
||||||
|
--- a/Resource/Init/gs_init.ps |
||||||
|
+++ b/Resource/Init/gs_init.ps |
||||||
|
@@ -2187,7 +2187,7 @@ SAFER { .setsafeglobal } if |
||||||
|
%% but can be easily restored (just delete the name from the list in the array). In future |
||||||
|
%% we may remove the operator and the code implementation entirely. |
||||||
|
[ |
||||||
|
- /.bitadd /.charboxpath /.cond /.countexecstack /.execstack /.runandhide /.popdevicefilter |
||||||
|
+ /.bitadd /.charboxpath /.cond /.runandhide /.popdevicefilter |
||||||
|
/.execfile /.filenamesplit /.file_name_parent |
||||||
|
/.setdefaultmatrix /.isprocfilter /.unread /.psstringencode |
||||||
|
/.buildsampledfunction /.isencapfunction /.currentaccuratecurves /.currentcurvejoin /.currentdashadapt /.currentdotlength |
||||||
|
@@ -2226,7 +2226,7 @@ SAFER { .setsafeglobal } if |
||||||
|
/.localvmarray /.localvmdict /.localvmpackedarray /.localvmstring /.systemvmarray /.systemvmdict /.systemvmpackedarray /.systemvmstring /.systemvmfile /.systemvmlibfile |
||||||
|
/.systemvmSFD /.settrapparams /.currentsystemparams /.currentuserparams /.getsystemparam /.getuserparam /.setsystemparams /.setuserparams |
||||||
|
/.checkpassword /.locale_to_utf8 /.currentglobal /.gcheck /.imagepath /.currentoutputdevice |
||||||
|
- /.type /.writecvs /.setSMask /.currentSMask /.needinput |
||||||
|
+ /.type /.writecvs /.setSMask /.currentSMask /.needinput /.countexecstack /.execstack |
||||||
|
|
||||||
|
% Used by a free user in the Library of Congress. Apparently this is used to |
||||||
|
% draw a partial page, which is then filled in by the results of a barcode |
||||||
|
diff --git a/Resource/Init/gs_resmp.ps b/Resource/Init/gs_resmp.ps |
||||||
|
index 7cacaf8..9bb4263 100644 |
||||||
|
--- a/Resource/Init/gs_resmp.ps |
||||||
|
+++ b/Resource/Init/gs_resmp.ps |
||||||
|
@@ -183,7 +183,7 @@ setpacking |
||||||
|
% We don't check them. |
||||||
|
|
||||||
|
currentglobal //false setglobal % <object> bGlobal |
||||||
|
- countexecstack array execstack % <object> bGlobal [execstack] |
||||||
|
+ //false .countexecstack array //false .execstack % <object> bGlobal [execstack] |
||||||
|
dup //null exch % <object> bGlobal [execstack] null [execstack] |
||||||
|
length 3 sub -1 0 { % <object> bGlobal [execstack] null i |
||||||
|
2 index exch get % <object> bGlobal [execstack] null proc |
||||||
|
diff --git a/psi/int.mak b/psi/int.mak |
||||||
|
index 5d9b3d5..6ab5bf0 100644 |
||||||
|
--- a/psi/int.mak |
||||||
|
+++ b/psi/int.mak |
||||||
|
@@ -323,7 +323,7 @@ $(PSOBJ)zarray.$(OBJ) : $(PSSRC)zarray.c $(OP) $(memory__h)\ |
||||||
|
|
||||||
|
$(PSOBJ)zcontrol.$(OBJ) : $(PSSRC)zcontrol.c $(OP) $(string__h)\ |
||||||
|
$(estack_h) $(files_h) $(ipacked_h) $(iutil_h) $(store_h) $(stream_h)\ |
||||||
|
- $(INT_MAK) $(MAKEDIRS) |
||||||
|
+ $(interp_h) $(INT_MAK) $(MAKEDIRS) |
||||||
|
$(PSCC) $(PSO_)zcontrol.$(OBJ) $(C_) $(PSSRC)zcontrol.c |
||||||
|
|
||||||
|
$(PSOBJ)zdict.$(OBJ) : $(PSSRC)zdict.c $(OP)\ |
||||||
|
diff --git a/psi/interp.c b/psi/interp.c |
||||||
|
index 3dd5f7a..1dec9b6 100644 |
||||||
|
--- a/psi/interp.c |
||||||
|
+++ b/psi/interp.c |
||||||
|
@@ -142,7 +142,6 @@ static int oparray_pop(i_ctx_t *); |
||||||
|
static int oparray_cleanup(i_ctx_t *); |
||||||
|
static int zerrorexec(i_ctx_t *); |
||||||
|
static int zfinderrorobject(i_ctx_t *); |
||||||
|
-static int errorexec_find(i_ctx_t *, ref *); |
||||||
|
static int errorexec_pop(i_ctx_t *); |
||||||
|
static int errorexec_cleanup(i_ctx_t *); |
||||||
|
static int zsetstackprotect(i_ctx_t *); |
||||||
|
@@ -737,7 +736,7 @@ copy_stack(i_ctx_t *i_ctx_p, const ref_stack_t * pstack, int skip, ref * arr) |
||||||
|
{ |
||||||
|
uint size = ref_stack_count(pstack) - skip; |
||||||
|
uint save_space = ialloc_space(idmemory); |
||||||
|
- int code; |
||||||
|
+ int code, i; |
||||||
|
|
||||||
|
if (size > 65535) |
||||||
|
size = 65535; |
||||||
|
@@ -746,6 +745,15 @@ copy_stack(i_ctx_t *i_ctx_p, const ref_stack_t * pstack, int skip, ref * arr) |
||||||
|
if (code >= 0) |
||||||
|
code = ref_stack_store(pstack, arr, size, 0, 1, true, idmemory, |
||||||
|
"copy_stack"); |
||||||
|
+ /* If we are copying the exec stack, try to replace any oparrays with |
||||||
|
+ * with the operator than references them |
||||||
|
+ */ |
||||||
|
+ if (pstack == &e_stack) { |
||||||
|
+ for (i = 0; i < size; i++) { |
||||||
|
+ if (errorexec_find(i_ctx_p, &arr->value.refs[i]) < 0) |
||||||
|
+ make_null(&arr->value.refs[i]); |
||||||
|
+ } |
||||||
|
+ } |
||||||
|
ialloc_set_space(idmemory, save_space); |
||||||
|
return code; |
||||||
|
} |
||||||
|
@@ -1910,7 +1918,7 @@ zfinderrorobject(i_ctx_t *i_ctx_p) |
||||||
|
* .errorexec with errobj != null, store it in *perror_object and return 1, |
||||||
|
* otherwise return 0; |
||||||
|
*/ |
||||||
|
-static int |
||||||
|
+int |
||||||
|
errorexec_find(i_ctx_t *i_ctx_p, ref *perror_object) |
||||||
|
{ |
||||||
|
long i; |
||||||
|
diff --git a/psi/interp.h b/psi/interp.h |
||||||
|
index e9275b9..4f551d1 100644 |
||||||
|
--- a/psi/interp.h |
||||||
|
+++ b/psi/interp.h |
||||||
|
@@ -91,5 +91,7 @@ void gs_interp_reset(i_ctx_t *i_ctx_p); |
||||||
|
/* Define the top-level interface to the interpreter. */ |
||||||
|
int gs_interpret(i_ctx_t **pi_ctx_p, ref * pref, int user_errors, |
||||||
|
int *pexit_code, ref * perror_object); |
||||||
|
+int |
||||||
|
+errorexec_find(i_ctx_t *i_ctx_p, ref *perror_object); |
||||||
|
|
||||||
|
#endif /* interp_INCLUDED */ |
||||||
|
diff --git a/psi/zcontrol.c b/psi/zcontrol.c |
||||||
|
index 36da22c..0362cf4 100644 |
||||||
|
--- a/psi/zcontrol.c |
||||||
|
+++ b/psi/zcontrol.c |
||||||
|
@@ -24,6 +24,7 @@ |
||||||
|
#include "ipacked.h" |
||||||
|
#include "iutil.h" |
||||||
|
#include "store.h" |
||||||
|
+#include "interp.h" |
||||||
|
|
||||||
|
/* Forward references */ |
||||||
|
static int check_for_exec(const_os_ptr); |
||||||
|
@@ -787,7 +788,7 @@ zexecstack2(i_ctx_t *i_ctx_p) |
||||||
|
/* Continuation operator to do the actual transfer. */ |
||||||
|
/* r_size(op1) was set just above. */ |
||||||
|
static int |
||||||
|
-do_execstack(i_ctx_t *i_ctx_p, bool include_marks, os_ptr op1) |
||||||
|
+do_execstack(i_ctx_t *i_ctx_p, bool include_marks, bool include_oparrays, os_ptr op1) |
||||||
|
{ |
||||||
|
os_ptr op = osp; |
||||||
|
ref *arefs = op1->value.refs; |
||||||
|
@@ -829,6 +830,12 @@ do_execstack(i_ctx_t *i_ctx_p, bool include_marks, os_ptr op1) |
||||||
|
strlen(tname), (const byte *)tname); |
||||||
|
break; |
||||||
|
} |
||||||
|
+ case t_array: |
||||||
|
+ case t_shortarray: |
||||||
|
+ case t_mixedarray: |
||||||
|
+ if (!include_oparrays && errorexec_find(i_ctx_p, rq) < 0) |
||||||
|
+ make_null(rq); |
||||||
|
+ break; |
||||||
|
default: |
||||||
|
; |
||||||
|
} |
||||||
|
@@ -841,14 +848,14 @@ execstack_continue(i_ctx_t *i_ctx_p) |
||||||
|
{ |
||||||
|
os_ptr op = osp; |
||||||
|
|
||||||
|
- return do_execstack(i_ctx_p, false, op); |
||||||
|
+ return do_execstack(i_ctx_p, false, false, op); |
||||||
|
} |
||||||
|
static int |
||||||
|
execstack2_continue(i_ctx_t *i_ctx_p) |
||||||
|
{ |
||||||
|
os_ptr op = osp; |
||||||
|
|
||||||
|
- return do_execstack(i_ctx_p, op->value.boolval, op - 1); |
||||||
|
+ return do_execstack(i_ctx_p, op->value.boolval, true, op - 1); |
||||||
|
} |
||||||
|
|
||||||
|
/* - .needinput - */ |
||||||
|
-- |
||||||
|
2.17.2 |
||||||
|
|
@ -0,0 +1,240 @@ |
|||||||
|
From 8d19fdf63f91f50466b08f23e2d93d37a4c5ea0b Mon Sep 17 00:00:00 2001 |
||||||
|
From: Ken Sharp <ken.sharp@artifex.com> |
||||||
|
Date: Mon, 15 Oct 2018 11:28:28 +0100 |
||||||
|
Subject: [PATCH] Make .forceput unavailable from '.policyprocs' helper |
||||||
|
dictionary |
||||||
|
|
||||||
|
Bug #69963 "1Policy is a dangerous operator, any callers should be odef" |
||||||
|
|
||||||
|
Leaving the .policyprocs dictionary with a procedure which is a simple |
||||||
|
wrapper for .forceput effectively leaves .forceput available. |
||||||
|
|
||||||
|
It seems that the only reason to have .policyprocs is to minimise the |
||||||
|
code in .applypolicies, so we can remove the dictionary and put the |
||||||
|
code straight into .applypolicies, which we can then bind and make |
||||||
|
executeonly, which hides the .forceput. Also, since we don't need |
||||||
|
.applypolicies after startup, we can undefine that from systemdict too. |
||||||
|
|
||||||
|
While we're here, review all the uses of .force* to make certain that |
||||||
|
there are no other similar cases. This showed a few places where we |
||||||
|
hadn't made a function executeonly, so do that too. Its probably not |
||||||
|
required, since I'm reasonably sure its impossible to load those |
||||||
|
functions as packed arrays (they are all defined as operators), but lets |
||||||
|
have a belt and braces approach, the additional time cost is negligible. |
||||||
|
--- |
||||||
|
Resource/Init/gs_diskn.ps | 2 +- |
||||||
|
Resource/Init/gs_dps.ps | 2 +- |
||||||
|
Resource/Init/gs_epsf.ps | 2 +- |
||||||
|
Resource/Init/gs_fonts.ps | 4 +- |
||||||
|
Resource/Init/gs_init.ps | 2 +- |
||||||
|
Resource/Init/gs_setpd.ps | 100 ++++++++++++++++++++------------------ |
||||||
|
6 files changed, 58 insertions(+), 54 deletions(-) |
||||||
|
|
||||||
|
diff --git a/Resource/Init/gs_diskn.ps b/Resource/Init/gs_diskn.ps |
||||||
|
index 26ec0b5..fd694bc 100644 |
||||||
|
--- a/Resource/Init/gs_diskn.ps |
||||||
|
+++ b/Resource/Init/gs_diskn.ps |
||||||
|
@@ -61,7 +61,7 @@ systemdict begin |
||||||
|
% doesn't get run enough to justify the complication |
||||||
|
//.putdevparams |
||||||
|
//systemdict /.searchabledevs .forceundef |
||||||
|
-} .bind odef % must be bound and hidden for .forceundef |
||||||
|
+} .bind executeonly odef % must be bound and hidden for .forceundef |
||||||
|
|
||||||
|
% ------ extend filenameforall to handle wildcards in %dev% part of pattern -------% |
||||||
|
/filenameforall { |
||||||
|
diff --git a/Resource/Init/gs_dps.ps b/Resource/Init/gs_dps.ps |
||||||
|
index daf7b0f..00c14d5 100644 |
||||||
|
--- a/Resource/Init/gs_dps.ps |
||||||
|
+++ b/Resource/Init/gs_dps.ps |
||||||
|
@@ -124,7 +124,7 @@ |
||||||
|
/savedinitialgstate .systemvar setgstate gsave |
||||||
|
% Wrap up. |
||||||
|
end .setglobal |
||||||
|
-} odef |
||||||
|
+} bind executeonly odef |
||||||
|
|
||||||
|
% Check whether an object is a procedure. |
||||||
|
/.proccheck { % <obj> .proccheck <bool> |
||||||
|
diff --git a/Resource/Init/gs_epsf.ps b/Resource/Init/gs_epsf.ps |
||||||
|
index e4037d9..2d0f677 100644 |
||||||
|
--- a/Resource/Init/gs_epsf.ps |
||||||
|
+++ b/Resource/Init/gs_epsf.ps |
||||||
|
@@ -31,7 +31,7 @@ |
||||||
|
/EPSBoundingBoxState 5 def |
||||||
|
/EPSBoundingBoxSetState { |
||||||
|
//systemdict /EPSBoundingBoxState 3 -1 roll .forceput |
||||||
|
-} .bind odef % .forceput must be bound and hidden |
||||||
|
+} .bind executeonly odef % .forceput must be bound and hidden |
||||||
|
|
||||||
|
% Parse 4 numbers for a bounding box |
||||||
|
/EPSBoundingBoxParse { % (llx lly urx ury) -- llx lly urx ury true OR false |
||||||
|
diff --git a/Resource/Init/gs_fonts.ps b/Resource/Init/gs_fonts.ps |
||||||
|
index 7a57366..052a191 100644 |
||||||
|
--- a/Resource/Init/gs_fonts.ps |
||||||
|
+++ b/Resource/Init/gs_fonts.ps |
||||||
|
@@ -583,7 +583,7 @@ buildfontdict 3 /.buildfont3 cvx put |
||||||
|
} bind def |
||||||
|
/.setloadingfont { |
||||||
|
//systemdict /.loadingfont 3 -1 roll .forceput |
||||||
|
-} .bind odef % .forceput must be bound and hidden |
||||||
|
+} .bind executeonly odef % .forceput must be bound and hidden |
||||||
|
/.loadfont |
||||||
|
{ % Some buggy fonts leave extra junk on the stack, |
||||||
|
% so we have to make a closure that records the stack depth |
||||||
|
@@ -1012,7 +1012,7 @@ $error /SubstituteFont { } put |
||||||
|
dup length string copy |
||||||
|
.forceput setglobal |
||||||
|
} ifelse |
||||||
|
-} .bind odef % must be bound and hidden for .forceput |
||||||
|
+} .bind executeonly odef % must be bound and hidden for .forceput |
||||||
|
|
||||||
|
% Attempt to load a font from a file. |
||||||
|
/.tryloadfont { % <fontname> .tryloadfont <font> true |
||||||
|
diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps |
||||||
|
index 2114a2a..0b900e6 100644 |
||||||
|
--- a/Resource/Init/gs_init.ps |
||||||
|
+++ b/Resource/Init/gs_init.ps |
||||||
|
@@ -2244,7 +2244,7 @@ SAFER { .setsafeglobal } if |
||||||
|
/.localvmarray /.localvmdict /.localvmpackedarray /.localvmstring /.systemvmarray /.systemvmdict /.systemvmpackedarray /.systemvmstring /.systemvmfile /.systemvmlibfile |
||||||
|
/.systemvmSFD /.settrapparams /.currentsystemparams /.currentuserparams /.getsystemparam /.getuserparam /.setsystemparams /.setuserparams |
||||||
|
/.checkpassword /.locale_to_utf8 /.currentglobal /.gcheck /.imagepath /.currentoutputdevice |
||||||
|
- /.type /.writecvs /.setSMask /.currentSMask /.needinput /.countexecstack /.execstack |
||||||
|
+ /.type /.writecvs /.setSMask /.currentSMask /.needinput /.countexecstack /.execstack /.applypolicies |
||||||
|
|
||||||
|
% Used by a free user in the Library of Congress. Apparently this is used to |
||||||
|
% draw a partial page, which is then filled in by the results of a barcode |
||||||
|
diff --git a/Resource/Init/gs_setpd.ps b/Resource/Init/gs_setpd.ps |
||||||
|
index fab8b84..71eb622 100644 |
||||||
|
--- a/Resource/Init/gs_setpd.ps |
||||||
|
+++ b/Resource/Init/gs_setpd.ps |
||||||
|
@@ -609,6 +609,23 @@ NOMEDIAATTRS { |
||||||
|
% and we replace the key in the <merged> dictionary with its prior value |
||||||
|
% (or remove it if it had no prior value). |
||||||
|
|
||||||
|
+% These procedures are called with the following on the stack: |
||||||
|
+% <orig> <merged> <failed> <Policies> <key> <policy> |
||||||
|
+% They are expected to consume the top 2 operands. |
||||||
|
+% NOTE: we currently treat all values other than 0, 1, or 7 (for PageSize) |
||||||
|
+% the same as 0, i.e., we signal an error. |
||||||
|
+/0Policy { % Set errorinfo and signal a configurationerror. |
||||||
|
+ NOMEDIAATTRS { |
||||||
|
+ % NOMEDIAATTRS means that the default policy is 7... |
||||||
|
+ pop 2 index exch 7 put |
||||||
|
+ } { |
||||||
|
+ pop dup 4 index exch get 2 array astore |
||||||
|
+ $error /errorinfo 3 -1 roll put |
||||||
|
+ cleartomark |
||||||
|
+ /setpagedevice .systemvar /configurationerror signalerror |
||||||
|
+ } ifelse |
||||||
|
+} bind executeonly odef |
||||||
|
+ |
||||||
|
% Making this an operator means we can properly hide |
||||||
|
% the contents - specifically .forceput |
||||||
|
/1Policy |
||||||
|
@@ -617,59 +634,46 @@ NOMEDIAATTRS { |
||||||
|
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 } |
||||||
|
+ { 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> |
||||||
|
-% They are expected to consume the top 2 operands. |
||||||
|
-% NOTE: we currently treat all values other than 0, 1, or 7 (for PageSize) |
||||||
|
-% the same as 0, i.e., we signal an error. |
||||||
|
-% |
||||||
|
-% M. Sweet, Easy Software Products: |
||||||
|
-% |
||||||
|
-% Define NOMEDIAATTRS to turn off the default (but unimplementable) media |
||||||
|
-% selection policies for setpagedevice. This is used by CUPS to support |
||||||
|
-% the standard Adobe media attributes. |
||||||
|
- 0 { % Set errorinfo and signal a configurationerror. |
||||||
|
- NOMEDIAATTRS { |
||||||
|
- % NOMEDIAATTRS means that the default policy is 7... |
||||||
|
- pop 2 index exch 7 put |
||||||
|
- } { |
||||||
|
- pop dup 4 index exch get 2 array astore |
||||||
|
- $error /errorinfo 3 -1 roll put |
||||||
|
- cleartomark |
||||||
|
- /setpagedevice .systemvar /configurationerror signalerror |
||||||
|
- } ifelse |
||||||
|
- } bind |
||||||
|
- 1 /1Policy load |
||||||
|
- 7 { % For PageSize only, just impose the request. |
||||||
|
- 1 index /PageSize eq |
||||||
|
- { pop pop 1 index /PageSize 7 put } |
||||||
|
- { .policyprocs 0 get exec } |
||||||
|
- ifelse |
||||||
|
- } bind |
||||||
|
-.dicttomark readonly def |
||||||
|
-currentdict /1Policy undef |
||||||
|
+/7Policy { % For PageSize only, just impose the request. |
||||||
|
+ 1 index /PageSize eq |
||||||
|
+ { pop pop 1 index /PageSize 7 put } |
||||||
|
+ { .policyprocs 0 get exec } |
||||||
|
+ ifelse |
||||||
|
+} bind executeonly odef |
||||||
|
|
||||||
|
/.applypolicies % <orig> <merged> <failed> .applypolicies |
||||||
|
% <orig> <merged'> <failed'> |
||||||
|
- { 1 index /Policies get 1 index |
||||||
|
- { type /integertype eq |
||||||
|
- { pop % already processed |
||||||
|
- } |
||||||
|
- { 2 copy .knownget not { 1 index /PolicyNotFound get } if |
||||||
|
- % Stack: <orig> <merged> <failed> <Policies> <key> |
||||||
|
- % <policy> |
||||||
|
- .policyprocs 1 index .knownget not { .policyprocs 0 get } if exec |
||||||
|
- } |
||||||
|
- ifelse |
||||||
|
- } |
||||||
|
- forall pop |
||||||
|
- } bind def |
||||||
|
+{ |
||||||
|
+ 1 index /Policies get 1 index |
||||||
|
+ { type /integertype eq |
||||||
|
+ { |
||||||
|
+ pop % already processed |
||||||
|
+ }{ |
||||||
|
+ 2 copy .knownget not { 1 index /PolicyNotFound get } if |
||||||
|
+ % Stack: <orig> <merged> <failed> <Policies> <key> |
||||||
|
+ % <policy> |
||||||
|
+ dup 1 eq { |
||||||
|
+ 1Policy |
||||||
|
+ }{ |
||||||
|
+ dup 7 eq { |
||||||
|
+ 7Policy |
||||||
|
+ }{ |
||||||
|
+ 0Policy |
||||||
|
+ } ifelse |
||||||
|
+ } ifelse |
||||||
|
+ } ifelse |
||||||
|
+ } |
||||||
|
+ forall pop |
||||||
|
+} bind executeonly odef |
||||||
|
+ |
||||||
|
+currentdict /0Policy undef |
||||||
|
+currentdict /1Policy undef |
||||||
|
+currentdict /7Policy undef |
||||||
|
|
||||||
|
% Prepare to present parameters to the device, by spreading them onto the |
||||||
|
% operand stack and removing any that shouldn't be presented. |
||||||
|
@@ -1012,7 +1016,7 @@ SETPDDEBUG { (Installing.) = pstack flush } if |
||||||
|
.postinstall |
||||||
|
} ifelse |
||||||
|
setglobal % return to original VM allocation mode |
||||||
|
-} odef |
||||||
|
+} bind executeonly odef |
||||||
|
|
||||||
|
% We break out the code after calling the Install procedure into a |
||||||
|
% separate procedure, since it is executed even if Install causes an error. |
||||||
|
-- |
||||||
|
2.17.2 |
||||||
|
|
@ -0,0 +1,153 @@ |
|||||||
|
From 693baf02152119af6e6afd30bb8ec76d14f84bbf Mon Sep 17 00:00:00 2001 |
||||||
|
From: Ken Sharp <ken.sharp@artifex.com> |
||||||
|
Date: Thu, 8 Nov 2018 14:43:32 +0000 |
||||||
|
Subject: [PATCH] PS interpreter - check the Implementation of a Pattern before |
||||||
|
use |
||||||
|
|
||||||
|
Bug #700141 "Type confusion in setpattern" |
||||||
|
|
||||||
|
As the bug thread says, we were not checking that the Implementation |
||||||
|
of a pattern dictionary was a structure type, leading to a crash when |
||||||
|
we tried to treat it as one. |
||||||
|
|
||||||
|
Here we make the st_pattern1_instance and st_pattern2_instance |
||||||
|
structures public definitions and in zsetcolor we check the object |
||||||
|
stored under the Implementation key in the supplied dictionary to see if |
||||||
|
its a t_struct or t_astruct type, and if it is that its a |
||||||
|
st_pattern1_instance or st_pattern2_instance structure. |
||||||
|
|
||||||
|
If either check fails we throw a typecheck error. |
||||||
|
|
||||||
|
We need to make the st_pattern1_instance and st_pattern2_instance |
||||||
|
definitions public as they are defined in the graphics library and we |
||||||
|
need to check in the interpreter. |
||||||
|
--- |
||||||
|
base/gsptype1.c | 2 +- |
||||||
|
base/gsptype2.c | 6 +++--- |
||||||
|
base/gsptype2.h | 4 ++-- |
||||||
|
base/gxcolor2.h | 4 ++-- |
||||||
|
psi/zcolor.c | 11 ++++++++--- |
||||||
|
5 files changed, 16 insertions(+), 11 deletions(-) |
||||||
|
|
||||||
|
diff --git a/base/gsptype1.c b/base/gsptype1.c |
||||||
|
index 27fdd5a..e98dde1 100644 |
||||||
|
--- a/base/gsptype1.c |
||||||
|
+++ b/base/gsptype1.c |
||||||
|
@@ -50,7 +50,7 @@ |
||||||
|
|
||||||
|
/* GC descriptors */ |
||||||
|
private_st_pattern1_template(); |
||||||
|
-private_st_pattern1_instance(); |
||||||
|
+public_st_pattern1_instance(); |
||||||
|
|
||||||
|
/* GC procedures */ |
||||||
|
static ENUM_PTRS_BEGIN(pattern1_instance_enum_ptrs) { |
||||||
|
diff --git a/base/gsptype2.c b/base/gsptype2.c |
||||||
|
index 791e538..c53eb2e 100644 |
||||||
|
--- a/base/gsptype2.c |
||||||
|
+++ b/base/gsptype2.c |
||||||
|
@@ -33,7 +33,7 @@ |
||||||
|
|
||||||
|
/* GC descriptors */ |
||||||
|
private_st_pattern2_template(); |
||||||
|
-private_st_pattern2_instance(); |
||||||
|
+public_st_pattern2_instance(); |
||||||
|
|
||||||
|
/* GC procedures */ |
||||||
|
static ENUM_PTRS_BEGIN(pattern2_instance_enum_ptrs) { |
||||||
|
@@ -206,10 +206,10 @@ gs_pattern2_set_color(const gs_client_color * pcc, gs_gstate * pgs) |
||||||
|
|
||||||
|
pinst->saved->overprint_mode = pgs->overprint_mode; |
||||||
|
pinst->saved->overprint = pgs->overprint; |
||||||
|
- |
||||||
|
+ |
||||||
|
num_comps = pgs->device->color_info.num_components; |
||||||
|
for (k = 0; k < num_comps; k++) { |
||||||
|
- pgs->color_component_map.color_map[k] = |
||||||
|
+ pgs->color_component_map.color_map[k] = |
||||||
|
pinst->saved->color_component_map.color_map[k]; |
||||||
|
} |
||||||
|
code = pcs->type->set_overprint(pcs, pgs); |
||||||
|
diff --git a/base/gsptype2.h b/base/gsptype2.h |
||||||
|
index f0f26d1..4186201 100644 |
||||||
|
--- a/base/gsptype2.h |
||||||
|
+++ b/base/gsptype2.h |
||||||
|
@@ -57,8 +57,8 @@ typedef struct gs_pattern2_instance_s { |
||||||
|
bool shfill; |
||||||
|
} gs_pattern2_instance_t; |
||||||
|
|
||||||
|
-#define private_st_pattern2_instance() /* in gsptype2.c */\ |
||||||
|
- gs_private_st_composite(st_pattern2_instance, gs_pattern2_instance_t,\ |
||||||
|
+#define public_st_pattern2_instance() /* in gsptype2.c */\ |
||||||
|
+ gs_public_st_composite(st_pattern2_instance, gs_pattern2_instance_t,\ |
||||||
|
"gs_pattern2_instance_t", pattern2_instance_enum_ptrs,\ |
||||||
|
pattern2_instance_reloc_ptrs) |
||||||
|
|
||||||
|
diff --git a/base/gxcolor2.h b/base/gxcolor2.h |
||||||
|
index 62ec05e..d5b1095 100644 |
||||||
|
--- a/base/gxcolor2.h |
||||||
|
+++ b/base/gxcolor2.h |
||||||
|
@@ -92,8 +92,8 @@ struct gs_pattern1_instance_s { |
||||||
|
gx_bitmap_id id; /* key for cached bitmap (= id of mask) */ |
||||||
|
}; |
||||||
|
|
||||||
|
-#define private_st_pattern1_instance() /* in gsptype1.c */\ |
||||||
|
- gs_private_st_composite(st_pattern1_instance, gs_pattern1_instance_t,\ |
||||||
|
+#define public_st_pattern1_instance() /* in gsptype1.c */\ |
||||||
|
+ gs_public_st_composite(st_pattern1_instance, gs_pattern1_instance_t,\ |
||||||
|
"gs_pattern1_instance_t", pattern1_instance_enum_ptrs,\ |
||||||
|
pattern1_instance_reloc_ptrs) |
||||||
|
|
||||||
|
diff --git a/psi/zcolor.c b/psi/zcolor.c |
||||||
|
index 7a00d4e..fe81e79 100644 |
||||||
|
--- a/psi/zcolor.c |
||||||
|
+++ b/psi/zcolor.c |
||||||
|
@@ -65,6 +65,8 @@ static const float default_0_1[] = {0, 1, 0, 1, 0, 1, 0, 1}; |
||||||
|
|
||||||
|
/* imported from gsht.c */ |
||||||
|
extern void gx_set_effective_transfer(gs_gstate *); |
||||||
|
+extern_st(st_pattern1_instance); |
||||||
|
+extern_st(st_pattern2_instance); |
||||||
|
|
||||||
|
/* Essential forward declarations */ |
||||||
|
static int validate_spaces(i_ctx_t *i_ctx_p, ref *arr, int *depth); |
||||||
|
@@ -289,6 +291,9 @@ zsetcolor(i_ctx_t * i_ctx_p) |
||||||
|
code = array_get(imemory, pImpl, 0, &pPatInst); |
||||||
|
if (code < 0) |
||||||
|
return code; |
||||||
|
+ if (!r_is_struct(&pPatInst) || (!r_has_stype(&pPatInst, imemory, st_pattern1_instance) && !r_has_stype(&pPatInst, imemory, st_pattern2_instance))) |
||||||
|
+ return_error(gs_error_typecheck); |
||||||
|
+ |
||||||
|
cc.pattern = r_ptr(&pPatInst, gs_pattern_instance_t); |
||||||
|
n_numeric_comps = ( pattern_instance_uses_base_space(cc.pattern) |
||||||
|
? n_comps - 1 |
||||||
|
@@ -4421,7 +4426,7 @@ static int setindexedspace(i_ctx_t * i_ctx_p, ref *r, int *stage, int *cont, int |
||||||
|
/* If we have a named color profile and the base space is DeviceN or |
||||||
|
Separation use a different set of procedures to ensure the named |
||||||
|
color remapping code is used */ |
||||||
|
- if (igs->icc_manager->device_named != NULL && |
||||||
|
+ if (igs->icc_manager->device_named != NULL && |
||||||
|
(base_type == gs_color_space_index_Separation || |
||||||
|
base_type == gs_color_space_index_DeviceN)) |
||||||
|
pcs = gs_cspace_alloc(imemory, &gs_color_space_type_Indexed_Named); |
||||||
|
@@ -5573,7 +5578,7 @@ static int iccompareproc(i_ctx_t *i_ctx_p, ref *space, ref *testspace) |
||||||
|
return 0; |
||||||
|
|
||||||
|
/* As a quick check see if current is same as new */ |
||||||
|
- if (ICCdict1.value.bytes == ICCdict2.value.bytes) |
||||||
|
+ if (ICCdict1.value.bytes == ICCdict2.value.bytes) |
||||||
|
return 1; |
||||||
|
|
||||||
|
/* Need to check all the various parts */ |
||||||
|
@@ -5593,7 +5598,7 @@ static int iccompareproc(i_ctx_t *i_ctx_p, ref *space, ref *testspace) |
||||||
|
code2 = dict_find_string(&ICCdict2, "DataSource", &tempref2); |
||||||
|
if (code2 <= 0) |
||||||
|
return 0; |
||||||
|
- if (r_size(tempref1) != r_size(tempref2)) |
||||||
|
+ if (r_size(tempref1) != r_size(tempref2)) |
||||||
|
return 0; |
||||||
|
|
||||||
|
buff_size = r_size(tempref1); |
||||||
|
-- |
||||||
|
2.17.2 |
||||||
|
|
@ -0,0 +1,322 @@ |
|||||||
|
From 661e8d8fb8248c38d67958beda32f3a5876d0c3f Mon Sep 17 00:00:00 2001 |
||||||
|
From: Chris Liddell <chris.liddell@artifex.com> |
||||||
|
Date: Wed, 14 Nov 2018 09:50:08 +0000 |
||||||
|
Subject: [PATCH 1/4] Bug 700176: check the *output* device for |
||||||
|
LockSafetyParams |
||||||
|
|
||||||
|
When calling .setdevice we were checking if LockSafetyParams was set, and if so |
||||||
|
throwing an invalidaccess error. |
||||||
|
|
||||||
|
The problem is, if another device, for example the pdf14 compositor is the 'top' |
||||||
|
device, that does not (and cannot) honour LockSafetyParams. |
||||||
|
|
||||||
|
To solve this, we'll now use the (relatively new) gxdso_current_output_device |
||||||
|
spec_op to retrieve the *actual* output device, and check the LockSafetyParams |
||||||
|
flag in that. |
||||||
|
--- |
||||||
|
psi/zdevice.c | 12 ++++++++---- |
||||||
|
1 file changed, 8 insertions(+), 4 deletions(-) |
||||||
|
|
||||||
|
diff --git a/psi/zdevice.c b/psi/zdevice.c |
||||||
|
index 8d48b74..c276746 100644 |
||||||
|
--- a/psi/zdevice.c |
||||||
|
+++ b/psi/zdevice.c |
||||||
|
@@ -461,13 +461,17 @@ zputdeviceparams(i_ctx_t *i_ctx_p) |
||||||
|
int |
||||||
|
zsetdevice(i_ctx_t *i_ctx_p) |
||||||
|
{ |
||||||
|
- gx_device *dev = gs_currentdevice(igs); |
||||||
|
+ gx_device *odev = NULL, *dev = gs_currentdevice(igs); |
||||||
|
os_ptr op = osp; |
||||||
|
- int code = 0; |
||||||
|
+ int code = dev_proc(dev, dev_spec_op)(dev, |
||||||
|
+ gxdso_current_output_device, (void *)&odev, 0); |
||||||
|
+ |
||||||
|
+ if (code < 0) |
||||||
|
+ return code; |
||||||
|
|
||||||
|
check_write_type(*op, t_device); |
||||||
|
- if (dev->LockSafetyParams) { /* do additional checking if locked */ |
||||||
|
- if(op->value.pdevice != dev) /* don't allow a different device */ |
||||||
|
+ if (odev->LockSafetyParams) { /* do additional checking if locked */ |
||||||
|
+ if(op->value.pdevice != odev) /* don't allow a different device */ |
||||||
|
return_error(gs_error_invalidaccess); |
||||||
|
} |
||||||
|
dev->ShowpageCount = 0; |
||||||
|
-- |
||||||
|
2.17.2 |
||||||
|
|
||||||
|
|
||||||
|
From ea1b3ef437f39e45874f821c06bd953196625ac5 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Chris Liddell <chris.liddell@artifex.com> |
||||||
|
Date: Wed, 14 Nov 2018 21:04:46 +0000 |
||||||
|
Subject: [PATCH 2/4] Bug 700176: Use the actual output device for both devices |
||||||
|
in setdevice |
||||||
|
|
||||||
|
Also fixes bug 700189. |
||||||
|
|
||||||
|
The pdf14 compositor device, despite being a forwarding device, does not forward |
||||||
|
all spec_ops to it's target, only a select few are special cased for that. |
||||||
|
gxdso_current_output_device needs to be included in those special cases. |
||||||
|
|
||||||
|
The original commit (661e8d8fb8248) changed the code to use the spec_op to |
||||||
|
retrieve the output device, checking that for LockSafetyParams. If |
||||||
|
LockSafetyParams is set, it returns an invalidaccess error if the new device |
||||||
|
differs from the current device. |
||||||
|
|
||||||
|
When we do the comparison between the two devices, we need to check the |
||||||
|
output device in both cases. |
||||||
|
|
||||||
|
This is complicated by the fact that the new device may not have ever been set |
||||||
|
(and thus fully initialised), and may not have a spec_op method available at |
||||||
|
that point. |
||||||
|
--- |
||||||
|
base/gdevp14.c | 3 ++- |
||||||
|
psi/zdevice.c | 18 ++++++++++++++++-- |
||||||
|
2 files changed, 18 insertions(+), 3 deletions(-) |
||||||
|
|
||||||
|
diff --git a/base/gdevp14.c b/base/gdevp14.c |
||||||
|
index f89bc04..f47ed30 100644 |
||||||
|
--- a/base/gdevp14.c |
||||||
|
+++ b/base/gdevp14.c |
||||||
|
@@ -5618,7 +5618,8 @@ pdf14_dev_spec_op(gx_device *pdev, int dev_spec_op, |
||||||
|
return 0; |
||||||
|
} |
||||||
|
} |
||||||
|
- if (dev_spec_op == gxdso_get_dev_param || dev_spec_op == gxdso_restrict_bbox) { |
||||||
|
+ if (dev_spec_op == gxdso_get_dev_param || dev_spec_op == gxdso_restrict_bbox |
||||||
|
+ || dev_spec_op == gxdso_current_output_device) { |
||||||
|
return dev_proc(p14dev->target, dev_spec_op)(p14dev->target, dev_spec_op, data, size); |
||||||
|
} |
||||||
|
|
||||||
|
diff --git a/psi/zdevice.c b/psi/zdevice.c |
||||||
|
index c276746..4beda04 100644 |
||||||
|
--- a/psi/zdevice.c |
||||||
|
+++ b/psi/zdevice.c |
||||||
|
@@ -462,16 +462,30 @@ int |
||||||
|
zsetdevice(i_ctx_t *i_ctx_p) |
||||||
|
{ |
||||||
|
gx_device *odev = NULL, *dev = gs_currentdevice(igs); |
||||||
|
+ gx_device *ndev = NULL; |
||||||
|
os_ptr op = osp; |
||||||
|
int code = dev_proc(dev, dev_spec_op)(dev, |
||||||
|
gxdso_current_output_device, (void *)&odev, 0); |
||||||
|
|
||||||
|
if (code < 0) |
||||||
|
return code; |
||||||
|
- |
||||||
|
check_write_type(*op, t_device); |
||||||
|
+ |
||||||
|
+ /* slightly icky special case: the new device may not have had |
||||||
|
+ * it's procs initialised, at this point - but we need to check |
||||||
|
+ * whether we're being asked to change the device here |
||||||
|
+ */ |
||||||
|
+ if (dev_proc((op->value.pdevice), dev_spec_op) == NULL) |
||||||
|
+ ndev = op->value.pdevice; |
||||||
|
+ else |
||||||
|
+ code = dev_proc((op->value.pdevice), dev_spec_op)(op->value.pdevice, |
||||||
|
+ gxdso_current_output_device, (void *)&ndev, 0); |
||||||
|
+ |
||||||
|
+ if (code < 0) |
||||||
|
+ return code; |
||||||
|
+ |
||||||
|
if (odev->LockSafetyParams) { /* do additional checking if locked */ |
||||||
|
- if(op->value.pdevice != odev) /* don't allow a different device */ |
||||||
|
+ if(ndev != odev) /* don't allow a different device */ |
||||||
|
return_error(gs_error_invalidaccess); |
||||||
|
} |
||||||
|
dev->ShowpageCount = 0; |
||||||
|
-- |
||||||
|
2.17.2 |
||||||
|
|
||||||
|
|
||||||
|
From 7c3e7eee829cc3d2582e4aa7ae1fd495ca72cef1 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Chris Liddell <chris.liddell@artifex.com> |
||||||
|
Date: Mon, 17 Sep 2018 14:06:12 +0100 |
||||||
|
Subject: [PATCH 3/4] Implement .currentoutputdevice operator |
||||||
|
|
||||||
|
The currentdevice operator returns the device currently installed in the |
||||||
|
graphics state. This can be the output/page device, but also could be a |
||||||
|
forwarding device (bbox device), compositor (pdf14) or subclass device |
||||||
|
(erasepage optimisation, First/Last page etc). |
||||||
|
|
||||||
|
In certain circumstances (for example during a setpagedevice) we want to be |
||||||
|
sure we're retrieving the *actual* output/page device. |
||||||
|
|
||||||
|
The new .currentoutputdevice operator uses the spec_op device method to traverse |
||||||
|
any chain of devices and retrieve the final device in the chain, which |
||||||
|
should always be the output/page device. |
||||||
|
--- |
||||||
|
Resource/Init/gs_init.ps | 2 +- |
||||||
|
Resource/Init/gs_setpd.ps | 8 +++++++- |
||||||
|
base/gdevdflt.c | 5 +++++ |
||||||
|
base/gxdevsop.h | 4 ++++ |
||||||
|
psi/zdevice.c | 30 ++++++++++++++++++++++++++++++ |
||||||
|
5 files changed, 47 insertions(+), 2 deletions(-) |
||||||
|
|
||||||
|
diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps |
||||||
|
index bec307d..55d6923 100644 |
||||||
|
--- a/Resource/Init/gs_init.ps |
||||||
|
+++ b/Resource/Init/gs_init.ps |
||||||
|
@@ -2211,7 +2211,7 @@ SAFER { .setsafeglobal } if |
||||||
|
/.shfill /.argindex /.bytestring /.namestring /.stringbreak /.stringmatch /.globalvmarray /.globalvmdict /.globalvmpackedarray /.globalvmstring |
||||||
|
/.localvmarray /.localvmdict /.localvmpackedarray /.localvmstring /.systemvmarray /.systemvmdict /.systemvmpackedarray /.systemvmstring /.systemvmfile /.systemvmlibfile |
||||||
|
/.systemvmSFD /.settrapparams /.currentsystemparams /.currentuserparams /.getsystemparam /.getuserparam /.setsystemparams /.setuserparams |
||||||
|
- /.checkpassword /.locale_to_utf8 /.currentglobal /.gcheck /.imagepath |
||||||
|
+ /.checkpassword /.locale_to_utf8 /.currentglobal /.gcheck /.imagepath /.currentoutputdevice |
||||||
|
|
||||||
|
% Used by a free user in the Library of Congress. Apparently this is used to |
||||||
|
% draw a partial page, which is then filled in by the results of a barcode |
||||||
|
diff --git a/Resource/Init/gs_setpd.ps b/Resource/Init/gs_setpd.ps |
||||||
|
index 8fa7c51..aa79b3f 100644 |
||||||
|
--- a/Resource/Init/gs_setpd.ps |
||||||
|
+++ b/Resource/Init/gs_setpd.ps |
||||||
|
@@ -877,7 +877,13 @@ SETPDDEBUG { (Selecting.) = pstack flush } if |
||||||
|
% Stack: mark <orig> <request> <merged> <failed> |
||||||
|
SETPDDEBUG { (Constructing.) = pstack flush } if |
||||||
|
|
||||||
|
- currentdevice .devicename 2 index /OutputDevice get eq |
||||||
|
+ % Non-obvious: we need to check the name of the output device, to tell |
||||||
|
+ % whether we're going to have to replace the entire device chain (which |
||||||
|
+ % may be only one device, or may be multiple devices. |
||||||
|
+ % If we're not replacing the entire change, we have to use the device in |
||||||
|
+ % the graphics state, so the configuration of the entire device chain is |
||||||
|
+ % correctly set. |
||||||
|
+ .currentoutputdevice .devicename 2 index /OutputDevice get eq |
||||||
|
{ currentdevice } |
||||||
|
{ 1 index /OutputDevice get finddevice } |
||||||
|
ifelse |
||||||
|
diff --git a/base/gdevdflt.c b/base/gdevdflt.c |
||||||
|
index 3cb9fbd..b5bd82b 100644 |
||||||
|
--- a/base/gdevdflt.c |
||||||
|
+++ b/base/gdevdflt.c |
||||||
|
@@ -1044,6 +1044,11 @@ gx_default_dev_spec_op(gx_device *pdev, int dev_spec_op, void *data, int size) |
||||||
|
dev_param_req_t *request = (dev_param_req_t *)data; |
||||||
|
return gx_default_get_param(pdev, request->Param, request->list); |
||||||
|
} |
||||||
|
+ case gxdso_current_output_device: |
||||||
|
+ { |
||||||
|
+ *(gx_device **)data = pdev; |
||||||
|
+ return 0; |
||||||
|
+ } |
||||||
|
} |
||||||
|
return_error(gs_error_undefined); |
||||||
|
} |
||||||
|
diff --git a/base/gxdevsop.h b/base/gxdevsop.h |
||||||
|
index cd3b632..27e3e84 100644 |
||||||
|
--- a/base/gxdevsop.h |
||||||
|
+++ b/base/gxdevsop.h |
||||||
|
@@ -327,6 +327,10 @@ enum { |
||||||
|
gxdso_JPEG_passthrough_data, |
||||||
|
gxdso_JPEG_passthrough_end, |
||||||
|
gxdso_supports_iccpostrender, |
||||||
|
+ /* Retrieve the last device in a device chain |
||||||
|
+ (either forwarding or subclass devices). |
||||||
|
+ */ |
||||||
|
+ gxdso_current_output_device, |
||||||
|
/* Add new gxdso_ keys above this. */ |
||||||
|
gxdso_pattern__LAST |
||||||
|
}; |
||||||
|
diff --git a/psi/zdevice.c b/psi/zdevice.c |
||||||
|
index 4beda04..03285dc 100644 |
||||||
|
--- a/psi/zdevice.c |
||||||
|
+++ b/psi/zdevice.c |
||||||
|
@@ -57,6 +57,7 @@ zcopydevice2(i_ctx_t *i_ctx_p) |
||||||
|
} |
||||||
|
|
||||||
|
/* - currentdevice <device> */ |
||||||
|
+/* Returns the current device in the graphics state */ |
||||||
|
int |
||||||
|
zcurrentdevice(i_ctx_t *i_ctx_p) |
||||||
|
{ |
||||||
|
@@ -71,6 +72,34 @@ zcurrentdevice(i_ctx_t *i_ctx_p) |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
+/* - .currentoutputdevice <device> */ |
||||||
|
+/* Returns the *output* device - which will often |
||||||
|
+ be the same as above, but not always: if a compositor |
||||||
|
+ or other forwarding device, or subclassing device is |
||||||
|
+ in force, that will be referenced by the graphics state |
||||||
|
+ rather than the output device. |
||||||
|
+ This is equivalent of currentdevice device, but returns |
||||||
|
+ the *device* object, rather than the dictionary describing |
||||||
|
+ the device and device state. |
||||||
|
+ */ |
||||||
|
+static int |
||||||
|
+zcurrentoutputdevice(i_ctx_t *i_ctx_p) |
||||||
|
+{ |
||||||
|
+ os_ptr op = osp; |
||||||
|
+ gx_device *odev = NULL, *dev = gs_currentdevice(igs); |
||||||
|
+ gs_ref_memory_t *mem = (gs_ref_memory_t *) dev->memory; |
||||||
|
+ int code = dev_proc(dev, dev_spec_op)(dev, |
||||||
|
+ gxdso_current_output_device, (void *)&odev, 0); |
||||||
|
+ if (code < 0) |
||||||
|
+ return code; |
||||||
|
+ |
||||||
|
+ push(1); |
||||||
|
+ make_tav(op, t_device, |
||||||
|
+ (mem == 0 ? avm_foreign : imemory_space(mem)) | a_all, |
||||||
|
+ pdevice, odev); |
||||||
|
+ return 0; |
||||||
|
+} |
||||||
|
+ |
||||||
|
/* <device> .devicename <string> */ |
||||||
|
static int |
||||||
|
zdevicename(i_ctx_t *i_ctx_p) |
||||||
|
@@ -632,6 +661,7 @@ const op_def zdevice_op_defs[] = |
||||||
|
{ |
||||||
|
{"1.copydevice2", zcopydevice2}, |
||||||
|
{"0currentdevice", zcurrentdevice}, |
||||||
|
+ {"0.currentoutputdevice", zcurrentoutputdevice}, |
||||||
|
{"1.devicename", zdevicename}, |
||||||
|
{"0.doneshowpage", zdoneshowpage}, |
||||||
|
{"0flushpage", zflushpage}, |
||||||
|
-- |
||||||
|
2.17.2 |
||||||
|
|
||||||
|
|
||||||
|
From 4d98293c72cc5b5fe456065a3252d39e9ab28e4d Mon Sep 17 00:00:00 2001 |
||||||
|
From: Ken Sharp <ken.sharp@artifex.com> |
||||||
|
Date: Mon, 19 Nov 2018 09:00:54 +0000 |
||||||
|
Subject: [PATCH 4/4] Coverity ID 327264 - move pointer NULL check |
||||||
|
|
||||||
|
Due to recent changes in this code, the pointer was being dereferenced |
||||||
|
before we checked it to see if it was NULL. Moe the check so that we |
||||||
|
check for NULL before dereferencing. |
||||||
|
|
||||||
|
The 'pvalue' of the operand can be NULL, even if the object is a t_device |
||||||
|
type, because invalidate_stack_devices traverses the operand stack |
||||||
|
looking for devices, and sets their pvalue member to NULL in order to |
||||||
|
invalidate them so that they cannot be used. |
||||||
|
--- |
||||||
|
psi/zdevice.c | 6 +++--- |
||||||
|
1 file changed, 3 insertions(+), 3 deletions(-) |
||||||
|
|
||||||
|
diff --git a/psi/zdevice.c b/psi/zdevice.c |
||||||
|
index 03285dc..63865f1 100644 |
||||||
|
--- a/psi/zdevice.c |
||||||
|
+++ b/psi/zdevice.c |
||||||
|
@@ -500,6 +500,9 @@ zsetdevice(i_ctx_t *i_ctx_p) |
||||||
|
return code; |
||||||
|
check_write_type(*op, t_device); |
||||||
|
|
||||||
|
+ if (op->value.pdevice == 0) |
||||||
|
+ return gs_note_error(gs_error_undefined); |
||||||
|
+ |
||||||
|
/* slightly icky special case: the new device may not have had |
||||||
|
* it's procs initialised, at this point - but we need to check |
||||||
|
* whether we're being asked to change the device here |
||||||
|
@@ -519,9 +522,6 @@ zsetdevice(i_ctx_t *i_ctx_p) |
||||||
|
} |
||||||
|
dev->ShowpageCount = 0; |
||||||
|
|
||||||
|
- if (op->value.pdevice == 0) |
||||||
|
- return gs_note_error(gs_error_undefined); |
||||||
|
- |
||||||
|
code = gs_setdevice_no_erase(igs, op->value.pdevice); |
||||||
|
if (code < 0) |
||||||
|
return code; |
||||||
|
-- |
||||||
|
2.17.2 |
||||||
|
|
@ -0,0 +1,29 @@ |
|||||||
|
From aeea342904978c9fe17d85f4906a0f6fcce2d315 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Chris Liddell <chris.liddell@artifex.com> |
||||||
|
Date: Mon, 12 Nov 2018 17:21:33 +0000 |
||||||
|
Subject: [PATCH] Bug 700153: restore: always check available stack |
||||||
|
|
||||||
|
Previously, we were checking there was enough stack space available when the |
||||||
|
restore operation required a device change, but since we have to use |
||||||
|
Postscript to reset the userparams (ick!), we need the stack check even when |
||||||
|
not changing the device. |
||||||
|
--- |
||||||
|
psi/zdevice2.c | 2 +- |
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-) |
||||||
|
|
||||||
|
diff --git a/psi/zdevice2.c b/psi/zdevice2.c |
||||||
|
index 159a0c0..e11b075 100644 |
||||||
|
--- a/psi/zdevice2.c |
||||||
|
+++ b/psi/zdevice2.c |
||||||
|
@@ -277,7 +277,7 @@ restore_page_device(i_ctx_t *i_ctx_p, const gs_gstate * pgs_old, const gs_gstate |
||||||
|
samepagedevice = false; |
||||||
|
} |
||||||
|
|
||||||
|
- if (LockSafetyParams && !samepagedevice) { |
||||||
|
+ if (LockSafetyParams) { |
||||||
|
const int required_ops = 512; |
||||||
|
const int required_es = 32; |
||||||
|
|
||||||
|
-- |
||||||
|
2.17.2 |
||||||
|
|
@ -0,0 +1,666 @@ |
|||||||
|
From fac7eb144135f3ed8fbb0028ab1f33ce4dcc1985 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Ken Sharp <ken.sharp@artifex.com> |
||||||
|
Date: Fri, 21 Sep 2018 13:02:56 +0100 |
||||||
|
Subject: [PATCH 1/3] Check all uses of dict_find* to ensure 0 return properly |
||||||
|
handled |
||||||
|
|
||||||
|
dict_find and friends have the surprising quirk of returning < 0 for |
||||||
|
an error and > 0 for no error. But they can also return 0 which means |
||||||
|
'not found' without it being an error. |
||||||
|
|
||||||
|
From bug 699801, if the code assumes the usual case where 0 is a success |
||||||
|
then an attempt might be made to use the empty dictionary slot returned |
||||||
|
by dict_find*, which can lead to seg faults, and certainly won't have |
||||||
|
the expected result. |
||||||
|
--- |
||||||
|
psi/icontext.c | 4 ++-- |
||||||
|
psi/zcid.c | 6 ++++-- |
||||||
|
psi/zfapi.c | 33 ++++++++++++++++++--------------- |
||||||
|
psi/zfcid0.c | 39 +++++++++++++++++++++++++++++---------- |
||||||
|
psi/zfcid1.c | 14 ++++++++++---- |
||||||
|
psi/zicc.c | 4 ++++ |
||||||
|
psi/zpdf_r6.c | 31 +++++++++++++++++++++++-------- |
||||||
|
psi/ztoken.c | 2 +- |
||||||
|
8 files changed, 91 insertions(+), 42 deletions(-) |
||||||
|
|
||||||
|
diff --git a/psi/icontext.c b/psi/icontext.c |
||||||
|
index 4db78e0..1fbe486 100644 |
||||||
|
--- a/psi/icontext.c |
||||||
|
+++ b/psi/icontext.c |
||||||
|
@@ -162,7 +162,7 @@ context_state_alloc(gs_context_state_t ** ppcst, |
||||||
|
uint size; |
||||||
|
ref *system_dict = &pcst->dict_stack.system_dict; |
||||||
|
|
||||||
|
- if (dict_find_string(system_dict, "userparams", &puserparams) >= 0) |
||||||
|
+ if (dict_find_string(system_dict, "userparams", &puserparams) > 0) |
||||||
|
size = dict_length(puserparams); |
||||||
|
else |
||||||
|
size = 300; |
||||||
|
@@ -286,7 +286,7 @@ context_state_store(gs_context_state_t * pcst) |
||||||
|
/* We need i_ctx_p for access to the d_stack. */ |
||||||
|
i_ctx_t *i_ctx_p = pcst; |
||||||
|
|
||||||
|
- if (dict_find_string(systemdict, "userparams", &puserparams) < 0) |
||||||
|
+ if (dict_find_string(systemdict, "userparams", &puserparams) <= 0) |
||||||
|
return_error(gs_error_Fatal); |
||||||
|
pcst->userparams = *puserparams; |
||||||
|
} |
||||||
|
diff --git a/psi/zcid.c b/psi/zcid.c |
||||||
|
index e394877..5c98fc9 100644 |
||||||
|
--- a/psi/zcid.c |
||||||
|
+++ b/psi/zcid.c |
||||||
|
@@ -72,11 +72,13 @@ TT_char_code_from_CID_no_subst(const gs_memory_t *mem, |
||||||
|
} else |
||||||
|
return false; /* Must not happen. */ |
||||||
|
for (;n--; i++) { |
||||||
|
+ int code; |
||||||
|
+ |
||||||
|
if (array_get(mem, DecodingArray, i, &char_code1) < 0 || |
||||||
|
!r_has_type(&char_code1, t_integer)) |
||||||
|
return false; /* Must not happen. */ |
||||||
|
- if (dict_find(TT_cmap, &char_code1, &glyph_index) >= 0 && |
||||||
|
- r_has_type(glyph_index, t_integer)) { |
||||||
|
+ code = dict_find(TT_cmap, &char_code1, &glyph_index); |
||||||
|
+ if (code > 0 && r_has_type(glyph_index, t_integer)) { |
||||||
|
*c = glyph_index->value.intval; |
||||||
|
found = true; |
||||||
|
if (*c != 0) |
||||||
|
diff --git a/psi/zfapi.c b/psi/zfapi.c |
||||||
|
index 48e1d54..1b687b0 100644 |
||||||
|
--- a/psi/zfapi.c |
||||||
|
+++ b/psi/zfapi.c |
||||||
|
@@ -1826,6 +1826,9 @@ FAPI_get_xlatmap(i_ctx_t *i_ctx_p, char **xlatmap) |
||||||
|
|
||||||
|
if ((code = dict_find_string(systemdict, ".xlatmap", &pref)) < 0) |
||||||
|
return code; |
||||||
|
+ if (code == 0) |
||||||
|
+ return_error(gs_error_undefined); |
||||||
|
+ |
||||||
|
if (r_type(pref) != t_string) |
||||||
|
return_error(gs_error_typecheck); |
||||||
|
*xlatmap = (char *)pref->value.bytes; |
||||||
|
@@ -1881,11 +1884,11 @@ ps_get_server_param(gs_fapi_server *I, const byte *subtype, |
||||||
|
ref *FAPIconfig, *options, *server_options; |
||||||
|
i_ctx_t *i_ctx_p = (i_ctx_t *) I->client_ctx_p; |
||||||
|
|
||||||
|
- if (dict_find_string(systemdict, ".FAPIconfig", &FAPIconfig) >= 0 |
||||||
|
+ if (dict_find_string(systemdict, ".FAPIconfig", &FAPIconfig) > 0 |
||||||
|
&& r_has_type(FAPIconfig, t_dictionary)) { |
||||||
|
- if (dict_find_string(FAPIconfig, "ServerOptions", &options) >= 0 |
||||||
|
+ if (dict_find_string(FAPIconfig, "ServerOptions", &options) > 0 |
||||||
|
&& r_has_type(options, t_dictionary)) { |
||||||
|
- if (dict_find_string(options, (char *)subtype, &server_options) >= |
||||||
|
+ if (dict_find_string(options, (char *)subtype, &server_options) > |
||||||
|
0 && r_has_type(server_options, t_string)) { |
||||||
|
*server_param = (byte *) server_options->value.const_bytes; |
||||||
|
*server_param_size = r_size(server_options); |
||||||
|
@@ -2070,7 +2073,7 @@ zFAPIrebuildfont(i_ctx_t *i_ctx_p) |
||||||
|
pdata = (font_data *) pfont->client_data; |
||||||
|
I = pbfont->FAPI; |
||||||
|
|
||||||
|
- if (dict_find_string((op - 1), "SubfontId", &v) >= 0 |
||||||
|
+ if (dict_find_string((op - 1), "SubfontId", &v) > 0 |
||||||
|
&& r_has_type(v, t_integer)) |
||||||
|
subfont = v->value.intval; |
||||||
|
else |
||||||
|
@@ -2277,8 +2280,8 @@ ps_get_glyphname_or_cid(gs_text_enum_t *penum, |
||||||
|
if (pbfont->FontType == ft_CID_TrueType && font_file_path) { |
||||||
|
ref *pdr2, *fidr, *dummy; |
||||||
|
pdr2 = pfont_dict(gs_rootfont(igs)); |
||||||
|
- if (dict_find_string(pdr2, "FontInfo", &fidr) && |
||||||
|
- dict_find_string(fidr, "GlyphNames2Unicode", &dummy)) |
||||||
|
+ if (dict_find_string(pdr2, "FontInfo", &fidr) > 0 && |
||||||
|
+ dict_find_string(fidr, "GlyphNames2Unicode", &dummy) > 0) |
||||||
|
{ |
||||||
|
unsigned char uc[4] = {0}; |
||||||
|
unsigned int cc = 0; |
||||||
|
@@ -2417,13 +2420,13 @@ ps_get_glyphname_or_cid(gs_text_enum_t *penum, |
||||||
|
|
||||||
|
fdict = pfont_dict(gs_rootfont(igs)); |
||||||
|
code = dict_find_string(fdict, "CMap", &CMapDict); |
||||||
|
- if (code >= 0 && r_has_type(CMapDict, t_dictionary)) { |
||||||
|
+ if (code > 0 && r_has_type(CMapDict, t_dictionary)) { |
||||||
|
code = dict_find_string(CMapDict, "WMode", &WMode); |
||||||
|
- if (code >= 0 && r_has_type(WMode, t_integer)) { |
||||||
|
+ if (code > 0 && r_has_type(WMode, t_integer)) { |
||||||
|
wmode = WMode->value.intval; |
||||||
|
} |
||||||
|
code = dict_find_string(CMapDict, "CMapName", &CMapName); |
||||||
|
- if (code >= 0 && r_has_type(CMapName, t_name)) { |
||||||
|
+ if (code > 0 && r_has_type(CMapName, t_name)) { |
||||||
|
name_string_ref(imemory, CMapName, &CMapNameStr); |
||||||
|
cmapnm = (char *)CMapNameStr.value.bytes; |
||||||
|
cmapnmlen = r_size(&CMapNameStr); |
||||||
|
@@ -2432,10 +2435,10 @@ ps_get_glyphname_or_cid(gs_text_enum_t *penum, |
||||||
|
/* We only have to lookup the char code if we're *not* using an identity ordering |
||||||
|
with the exception of Identity-UTF16 which is a different beast altogether */ |
||||||
|
if (unicode_cp || (cmapnmlen > 0 && !strncmp(cmapnm, utfcmap, cmapnmlen > utfcmaplen ? utfcmaplen : cmapnmlen)) |
||||||
|
- || (dict_find_string(pdr, "CIDSystemInfo", &CIDSystemInfo) >= 0 |
||||||
|
+ || (dict_find_string(pdr, "CIDSystemInfo", &CIDSystemInfo) > 0 |
||||||
|
&& r_has_type(CIDSystemInfo, t_dictionary) |
||||||
|
&& dict_find_string(CIDSystemInfo, "Ordering", |
||||||
|
- &Ordering) >= 0 |
||||||
|
+ &Ordering) > 0 |
||||||
|
&& r_has_type(Ordering, t_string) |
||||||
|
&& strncmp((const char *)Ordering->value.bytes, |
||||||
|
"Identity", 8) != 0)) { |
||||||
|
@@ -2463,7 +2466,7 @@ ps_get_glyphname_or_cid(gs_text_enum_t *penum, |
||||||
|
ref cc32; |
||||||
|
ref *gid; |
||||||
|
make_int(&cc32, 32); |
||||||
|
- if (dict_find(TT_cmap, &cc32, &gid) >= 0) |
||||||
|
+ if (dict_find(TT_cmap, &cc32, &gid) > 0) |
||||||
|
c = gid->value.intval; |
||||||
|
} |
||||||
|
cr->char_codes[0] = c; |
||||||
|
@@ -2536,7 +2539,7 @@ ps_get_glyphname_or_cid(gs_text_enum_t *penum, |
||||||
|
if (dict_find_string(pdr, "CharStrings", &CharStrings) <= 0 |
||||||
|
|| !r_has_type(CharStrings, t_dictionary)) |
||||||
|
return_error(gs_error_invalidfont); |
||||||
|
- if ((dict_find(CharStrings, &char_name, &glyph_index) < 0) |
||||||
|
+ if ((dict_find(CharStrings, &char_name, &glyph_index) <= 0) |
||||||
|
|| r_has_type(glyph_index, t_null)) { |
||||||
|
#ifdef DEBUG |
||||||
|
ref *pvalue; |
||||||
|
@@ -2955,7 +2958,7 @@ zFAPIpassfont(i_ctx_t *i_ctx_p) |
||||||
|
if (code < 0) |
||||||
|
return code; |
||||||
|
|
||||||
|
- if (dict_find_string(op, "SubfontId", &v) >= 0 |
||||||
|
+ if (dict_find_string(op, "SubfontId", &v) > 0 |
||||||
|
&& r_has_type(v, t_integer)) |
||||||
|
subfont = v->value.intval; |
||||||
|
else |
||||||
|
@@ -2968,7 +2971,7 @@ zFAPIpassfont(i_ctx_t *i_ctx_p) |
||||||
|
/* If the font dictionary contains a FAPIPlugInReq key, the the PS world wants us |
||||||
|
* to try to use a specific FAPI plugin, so find it, and try it.... |
||||||
|
*/ |
||||||
|
- if (dict_find_string(op, "FAPIPlugInReq", &v) >= 0 && r_type(v) == t_name) { |
||||||
|
+ if (dict_find_string(op, "FAPIPlugInReq", &v) > 0 && r_type(v) == t_name) { |
||||||
|
|
||||||
|
name_string_ref(imemory, v, &reqstr); |
||||||
|
|
||||||
|
diff --git a/psi/zfcid0.c b/psi/zfcid0.c |
||||||
|
index 2aba09a..ba00b21 100644 |
||||||
|
--- a/psi/zfcid0.c |
||||||
|
+++ b/psi/zfcid0.c |
||||||
|
@@ -410,13 +410,25 @@ zbuildfont9(i_ctx_t *i_ctx_p) |
||||||
|
* from a file, GlyphData will be an integer, and DataSource will be |
||||||
|
* a (reusable) stream. |
||||||
|
*/ |
||||||
|
- if (code < 0 || |
||||||
|
- (code = cid_font_data_param(op, &common, &GlyphDirectory)) < 0 || |
||||||
|
- (code = dict_find_string(op, "FDArray", &prfda)) < 0 || |
||||||
|
- (code = dict_find_string(op, "CIDFontName", &pCIDFontName)) <= 0 || |
||||||
|
- (code = dict_int_param(op, "FDBytes", 0, MAX_FDBytes, -1, &FDBytes)) < 0 |
||||||
|
- ) |
||||||
|
+ if (code < 0) |
||||||
|
+ return code; |
||||||
|
+ code = cid_font_data_param(op, &common, &GlyphDirectory); |
||||||
|
+ if (code < 0) |
||||||
|
+ return code; |
||||||
|
+ code = dict_find_string(op, "FDArray", &prfda); |
||||||
|
+ if (code < 0) |
||||||
|
+ return code; |
||||||
|
+ if (code == 0) |
||||||
|
+ return_error(gs_error_undefined); |
||||||
|
+ code = dict_find_string(op, "CIDFontName", &pCIDFontName); |
||||||
|
+ if (code < 0) |
||||||
|
+ return code; |
||||||
|
+ if (code == 0) |
||||||
|
+ return_error(gs_error_undefined); |
||||||
|
+ code = dict_int_param(op, "FDBytes", 0, MAX_FDBytes, -1, &FDBytes); |
||||||
|
+ if (code < 0) |
||||||
|
return code; |
||||||
|
+ |
||||||
|
/* |
||||||
|
* Since build_gs_simple_font may resize the dictionary and cause |
||||||
|
* pointers to become invalid, save CIDFontName |
||||||
|
@@ -426,17 +438,24 @@ zbuildfont9(i_ctx_t *i_ctx_p) |
||||||
|
/* Standard CIDFont, require GlyphData and CIDMapOffset. */ |
||||||
|
ref *pGlyphData; |
||||||
|
|
||||||
|
- if ((code = dict_find_string(op, "GlyphData", &pGlyphData)) < 0 || |
||||||
|
- (code = dict_uint_param(op, "CIDMapOffset", 0, max_uint - 1, |
||||||
|
- max_uint, &CIDMapOffset)) < 0) |
||||||
|
+ code = dict_find_string(op, "GlyphData", &pGlyphData); |
||||||
|
+ if (code < 0) |
||||||
|
+ return code; |
||||||
|
+ if (code == 0) |
||||||
|
+ return_error(gs_error_undefined); |
||||||
|
+ code = dict_uint_param(op, "CIDMapOffset", 0, max_uint - 1, max_uint, &CIDMapOffset); |
||||||
|
+ if (code < 0) |
||||||
|
return code; |
||||||
|
GlyphData = *pGlyphData; |
||||||
|
if (r_has_type(&GlyphData, t_integer)) { |
||||||
|
ref *pds; |
||||||
|
stream *ignore_s; |
||||||
|
|
||||||
|
- if ((code = dict_find_string(op, "DataSource", &pds)) < 0) |
||||||
|
+ code = dict_find_string(op, "DataSource", &pds); |
||||||
|
+ if (code < 0) |
||||||
|
return code; |
||||||
|
+ if (code == 0) |
||||||
|
+ return_error(gs_error_undefined); |
||||||
|
check_read_file(i_ctx_p, ignore_s, pds); |
||||||
|
DataSource = *pds; |
||||||
|
} else { |
||||||
|
diff --git a/psi/zfcid1.c b/psi/zfcid1.c |
||||||
|
index ef3ece0..e3643a0 100644 |
||||||
|
--- a/psi/zfcid1.c |
||||||
|
+++ b/psi/zfcid1.c |
||||||
|
@@ -347,11 +347,17 @@ zbuildfont11(i_ctx_t *i_ctx_p) |
||||||
|
ref rcidmap, ignore_gdir, file, *pfile, cfnstr, *pCIDFontName, CIDFontName, *t; |
||||||
|
ulong loca_glyph_pos[2][2]; |
||||||
|
int code = cid_font_data_param(op, &common, &ignore_gdir); |
||||||
|
+ if (code < 0) |
||||||
|
+ return code; |
||||||
|
|
||||||
|
- if (code < 0 || |
||||||
|
- (code = dict_find_string(op, "CIDFontName", &pCIDFontName)) <= 0 || |
||||||
|
- (code = dict_int_param(op, "MetricsCount", 0, 4, 0, &MetricsCount)) < 0 |
||||||
|
- ) |
||||||
|
+ code = dict_find_string(op, "CIDFontName", &pCIDFontName); |
||||||
|
+ if (code <= 0) { |
||||||
|
+ if (code == 0) |
||||||
|
+ return_error(gs_error_undefined); |
||||||
|
+ return code; |
||||||
|
+ } |
||||||
|
+ code = dict_int_param(op, "MetricsCount", 0, 4, 0, &MetricsCount); |
||||||
|
+ if (code < 0) |
||||||
|
return code; |
||||||
|
/* |
||||||
|
* Since build_gs_simple_font may resize the dictionary and cause |
||||||
|
diff --git a/psi/zicc.c b/psi/zicc.c |
||||||
|
index ebf25fe..53bdf34 100644 |
||||||
|
--- a/psi/zicc.c |
||||||
|
+++ b/psi/zicc.c |
||||||
|
@@ -261,6 +261,8 @@ zset_outputintent(i_ctx_t * i_ctx_p) |
||||||
|
code = dict_find_string(op, "N", &pnval); |
||||||
|
if (code < 0) |
||||||
|
return code; |
||||||
|
+ if (code == 0) |
||||||
|
+ return_error(gs_error_undefined); |
||||||
|
ncomps = pnval->value.intval; |
||||||
|
|
||||||
|
/* verify the DataSource entry. Creat profile from stream */ |
||||||
|
@@ -491,6 +493,8 @@ znumicc_components(i_ctx_t * i_ctx_p) |
||||||
|
code = dict_find_string(op, "N", &pnval); |
||||||
|
if (code < 0) |
||||||
|
return code; |
||||||
|
+ if (code == 0) |
||||||
|
+ return_error(gs_error_undefined); |
||||||
|
ncomps = pnval->value.intval; |
||||||
|
/* verify the DataSource entry. Create profile from stream */ |
||||||
|
if (dict_find_string(op, "DataSource", &pstrmval) <= 0) |
||||||
|
diff --git a/psi/zpdf_r6.c b/psi/zpdf_r6.c |
||||||
|
index bcd4907..992f316 100644 |
||||||
|
--- a/psi/zpdf_r6.c |
||||||
|
+++ b/psi/zpdf_r6.c |
||||||
|
@@ -145,21 +145,36 @@ zcheck_r6_password(i_ctx_t * i_ctx_p) |
||||||
|
return_error(gs_error_typecheck); |
||||||
|
|
||||||
|
code = dict_find_string(CryptDict, "O", &Oref); |
||||||
|
- if (code < 0 || !r_has_type(Oref, t_string)) { |
||||||
|
+ if (code < 0) |
||||||
|
+ return code; |
||||||
|
+ if (code == 0) |
||||||
|
+ return_error(gs_error_undefined); |
||||||
|
+ if (!r_has_type(Oref, t_string)) |
||||||
|
return_error(gs_error_typecheck); |
||||||
|
- } |
||||||
|
+ |
||||||
|
code = dict_find_string(CryptDict, "OE", &OEref); |
||||||
|
- if (code < 0 || !r_has_type(OEref, t_string)) { |
||||||
|
+ if (code < 0) |
||||||
|
+ return code; |
||||||
|
+ if (code == 0) |
||||||
|
+ return_error(gs_error_undefined); |
||||||
|
+ if (!r_has_type(OEref, t_string)) |
||||||
|
return_error(gs_error_typecheck); |
||||||
|
- } |
||||||
|
+ |
||||||
|
code = dict_find_string(CryptDict, "U", &Uref); |
||||||
|
- if (code < 0 || !r_has_type(Uref, t_string)) { |
||||||
|
+ if (code < 0) |
||||||
|
+ return code; |
||||||
|
+ if (code == 0) |
||||||
|
+ return_error(gs_error_undefined); |
||||||
|
+ if (!r_has_type(Uref, t_string)) |
||||||
|
return_error(gs_error_typecheck); |
||||||
|
- } |
||||||
|
+ |
||||||
|
code = dict_find_string(CryptDict, "UE", &UEref); |
||||||
|
- if (code < 0 || !r_has_type(UEref, t_string)) { |
||||||
|
+ if (code < 0) |
||||||
|
+ return code; |
||||||
|
+ if (code == 0) |
||||||
|
+ return_error(gs_error_undefined); |
||||||
|
+ if (!r_has_type(UEref, t_string)) |
||||||
|
return_error(gs_error_typecheck); |
||||||
|
- } |
||||||
|
|
||||||
|
pop(2); |
||||||
|
op = osp; |
||||||
|
diff --git a/psi/ztoken.c b/psi/ztoken.c |
||||||
|
index 519cd09..9314d97 100644 |
||||||
|
--- a/psi/ztoken.c |
||||||
|
+++ b/psi/ztoken.c |
||||||
|
@@ -356,7 +356,7 @@ ztoken_scanner_options(const ref *upref, int old_options) |
||||||
|
int code = dict_find_string(upref, pnso->pname, &ppcproc); |
||||||
|
|
||||||
|
/* Update the options only if the parameter has changed. */ |
||||||
|
- if (code >= 0) { |
||||||
|
+ if (code > 0) { |
||||||
|
if (r_has_type(ppcproc, t_null)) |
||||||
|
options &= ~pnso->option; |
||||||
|
else |
||||||
|
-- |
||||||
|
2.17.2 |
||||||
|
|
||||||
|
|
||||||
|
From 434753adbe8be5534bfb9b7d91746023e8073d16 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Ken Sharp <ken.sharp@artifex.com> |
||||||
|
Date: Wed, 14 Nov 2018 09:25:13 +0000 |
||||||
|
Subject: [PATCH 2/3] Bug #700169 - unchecked type |
||||||
|
|
||||||
|
Bug #700169 "Type confusion in setcolorspace" |
||||||
|
|
||||||
|
In seticc() we extract "Name" from a dictionary, if it succeeds we then |
||||||
|
use it as a string, without checking the type to see if it is in fact |
||||||
|
a string. |
||||||
|
|
||||||
|
Add a check on the type, and add a couple to check that 'N' is an integer |
||||||
|
in a few places too. |
||||||
|
--- |
||||||
|
psi/zicc.c | 6 +++++- |
||||||
|
1 file changed, 5 insertions(+), 1 deletion(-) |
||||||
|
|
||||||
|
diff --git a/psi/zicc.c b/psi/zicc.c |
||||||
|
index 53bdf34..dbd2562 100644 |
||||||
|
--- a/psi/zicc.c |
||||||
|
+++ b/psi/zicc.c |
||||||
|
@@ -76,7 +76,7 @@ int seticc(i_ctx_t * i_ctx_p, int ncomps, ref *ICCdict, float *range_buff) |
||||||
|
want to have this buffer. */ |
||||||
|
/* Check if we have the /Name entry. This is used to associate with |
||||||
|
specs that have enumerated types to indicate sRGB sGray etc */ |
||||||
|
- if (dict_find_string(ICCdict, "Name", &pnameval) > 0){ |
||||||
|
+ if (dict_find_string(ICCdict, "Name", &pnameval) > 0 && r_has_type(pnameval, t_string)){ |
||||||
|
uint size = r_size(pnameval); |
||||||
|
char *str = (char *)gs_alloc_bytes(gs_gstate_memory(igs), size+1, "seticc"); |
||||||
|
memcpy(str, (const char *)pnameval->value.bytes, size); |
||||||
|
@@ -263,6 +263,8 @@ zset_outputintent(i_ctx_t * i_ctx_p) |
||||||
|
return code; |
||||||
|
if (code == 0) |
||||||
|
return_error(gs_error_undefined); |
||||||
|
+ if (r_type(pnval) != t_integer) |
||||||
|
+ return gs_note_error(gs_error_typecheck); |
||||||
|
ncomps = pnval->value.intval; |
||||||
|
|
||||||
|
/* verify the DataSource entry. Creat profile from stream */ |
||||||
|
@@ -495,6 +497,8 @@ znumicc_components(i_ctx_t * i_ctx_p) |
||||||
|
return code; |
||||||
|
if (code == 0) |
||||||
|
return_error(gs_error_undefined); |
||||||
|
+ if (r_type(pnval) != t_integer) |
||||||
|
+ return gs_note_error(gs_error_typecheck); |
||||||
|
ncomps = pnval->value.intval; |
||||||
|
/* verify the DataSource entry. Create profile from stream */ |
||||||
|
if (dict_find_string(op, "DataSource", &pstrmval) <= 0) |
||||||
|
-- |
||||||
|
2.17.2 |
||||||
|
|
||||||
|
|
||||||
|
From 9a1b3ac61761094713f44dedfce56013308a3b1d Mon Sep 17 00:00:00 2001 |
||||||
|
From: Ken Sharp <ken.sharp@artifex.com> |
||||||
|
Date: Wed, 14 Nov 2018 09:31:10 +0000 |
||||||
|
Subject: [PATCH 3/3] PS interpreter - add some type checking |
||||||
|
|
||||||
|
These were 'probably' safe anyway, since they mostly treat the objects |
||||||
|
as integers without checking, which at least can't result in a crash. |
||||||
|
|
||||||
|
Nevertheless, we ought to check. |
||||||
|
|
||||||
|
The return from comparedictkeys could be wrong if one of the keys had |
||||||
|
a value which was not an array, it could incorrectly decide the two |
||||||
|
were in fact the same. |
||||||
|
--- |
||||||
|
psi/zbfont.c | 15 +++++++++------ |
||||||
|
psi/zcolor.c | 24 +++++++++++++++++++++++- |
||||||
|
psi/zcrd.c | 4 +++- |
||||||
|
psi/zfjpx.c | 2 ++ |
||||||
|
psi/zfont.c | 3 +++ |
||||||
|
psi/zfont0.c | 3 +++ |
||||||
|
psi/zimage3.c | 2 ++ |
||||||
|
psi/ztrans.c | 4 ++++ |
||||||
|
8 files changed, 49 insertions(+), 8 deletions(-) |
||||||
|
|
||||||
|
diff --git a/psi/zbfont.c b/psi/zbfont.c |
||||||
|
index c1d0461..5b830a2 100644 |
||||||
|
--- a/psi/zbfont.c |
||||||
|
+++ b/psi/zbfont.c |
||||||
|
@@ -666,6 +666,9 @@ sub_font_params(gs_memory_t *mem, const ref *op, gs_matrix *pmat, gs_matrix *pom |
||||||
|
return_error(gs_error_invalidfont); |
||||||
|
if (dict_find_string(op, "OrigFont", &porigfont) <= 0) |
||||||
|
porigfont = NULL; |
||||||
|
+ if (porigfont != NULL && !r_has_type(porigfont, t_dictionary)) |
||||||
|
+ return_error(gs_error_typecheck); |
||||||
|
+ |
||||||
|
if (pomat!= NULL) { |
||||||
|
if (porigfont == NULL || |
||||||
|
dict_find_string(porigfont, "FontMatrix", &pmatrix) <= 0 || |
||||||
|
@@ -676,8 +679,8 @@ sub_font_params(gs_memory_t *mem, const ref *op, gs_matrix *pmat, gs_matrix *pom |
||||||
|
/* Use the FontInfo/OrigFontName key preferrentially (created by MS PSCRIPT driver) */ |
||||||
|
if ((dict_find_string((porigfont != NULL ? porigfont : op), "FontInfo", &pfontinfo) > 0) && |
||||||
|
r_has_type(pfontinfo, t_dictionary) && |
||||||
|
- (dict_find_string(pfontinfo, "OrigFontName", &pfontname) > 0)) { |
||||||
|
- if ((dict_find_string(pfontinfo, "OrigFontStyle", &pfontstyle) > 0) && |
||||||
|
+ (dict_find_string(pfontinfo, "OrigFontName", &pfontname) > 0) && (r_has_type(pfontname, t_name) || r_has_type(pfontname, t_string))) { |
||||||
|
+ if ((dict_find_string(pfontinfo, "OrigFontStyle", &pfontstyle) > 0) && (r_has_type(pfontname, t_name) || r_has_type(pfontname, t_string)) && |
||||||
|
r_size(pfontstyle) > 0) { |
||||||
|
const byte *tmpStr1 = pfontname->value.const_bytes; |
||||||
|
const byte *tmpStr2 = pfontstyle->value.const_bytes; |
||||||
|
@@ -775,11 +778,11 @@ build_gs_font(i_ctx_t *i_ctx_p, os_ptr op, gs_font ** ppfont, font_type ftype, |
||||||
|
avm_space useglob = r_is_local(pencoding) ? avm_local : avm_global; |
||||||
|
|
||||||
|
ialloc_set_space(idmemory, useglob); |
||||||
|
- |
||||||
|
+ |
||||||
|
count = r_size(pencoding); |
||||||
|
if ((code = ialloc_ref_array(&penc, (r_type_attrs(pencoding) & a_readonly), count, "build_gs_font")) < 0) |
||||||
|
return code; |
||||||
|
- |
||||||
|
+ |
||||||
|
while (count--) { |
||||||
|
ref r; |
||||||
|
if (array_get(imemory, pencoding, count, &r) < 0){ |
||||||
|
@@ -790,7 +793,7 @@ build_gs_font(i_ctx_t *i_ctx_p, os_ptr op, gs_font ** ppfont, font_type ftype, |
||||||
|
ref_assign(&(penc.value.refs[count]), &r); |
||||||
|
} |
||||||
|
else { |
||||||
|
- |
||||||
|
+ |
||||||
|
if ((code = obj_cvs(imemory, &r, (byte *)buf, 32, &size, (const byte **)(&bptr))) < 0) { |
||||||
|
return(code); |
||||||
|
} |
||||||
|
@@ -799,7 +802,7 @@ build_gs_font(i_ctx_t *i_ctx_p, os_ptr op, gs_font ** ppfont, font_type ftype, |
||||||
|
ref_assign(&(penc.value.refs[count]), &r); |
||||||
|
} |
||||||
|
} |
||||||
|
- |
||||||
|
+ |
||||||
|
if ((code = dict_put_string(osp, "Encoding", &penc, NULL)) < 0) |
||||||
|
return code; |
||||||
|
ialloc_set_space(idmemory, curglob); |
||||||
|
diff --git a/psi/zcolor.c b/psi/zcolor.c |
||||||
|
index fe81e79..b69b8f5 100644 |
||||||
|
--- a/psi/zcolor.c |
||||||
|
+++ b/psi/zcolor.c |
||||||
|
@@ -1877,7 +1877,12 @@ static int comparedictkey(i_ctx_t * i_ctx_p, ref *CIEdict1, ref *CIEdict2, char |
||||||
|
if (r_type(tempref1) == t_null) |
||||||
|
return 1; |
||||||
|
|
||||||
|
- return comparearrays(i_ctx_p, tempref1, tempref2); |
||||||
|
+ code = comparearrays(i_ctx_p, tempref1, tempref2); |
||||||
|
+ |
||||||
|
+ if (code > 0) |
||||||
|
+ return 1; |
||||||
|
+ else |
||||||
|
+ return 0; |
||||||
|
} |
||||||
|
|
||||||
|
static int hasharray(i_ctx_t * i_ctx_p, ref *m1, gs_md5_state_t *md5) |
||||||
|
@@ -5473,6 +5478,9 @@ static int seticcspace(i_ctx_t * i_ctx_p, ref *r, int *stage, int *cont, int CIE |
||||||
|
return code; |
||||||
|
if (code == 0) |
||||||
|
return gs_note_error(gs_error_undefined); |
||||||
|
+ if (r_type(tempref) != t_integer) |
||||||
|
+ return gs_note_error(gs_error_typecheck); |
||||||
|
+ |
||||||
|
components = tempref->value.intval; |
||||||
|
if (components > count_of(range)/2) |
||||||
|
return_error(gs_error_rangecheck); |
||||||
|
@@ -5584,6 +5592,10 @@ static int iccompareproc(i_ctx_t *i_ctx_p, ref *space, ref *testspace) |
||||||
|
/* Need to check all the various parts */ |
||||||
|
code1 = dict_find_string(&ICCdict1, "N", &tempref1); |
||||||
|
code2 = dict_find_string(&ICCdict2, "N", &tempref2); |
||||||
|
+ |
||||||
|
+ if (!r_has_type(tempref1, t_integer) || !r_has_type(tempref2, t_integer)) |
||||||
|
+ return 0; |
||||||
|
+ |
||||||
|
if (code1 != code2) |
||||||
|
return 0; |
||||||
|
if (tempref1->value.intval != tempref2->value.intval) |
||||||
|
@@ -5737,6 +5749,8 @@ static int iccalternatespace(i_ctx_t * i_ctx_p, ref *space, ref **r, int *CIESub |
||||||
|
return code; |
||||||
|
if (code == 0) |
||||||
|
return gs_note_error(gs_error_undefined); |
||||||
|
+ if (!r_has_type(tempref, t_integer)) |
||||||
|
+ return_error(gs_error_typecheck); |
||||||
|
|
||||||
|
components = tempref->value.intval; |
||||||
|
|
||||||
|
@@ -5775,6 +5789,9 @@ static int icccomponents(i_ctx_t * i_ctx_p, ref *space, int *n) |
||||||
|
return code; |
||||||
|
if (code == 0) |
||||||
|
return gs_note_error(gs_error_undefined); |
||||||
|
+ if (!r_has_type(tempref, t_integer)) |
||||||
|
+ return gs_note_error(gs_error_typecheck); |
||||||
|
+ |
||||||
|
*n = tempref->value.intval; |
||||||
|
return 0; |
||||||
|
} |
||||||
|
@@ -5791,6 +5808,9 @@ static int iccdomain(i_ctx_t * i_ctx_p, ref *space, float *ptr) |
||||||
|
return code; |
||||||
|
if (code == 0) |
||||||
|
return gs_note_error(gs_error_undefined); |
||||||
|
+ if (!r_has_type(tempref, t_integer)) |
||||||
|
+ return gs_note_error(gs_error_typecheck); |
||||||
|
+ |
||||||
|
components = tempref->value.intval; |
||||||
|
code = dict_find_string(&ICCdict, "Range", &tempref); |
||||||
|
if (code > 0 && !r_has_type(tempref, t_null)) { |
||||||
|
@@ -5824,6 +5844,8 @@ static int iccrange(i_ctx_t * i_ctx_p, ref *space, float *ptr) |
||||||
|
return code; |
||||||
|
if (code == 0) |
||||||
|
return gs_note_error(gs_error_undefined); |
||||||
|
+ if (!r_has_type(tempref, t_integer)) |
||||||
|
+ return gs_note_error(gs_error_typecheck); |
||||||
|
components = tempref->value.intval; |
||||||
|
code = dict_find_string(&ICCdict, "Range", &tempref); |
||||||
|
if (code > 0 && !r_has_type(tempref, t_null)) { |
||||||
|
diff --git a/psi/zcrd.c b/psi/zcrd.c |
||||||
|
index 7993b15..d58160d 100644 |
||||||
|
--- a/psi/zcrd.c |
||||||
|
+++ b/psi/zcrd.c |
||||||
|
@@ -231,8 +231,10 @@ zcrd1_params(os_ptr op, gs_cie_render * pcrd, |
||||||
|
return code; |
||||||
|
|
||||||
|
if (dict_find_string(op, "RenderTable", &pRT) > 0) { |
||||||
|
- const ref *prte = pRT->value.const_refs; |
||||||
|
+ const ref *prte; |
||||||
|
|
||||||
|
+ check_read_type(*pRT, t_array); |
||||||
|
+ prte = pRT->value.const_refs; |
||||||
|
/* Finish unpacking and checking the RenderTable parameter. */ |
||||||
|
check_type_only(prte[4], t_integer); |
||||||
|
if (!(prte[4].value.intval == 3 || prte[4].value.intval == 4)) |
||||||
|
diff --git a/psi/zfjpx.c b/psi/zfjpx.c |
||||||
|
index c622f48..db1fae2 100644 |
||||||
|
--- a/psi/zfjpx.c |
||||||
|
+++ b/psi/zfjpx.c |
||||||
|
@@ -115,6 +115,8 @@ z_jpx_decode(i_ctx_t * i_ctx_p) |
||||||
|
dict_find_string(csdict, "N", &nref) > 0) { |
||||||
|
if_debug1m('w', imemory, "[w] JPX image has an external %"PRIpsint |
||||||
|
" channel colorspace\n", nref->value.intval); |
||||||
|
+ if (r_type(nref) != t_integer) |
||||||
|
+ return gs_note_error(gs_error_typecheck); |
||||||
|
switch (nref->value.intval) { |
||||||
|
case 1: state.colorspace = gs_jpx_cs_gray; |
||||||
|
break; |
||||||
|
diff --git a/psi/zfont.c b/psi/zfont.c |
||||||
|
index 9c51792..f6c5ae1 100644 |
||||||
|
--- a/psi/zfont.c |
||||||
|
+++ b/psi/zfont.c |
||||||
|
@@ -596,6 +596,9 @@ zfont_info(gs_font *font, const gs_point *pscale, int members, |
||||||
|
info->members |= FONT_INFO_FULL_NAME; |
||||||
|
if ((members & FONT_INFO_EMBEDDING_RIGHTS) |
||||||
|
&& (dict_find_string(pfontinfo, "FSType", &pvalue) > 0)) { |
||||||
|
+ if (r_type(pvalue) != t_integer) |
||||||
|
+ return gs_note_error(gs_error_typecheck); |
||||||
|
+ |
||||||
|
info->EmbeddingRights = pvalue->value.intval; |
||||||
|
info->members |= FONT_INFO_EMBEDDING_RIGHTS; |
||||||
|
} |
||||||
|
diff --git a/psi/zfont0.c b/psi/zfont0.c |
||||||
|
index 4b01c20..a179d7b 100644 |
||||||
|
--- a/psi/zfont0.c |
||||||
|
+++ b/psi/zfont0.c |
||||||
|
@@ -243,6 +243,9 @@ zbuildfont0(i_ctx_t *i_ctx_p) |
||||||
|
array_get(pfont->memory, &fdepvector, i, &fdep); |
||||||
|
/* The lookup can't fail, because of the pre-check above. */ |
||||||
|
dict_find_string(&fdep, "FID", &pfid); |
||||||
|
+ if (!r_has_type(pfid, t_fontID)) |
||||||
|
+ return gs_note_error(gs_error_typecheck); |
||||||
|
+ |
||||||
|
data.FDepVector[i] = r_ptr(pfid, gs_font); |
||||||
|
} |
||||||
|
pfont->data = data; |
||||||
|
diff --git a/psi/zimage3.c b/psi/zimage3.c |
||||||
|
index 87a3dce..2beda9f 100644 |
||||||
|
--- a/psi/zimage3.c |
||||||
|
+++ b/psi/zimage3.c |
||||||
|
@@ -53,6 +53,8 @@ zimage3(i_ctx_t *i_ctx_p) |
||||||
|
dict_find_string(op, "MaskDict", &pMaskDict) <= 0 |
||||||
|
) |
||||||
|
return_error(gs_error_rangecheck); |
||||||
|
+ check_type(*pDataDict, t_dictionary); |
||||||
|
+ check_type(*pMaskDict, t_dictionary); |
||||||
|
if ((code = pixel_image_params(i_ctx_p, pDataDict, |
||||||
|
(gs_pixel_image_t *)&image, &ip_data, |
||||||
|
12, false, gs_currentcolorspace(igs))) < 0 || |
||||||
|
diff --git a/psi/ztrans.c b/psi/ztrans.c |
||||||
|
index 64defda..0550a10 100644 |
||||||
|
--- a/psi/ztrans.c |
||||||
|
+++ b/psi/ztrans.c |
||||||
|
@@ -417,6 +417,7 @@ zimage3x(i_ctx_t *i_ctx_p) |
||||||
|
gs_image3x_t_init(&image, NULL); |
||||||
|
if (dict_find_string(op, "DataDict", &pDataDict) <= 0) |
||||||
|
return_error(gs_error_rangecheck); |
||||||
|
+ check_type(*pDataDict, t_dictionary); |
||||||
|
if ((code = pixel_image_params(i_ctx_p, pDataDict, |
||||||
|
(gs_pixel_image_t *)&image, &ip_data, |
||||||
|
16, false, gs_currentcolorspace(igs))) < 0 || |
||||||
|
@@ -453,6 +454,9 @@ image_params *pip_data, const char *dict_name, |
||||||
|
|
||||||
|
if (dict_find_string(op, dict_name, &pMaskDict) <= 0) |
||||||
|
return 1; |
||||||
|
+ if (!r_has_type(pMaskDict, t_dictionary)) |
||||||
|
+ return gs_note_error(gs_error_typecheck); |
||||||
|
+ |
||||||
|
if ((mcode = code = data_image_params(mem, pMaskDict, &pixm->MaskDict, |
||||||
|
&ip_mask, false, 1, 16, false, false)) < 0 || |
||||||
|
(code = dict_int_param(pMaskDict, "ImageType", 1, 1, 0, &ignored)) < 0 || |
||||||
|
-- |
||||||
|
2.17.2 |
||||||
|
|
@ -0,0 +1,32 @@ |
|||||||
|
From 606a22e77e7f081781e99e44644cd0119f559e03 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Ken Sharp <ken.sharp@artifex.com> |
||||||
|
Date: Wed, 14 Nov 2018 09:27:00 +0000 |
||||||
|
Subject: [PATCH] Bug #700168 - add a type check |
||||||
|
|
||||||
|
Bug #700168 "Type confusion in JBIG2Decode" |
||||||
|
|
||||||
|
The code was assuming that .jbig2globalctx was a structure allocated |
||||||
|
by the graphics library, without checking. |
||||||
|
|
||||||
|
Add a check to see that it is a structure and that its the correct |
||||||
|
type of structure. |
||||||
|
--- |
||||||
|
psi/zfjbig2.c | 2 ++ |
||||||
|
1 file changed, 2 insertions(+) |
||||||
|
|
||||||
|
diff --git a/psi/zfjbig2.c b/psi/zfjbig2.c |
||||||
|
index a3d13a2..07b470f 100644 |
||||||
|
--- a/psi/zfjbig2.c |
||||||
|
+++ b/psi/zfjbig2.c |
||||||
|
@@ -72,6 +72,8 @@ z_jbig2decode(i_ctx_t * i_ctx_p) |
||||||
|
if (r_has_type(op, t_dictionary)) { |
||||||
|
check_dict_read(*op); |
||||||
|
if ( dict_find_string(op, ".jbig2globalctx", &sop) > 0) { |
||||||
|
+ if (!r_is_struct(sop) || !r_has_stype(sop, imemory, st_jbig2_global_data_t)) |
||||||
|
+ return_error(gs_error_typecheck); |
||||||
|
gref = r_ptr(sop, s_jbig2_global_data_t); |
||||||
|
s_jbig2decode_set_global_data((stream_state*)&state, gref); |
||||||
|
} |
||||||
|
-- |
||||||
|
2.17.2 |
||||||
|
|
@ -0,0 +1,43 @@ |
|||||||
|
From 5b85ddd19a8420a1bd2d5529325be35d78e94234 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Chris Liddell <chris.liddell@artifex.com> |
||||||
|
Date: Fri, 2 Aug 2019 15:18:26 +0100 |
||||||
|
Subject: Bug 701394: protect use of .forceput with executeonly |
||||||
|
|
||||||
|
|
||||||
|
diff --git a/Resource/Init/gs_type1.ps b/Resource/Init/gs_type1.ps |
||||||
|
index 6c7735bc0c..a039ccee35 100644 |
||||||
|
--- a/Resource/Init/gs_type1.ps |
||||||
|
+++ b/Resource/Init/gs_type1.ps |
||||||
|
@@ -118,25 +118,25 @@ |
||||||
|
( to be the same as glyph: ) print 1 index //== exec } if |
||||||
|
3 index exch 3 index .forceput |
||||||
|
% scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname |
||||||
|
- } |
||||||
|
+ }executeonly |
||||||
|
{pop} ifelse |
||||||
|
- } forall |
||||||
|
+ } executeonly forall |
||||||
|
pop pop |
||||||
|
- } |
||||||
|
+ } executeonly |
||||||
|
{ |
||||||
|
pop pop pop |
||||||
|
} ifelse |
||||||
|
- } |
||||||
|
+ } executeonly |
||||||
|
{ |
||||||
|
% scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname |
||||||
|
pop pop |
||||||
|
} ifelse |
||||||
|
- } forall |
||||||
|
+ } executeonly forall |
||||||
|
3 1 roll pop pop |
||||||
|
- } if |
||||||
|
+ } executeonly if |
||||||
|
pop |
||||||
|
dup /.AGLprocessed~GS //true .forceput |
||||||
|
- } if |
||||||
|
+ } executeonly if |
||||||
|
|
||||||
|
%% We need to excute the C .buildfont1 in a stopped context so that, if there |
||||||
|
%% are errors we can put the stack back sanely and exit. Otherwise callers won't |
@ -0,0 +1,56 @@ |
|||||||
|
From 885444fcbe10dc42787ecb76686c8ee4dd33bf33 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Ken Sharp <ken.sharp@artifex.com> |
||||||
|
Date: Tue, 20 Aug 2019 10:10:28 +0100 |
||||||
|
Subject: make .forceput inaccessible |
||||||
|
|
||||||
|
Bug #701343, #701344, #701345 |
||||||
|
|
||||||
|
More defensive programming. We don't want people to access .forecput |
||||||
|
even though it is no longer sufficient to bypass SAFER. The exploit |
||||||
|
in #701343 didn't work anyway because of earlier work to stop the error |
||||||
|
handler being used, but nevertheless, prevent access to .forceput from |
||||||
|
.setuserparams2. |
||||||
|
|
||||||
|
diff --git a/Resource/Init/gs_lev2.ps b/Resource/Init/gs_lev2.ps |
||||||
|
index 4cc7f820f..0fd416465 100644 |
||||||
|
--- a/Resource/Init/gs_lev2.ps |
||||||
|
+++ b/Resource/Init/gs_lev2.ps |
||||||
|
@@ -158,7 +158,7 @@ end |
||||||
|
{ |
||||||
|
pop pop |
||||||
|
} ifelse |
||||||
|
- } forall |
||||||
|
+ } executeonly forall |
||||||
|
% A context switch might have occurred during the above loop, |
||||||
|
% causing the interpreter-level parameters to be reset. |
||||||
|
% Set them again to the new values. From here on, we are safe, |
||||||
|
@@ -229,9 +229,9 @@ end |
||||||
|
{ pop pop |
||||||
|
} |
||||||
|
ifelse |
||||||
|
- } |
||||||
|
+ } executeonly |
||||||
|
forall pop |
||||||
|
-} .bind odef |
||||||
|
+} .bind executeonly odef |
||||||
|
|
||||||
|
% Initialize the passwords. |
||||||
|
% NOTE: the names StartJobPassword and SystemParamsPassword are known to |
||||||
|
diff --git a/Resource/Init/gs_pdfwr.ps b/Resource/Init/gs_pdfwr.ps |
||||||
|
index c158a8faf..422e66e1a 100644 |
||||||
|
--- a/Resource/Init/gs_pdfwr.ps |
||||||
|
+++ b/Resource/Init/gs_pdfwr.ps |
||||||
|
@@ -658,11 +658,11 @@ currentdict /.pdfmarkparams .undef |
||||||
|
systemdict /.pdf_hooked_DSC_Creator //true .forceput |
||||||
|
} executeonly if |
||||||
|
pop |
||||||
|
- } if |
||||||
|
+ } executeonly if |
||||||
|
} { |
||||||
|
pop |
||||||
|
} ifelse |
||||||
|
- } |
||||||
|
+ } executeonly |
||||||
|
{ |
||||||
|
pop |
||||||
|
} ifelse |
@ -0,0 +1,258 @@ |
|||||||
|
From be86d2ff2f0f0ea0e365707f3be0fa0c9e7315ee Mon Sep 17 00:00:00 2001 |
||||||
|
From: Ray Johnston <ray.johnston@artifex.com> |
||||||
|
Date: Mon, 18 Feb 2019 12:11:45 -0800 |
||||||
|
Subject: [PATCH 1/2] Bug 700599: Issue an error message if an ExtGstate is not |
||||||
|
found. |
||||||
|
|
||||||
|
Previously, this was silently ignored. Only issue a single warning, |
||||||
|
and respect PDFSTOPONERROR to prevent continuing with potentially |
||||||
|
incorrect output. |
||||||
|
|
||||||
|
Note that tests_private/pdf/uploads/bug696410.pdf also now gets this |
||||||
|
error message (ExtGState" instead of ExtGState in object 10). |
||||||
|
--- |
||||||
|
Resource/Init/pdf_draw.ps | 11 ++++++++++- |
||||||
|
1 file changed, 10 insertions(+), 1 deletion(-) |
||||||
|
|
||||||
|
diff --git a/Resource/Init/pdf_draw.ps b/Resource/Init/pdf_draw.ps |
||||||
|
index 1add3f7..6a2773a 100644 |
||||||
|
--- a/Resource/Init/pdf_draw.ps |
||||||
|
+++ b/Resource/Init/pdf_draw.ps |
||||||
|
@@ -494,7 +494,16 @@ end |
||||||
|
dup { |
||||||
|
oforce exch gsparamdict exch .knownget { exec } { pop } ifelse |
||||||
|
} forall pop |
||||||
|
- } if |
||||||
|
+ } { |
||||||
|
+ //pdfdict /.gs_warning_issued known not { |
||||||
|
+ (\n **** Error 'gs' ignored -- ExtGState missing from Resources.\n) |
||||||
|
+ pdfformaterror |
||||||
|
+ ( Output may be incorrect.\n) pdfformaterror |
||||||
|
+ //pdfdict /.gs_warning_issued //true .forceput |
||||||
|
+ PDFSTOPONERROR { /gs /undefined signalerror } if |
||||||
|
+ } if |
||||||
|
+ } |
||||||
|
+ ifelse |
||||||
|
} bind executeonly def |
||||||
|
|
||||||
|
% ------ Transparency support ------ % |
||||||
|
-- |
||||||
|
2.20.1 |
||||||
|
|
||||||
|
|
||||||
|
From cd1b1cacadac2479e291efe611979bdc1b3bdb19 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Ken Sharp <ken.sharp@artifex.com> |
||||||
|
Date: Wed, 21 Aug 2019 10:10:51 +0100 |
||||||
|
Subject: [PATCH 2/2] PDF interpreter - review .forceput security |
||||||
|
|
||||||
|
Bug #701450 "Safer Mode Bypass by .forceput Exposure in .pdfexectoken" |
||||||
|
|
||||||
|
By abusing the error handler it was possible to get the PDFDEBUG portion |
||||||
|
of .pdfexectoken, which uses .forceput left readable. |
||||||
|
|
||||||
|
Add an executeonly appropriately to make sure that clause isn't readable |
||||||
|
no mstter what. |
||||||
|
|
||||||
|
Review all the uses of .forceput searching for similar cases, add |
||||||
|
executeonly as required to secure those. All cases in the PostScript |
||||||
|
support files seem to be covered already. |
||||||
|
--- |
||||||
|
Resource/Init/pdf_base.ps | 2 +- |
||||||
|
Resource/Init/pdf_draw.ps | 14 +++++++------- |
||||||
|
Resource/Init/pdf_font.ps | 23 ++++++++++++----------- |
||||||
|
Resource/Init/pdf_main.ps | 6 +++--- |
||||||
|
Resource/Init/pdf_ops.ps | 11 ++++++----- |
||||||
|
5 files changed, 29 insertions(+), 27 deletions(-) |
||||||
|
|
||||||
|
diff --git a/Resource/Init/pdf_base.ps b/Resource/Init/pdf_base.ps |
||||||
|
index d3c3a5f..5dabe4d 100644 |
||||||
|
--- a/Resource/Init/pdf_base.ps |
||||||
|
+++ b/Resource/Init/pdf_base.ps |
||||||
|
@@ -154,7 +154,7 @@ currentdict /num-chars-dict .undef |
||||||
|
{ |
||||||
|
dup ==only () = flush |
||||||
|
} ifelse % PDFSTEP |
||||||
|
- } if % PDFDEBUG |
||||||
|
+ } executeonly if % PDFDEBUG |
||||||
|
2 copy .knownget { |
||||||
|
exch pop exch pop exch pop exec |
||||||
|
} { |
||||||
|
diff --git a/Resource/Init/pdf_draw.ps b/Resource/Init/pdf_draw.ps |
||||||
|
index 6a2773a..068ba7c 100644 |
||||||
|
--- a/Resource/Init/pdf_draw.ps |
||||||
|
+++ b/Resource/Init/pdf_draw.ps |
||||||
|
@@ -501,8 +501,8 @@ end |
||||||
|
( Output may be incorrect.\n) pdfformaterror |
||||||
|
//pdfdict /.gs_warning_issued //true .forceput |
||||||
|
PDFSTOPONERROR { /gs /undefined signalerror } if |
||||||
|
- } if |
||||||
|
- } |
||||||
|
+ } executeonly if |
||||||
|
+ } executeonly |
||||||
|
ifelse |
||||||
|
} bind executeonly def |
||||||
|
|
||||||
|
@@ -1127,7 +1127,7 @@ currentdict end readonly def |
||||||
|
.setglobal |
||||||
|
pdfformaterror |
||||||
|
} executeonly ifelse |
||||||
|
- } |
||||||
|
+ } executeonly |
||||||
|
{ |
||||||
|
currentglobal //pdfdict gcheck .setglobal |
||||||
|
//pdfdict /.Qqwarning_issued //true .forceput |
||||||
|
@@ -1135,8 +1135,8 @@ currentdict end readonly def |
||||||
|
pdfformaterror |
||||||
|
} executeonly ifelse |
||||||
|
end |
||||||
|
- } ifelse |
||||||
|
- } loop |
||||||
|
+ } executeonly ifelse |
||||||
|
+ } executeonly loop |
||||||
|
{ |
||||||
|
(\n **** Error: File has unbalanced q/Q operators \(too many q's\)\n Output may be incorrect.\n) |
||||||
|
//pdfdict /.Qqwarning_issued .knownget |
||||||
|
@@ -1150,14 +1150,14 @@ currentdict end readonly def |
||||||
|
.setglobal |
||||||
|
pdfformaterror |
||||||
|
} executeonly ifelse |
||||||
|
- } |
||||||
|
+ } executeonly |
||||||
|
{ |
||||||
|
currentglobal //pdfdict gcheck .setglobal |
||||||
|
//pdfdict /.Qqwarning_issued //true .forceput |
||||||
|
.setglobal |
||||||
|
pdfformaterror |
||||||
|
} executeonly ifelse |
||||||
|
- } if |
||||||
|
+ } executeonly if |
||||||
|
pop |
||||||
|
|
||||||
|
% restore pdfemptycount |
||||||
|
diff --git a/Resource/Init/pdf_font.ps b/Resource/Init/pdf_font.ps |
||||||
|
index 8b8fef8..86b1870 100644 |
||||||
|
--- a/Resource/Init/pdf_font.ps |
||||||
|
+++ b/Resource/Init/pdf_font.ps |
||||||
|
@@ -677,7 +677,7 @@ currentdict end readonly def |
||||||
|
currentglobal 2 index dup gcheck setglobal |
||||||
|
/FontInfo 5 dict dup 5 1 roll .forceput |
||||||
|
setglobal |
||||||
|
- } if |
||||||
|
+ } executeonly if |
||||||
|
dup /GlyphNames2Unicode .knownget not { |
||||||
|
//true % No existing G2U, make one |
||||||
|
} { |
||||||
|
@@ -701,9 +701,9 @@ currentdict end readonly def |
||||||
|
} if |
||||||
|
PDFDEBUG { |
||||||
|
(.processToUnicode end) = |
||||||
|
- } if |
||||||
|
- } if |
||||||
|
- } stopped |
||||||
|
+ } executeonly if |
||||||
|
+ } executeonly if |
||||||
|
+ } executeonly stopped |
||||||
|
{ |
||||||
|
.dstackdepth 1 countdictstack 1 sub |
||||||
|
{pop end} for |
||||||
|
@@ -1225,19 +1225,20 @@ currentdict /eexec_pdf_param_dict .undef |
||||||
|
//pdfdict /.Qqwarning_issued //true .forceput |
||||||
|
} executeonly if |
||||||
|
Q |
||||||
|
- } repeat |
||||||
|
+ } executeonly repeat |
||||||
|
Q |
||||||
|
- } PDFfile fileposition 2 .execn % Keep pdfcount valid. |
||||||
|
+ } executeonly PDFfile fileposition 2 .execn % Keep pdfcount valid. |
||||||
|
PDFfile exch setfileposition |
||||||
|
- } ifelse |
||||||
|
- } { |
||||||
|
+ } executeonly ifelse |
||||||
|
+ } executeonly |
||||||
|
+ { |
||||||
|
% PDF Type 3 fonts don't use .notdef |
||||||
|
% d1 implementation adjusts the width as needed |
||||||
|
0 0 0 0 0 0 |
||||||
|
pdfopdict /d1 get exec |
||||||
|
} ifelse |
||||||
|
end end |
||||||
|
- } bdef |
||||||
|
+ } executeonly bdef |
||||||
|
dup currentdict Encoding .processToUnicode |
||||||
|
currentdict end .completefont exch pop |
||||||
|
} bind executeonly odef |
||||||
|
@@ -2022,9 +2023,9 @@ currentdict /CMap_read_dict undef |
||||||
|
(Will continue, but content may be missing.) = flush |
||||||
|
} ifelse |
||||||
|
} if |
||||||
|
- } if |
||||||
|
+ } executeonly if |
||||||
|
/findresource cvx /undefined signalerror |
||||||
|
- } loop |
||||||
|
+ } executeonly loop |
||||||
|
} bind executeonly odef |
||||||
|
|
||||||
|
/buildCIDType0 { % <CIDFontType0-font-resource> buildCIDType0 <font> |
||||||
|
diff --git a/Resource/Init/pdf_main.ps b/Resource/Init/pdf_main.ps |
||||||
|
index e44288e..ecde3d4 100644 |
||||||
|
--- a/Resource/Init/pdf_main.ps |
||||||
|
+++ b/Resource/Init/pdf_main.ps |
||||||
|
@@ -2696,15 +2696,15 @@ currentdict /PDF2PS_matrix_key undef |
||||||
|
.setglobal |
||||||
|
pdfformaterror |
||||||
|
} executeonly ifelse |
||||||
|
- } |
||||||
|
+ } executeonly |
||||||
|
{ |
||||||
|
currentglobal //pdfdict gcheck .setglobal |
||||||
|
//pdfdict /.Qqwarning_issued //true .forceput |
||||||
|
.setglobal |
||||||
|
pdfformaterror |
||||||
|
} executeonly ifelse |
||||||
|
- } if |
||||||
|
- } if |
||||||
|
+ } executeonly if |
||||||
|
+ } executeonly if |
||||||
|
pop |
||||||
|
count PDFexecstackcount sub { pop } repeat |
||||||
|
(after exec) VMDEBUG |
||||||
|
diff --git a/Resource/Init/pdf_ops.ps b/Resource/Init/pdf_ops.ps |
||||||
|
index c2e7461..12d5a66 100644 |
||||||
|
--- a/Resource/Init/pdf_ops.ps |
||||||
|
+++ b/Resource/Init/pdf_ops.ps |
||||||
|
@@ -186,14 +186,14 @@ currentdict /gput_always_allow .undef |
||||||
|
.setglobal |
||||||
|
pdfformaterror |
||||||
|
} executeonly ifelse |
||||||
|
- } |
||||||
|
+ } executeonly |
||||||
|
{ |
||||||
|
currentglobal //pdfdict gcheck .setglobal |
||||||
|
//pdfdict /.Qqwarning_issued //true .forceput |
||||||
|
.setglobal |
||||||
|
pdfformaterror |
||||||
|
} executeonly ifelse |
||||||
|
- } if |
||||||
|
+ } executeonly if |
||||||
|
} bind executeonly odef |
||||||
|
|
||||||
|
% Save PDF gstate |
||||||
|
@@ -440,11 +440,12 @@ currentdict /gput_always_allow .undef |
||||||
|
dup type /booleantype eq { |
||||||
|
.currentSMask type /dicttype eq { |
||||||
|
.currentSMask /Processed 2 index .forceput |
||||||
|
+ } executeonly |
||||||
|
+ { |
||||||
|
+ .setSMask |
||||||
|
+ }ifelse |
||||||
|
} executeonly |
||||||
|
{ |
||||||
|
- .setSMask |
||||||
|
- }ifelse |
||||||
|
- }{ |
||||||
|
.setSMask |
||||||
|
}ifelse |
||||||
|
|
||||||
|
-- |
||||||
|
2.20.1 |
||||||
|
|
@ -0,0 +1,40 @@ |
|||||||
|
diff --git a/Resource/Init/gs_ttf.ps b/Resource/Init/gs_ttf.ps |
||||||
|
index 064b6c8..600907e 100644 |
||||||
|
--- a/Resource/Init/gs_ttf.ps |
||||||
|
+++ b/Resource/Init/gs_ttf.ps |
||||||
|
@@ -1421,7 +1421,7 @@ mark |
||||||
|
TTFDEBUG { (\n1 setting alias: ) print dup ==only |
||||||
|
( to be the same as ) print 2 index //== exec } if |
||||||
|
|
||||||
|
- 7 index 2 index 3 -1 roll exch .forceput |
||||||
|
+ 7 index 2 index 3 -1 roll exch put |
||||||
|
} forall |
||||||
|
pop pop pop |
||||||
|
} |
||||||
|
@@ -1439,7 +1439,7 @@ mark |
||||||
|
exch pop |
||||||
|
TTFDEBUG { (\n2 setting alias: ) print 1 index ==only |
||||||
|
( to use glyph index: ) print dup //== exec } if |
||||||
|
- 5 index 3 1 roll .forceput |
||||||
|
+ 5 index 3 1 roll put |
||||||
|
//false |
||||||
|
} |
||||||
|
{ |
||||||
|
@@ -1456,7 +1456,7 @@ mark |
||||||
|
{ % CharStrings(dict) isunicode(boolean) cmap(dict) RAGL(dict) gname(name) codep(integer) gindex(integer) |
||||||
|
TTFDEBUG { (\3 nsetting alias: ) print 1 index ==only |
||||||
|
( to be index: ) print dup //== exec } if |
||||||
|
- exch pop 5 index 3 1 roll .forceput |
||||||
|
+ exch pop 5 index 3 1 roll put |
||||||
|
} |
||||||
|
{ |
||||||
|
pop pop |
||||||
|
@@ -1486,7 +1486,7 @@ mark |
||||||
|
} ifelse |
||||||
|
] |
||||||
|
TTFDEBUG { (Encoding: ) print dup === flush } if |
||||||
|
-} .bind executeonly odef % hides .forceput |
||||||
|
+} .bind odef |
||||||
|
|
||||||
|
% to be removed 9.09...... |
||||||
|
currentdict /postalias undef |
@ -0,0 +1,615 @@ |
|||||||
|
From 779664d79f0dca77dbdd66b753679bfd12dcbbad Mon Sep 17 00:00:00 2001 |
||||||
|
From: Chris Liddell <chris.liddell@artifex.com> |
||||||
|
Date: Mon, 26 Nov 2018 18:01:25 +0000 |
||||||
|
Subject: [PATCH 1/4] Have gs_cet.ps run from gs_init.ps |
||||||
|
|
||||||
|
Previously gs_cet.ps was run on the command line, to set up the interpreter |
||||||
|
state so our output more closely matches the example output for the QL CET |
||||||
|
tests. |
||||||
|
|
||||||
|
Allow a -dCETMODE command line switch, which will cause gs_init.ps to run the |
||||||
|
file directly. |
||||||
|
|
||||||
|
This works better for gpdl as it means the changes are made in the intial |
||||||
|
interpreter state, rather than after initialisation is complete. |
||||||
|
|
||||||
|
This also means adding a definition of the default procedure for black |
||||||
|
generation and under color removal (rather it being defined in-line in |
||||||
|
.setdefaultbgucr |
||||||
|
|
||||||
|
Also, add a check so gs_cet.ps only runs once - if we try to run it a second |
||||||
|
time, we'll just skip over the file, flushing through to the end. |
||||||
|
--- |
||||||
|
Resource/Init/gs_cet.ps | 11 ++++++++++- |
||||||
|
Resource/Init/gs_init.ps | 13 ++++++++++++- |
||||||
|
2 files changed, 22 insertions(+), 2 deletions(-) |
||||||
|
|
||||||
|
diff --git a/Resource/Init/gs_cet.ps b/Resource/Init/gs_cet.ps |
||||||
|
index d3e1686..75534bb 100644 |
||||||
|
--- a/Resource/Init/gs_cet.ps |
||||||
|
+++ b/Resource/Init/gs_cet.ps |
||||||
|
@@ -1,6 +1,11 @@ |
||||||
|
%!PS |
||||||
|
% Set defaults for Ghostscript to match Adobe CPSI behaviour for CET |
||||||
|
|
||||||
|
+systemdict /product get (PhotoPRINT SE 5.0v2) readonly eq |
||||||
|
+{ |
||||||
|
+ (%END GS_CET) .skipeof |
||||||
|
+} if |
||||||
|
+ |
||||||
|
% do this in the server level so it is persistent across jobs |
||||||
|
//true 0 startjob not { |
||||||
|
(*** Warning: CET startup is not in server default) = flush |
||||||
|
@@ -25,7 +30,9 @@ currentglobal //true setglobal |
||||||
|
|
||||||
|
/UNROLLFORMS true def |
||||||
|
|
||||||
|
-{ } bind dup |
||||||
|
+(%.defaultbgrucrproc) cvn { } bind def |
||||||
|
+ |
||||||
|
+(%.defaultbgrucrproc) cvn load dup |
||||||
|
setblackgeneration |
||||||
|
setundercolorremoval |
||||||
|
0 array cvx readonly dup dup dup setcolortransfer |
||||||
|
@@ -109,3 +116,5 @@ userdict /.smoothness currentsmoothness put |
||||||
|
% end of slightly nasty hack to give consistent cluster results |
||||||
|
|
||||||
|
//false 0 startjob pop % re-enter encapsulated mode |
||||||
|
+ |
||||||
|
+%END GS_CET |
||||||
|
diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps |
||||||
|
index a2503f1..9a1f2b2 100644 |
||||||
|
--- a/Resource/Init/gs_init.ps |
||||||
|
+++ b/Resource/Init/gs_init.ps |
||||||
|
@@ -1534,10 +1534,18 @@ setpacking |
||||||
|
% any-part-of-pixel rule. |
||||||
|
0.5 .setfilladjust |
||||||
|
} bind def |
||||||
|
+ |
||||||
|
% Set the default screen and BG/UCR. |
||||||
|
+% We define the proc here, rather than inline in .setdefaultbgucr |
||||||
|
+% for the benefit of gs_cet.ps so jobs that do anything that causes |
||||||
|
+% .setdefaultbgucr to be called will still get the redefined proc |
||||||
|
+% in gs_cet.ps |
||||||
|
+(%.defaultbgrucrproc) cvn { pop 0 } def |
||||||
|
+ |
||||||
|
/.setdefaultbgucr { |
||||||
|
systemdict /setblackgeneration known { |
||||||
|
- { pop 0 } dup setblackgeneration setundercolorremoval |
||||||
|
+ (%.defaultbgrucrproc) cvn load dup |
||||||
|
+ setblackgeneration setundercolorremoval |
||||||
|
} if |
||||||
|
} bind def |
||||||
|
/.useloresscreen { % - .useloresscreen <bool> |
||||||
|
@@ -2506,4 +2514,7 @@ WRITESYSTEMDICT { |
||||||
|
% be 'true' in some cases. |
||||||
|
userdict /AGM_preserve_spots //false put |
||||||
|
|
||||||
|
+systemdict /CETMODE .knownget |
||||||
|
+{ { (gs_cet.ps) runlibfile } if } if |
||||||
|
+ |
||||||
|
% The interpreter will run the initial procedure (start). |
||||||
|
-- |
||||||
|
2.20.1 |
||||||
|
|
||||||
|
|
||||||
|
From e8acf6d1aa1fc92f453175509bfdad6f2b12dc73 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Nancy Durgin <nancy.durgin@artifex.com> |
||||||
|
Date: Thu, 14 Feb 2019 10:09:00 -0800 |
||||||
|
Subject: [PATCH 2/4] Undef /odef in gs_init.ps |
||||||
|
|
||||||
|
Made a new temporary utility function in gs_cet.ps (.odef) to use instead |
||||||
|
of /odef. This makes it fine to undef odef with all the other operators in |
||||||
|
gs_init.ps |
||||||
|
|
||||||
|
This punts the bigger question of what to do with .makeoperator, but it |
||||||
|
doesn't make the situation any worse than it already was. |
||||||
|
--- |
||||||
|
Resource/Init/gs_cet.ps | 10 ++++++++-- |
||||||
|
Resource/Init/gs_init.ps | 1 + |
||||||
|
2 files changed, 9 insertions(+), 2 deletions(-) |
||||||
|
|
||||||
|
diff --git a/Resource/Init/gs_cet.ps b/Resource/Init/gs_cet.ps |
||||||
|
index 75534bb..dbc5c4e 100644 |
||||||
|
--- a/Resource/Init/gs_cet.ps |
||||||
|
+++ b/Resource/Init/gs_cet.ps |
||||||
|
@@ -1,6 +1,10 @@ |
||||||
|
%!PS |
||||||
|
% Set defaults for Ghostscript to match Adobe CPSI behaviour for CET |
||||||
|
|
||||||
|
+/.odef { % <name> <proc> odef - |
||||||
|
+ 1 index exch .makeoperator def |
||||||
|
+} bind def |
||||||
|
+ |
||||||
|
systemdict /product get (PhotoPRINT SE 5.0v2) readonly eq |
||||||
|
{ |
||||||
|
(%END GS_CET) .skipeof |
||||||
|
@@ -93,8 +97,8 @@ userdict /.smoothness currentsmoothness put |
||||||
|
} { |
||||||
|
/setsmoothness .systemvar /typecheck signalerror |
||||||
|
} ifelse |
||||||
|
-} bind odef |
||||||
|
-/currentsmoothness { userdict /.smoothness get } bind odef % for 09-55.PS, 09-57.PS . |
||||||
|
+} bind //.odef exec |
||||||
|
+/currentsmoothness { userdict /.smoothness get } bind //.odef exec % for 09-55.PS, 09-57.PS . |
||||||
|
|
||||||
|
% slightly nasty hack to give consistent cluster results |
||||||
|
/ofnfa systemdict /filenameforall get def |
||||||
|
@@ -113,6 +117,8 @@ userdict /.smoothness currentsmoothness put |
||||||
|
} ifelse |
||||||
|
ofnfa |
||||||
|
} bind def |
||||||
|
+ |
||||||
|
+currentdict /.odef undef |
||||||
|
% end of slightly nasty hack to give consistent cluster results |
||||||
|
|
||||||
|
//false 0 startjob pop % re-enter encapsulated mode |
||||||
|
diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps |
||||||
|
index 9a1f2b2..e5678b9 100644 |
||||||
|
--- a/Resource/Init/gs_init.ps |
||||||
|
+++ b/Resource/Init/gs_init.ps |
||||||
|
@@ -2253,6 +2253,7 @@ SAFER { .setsafeglobal } if |
||||||
|
/.systemvmSFD /.settrapparams /.currentsystemparams /.currentuserparams /.getsystemparam /.getuserparam /.setsystemparams /.setuserparams |
||||||
|
/.checkpassword /.locale_to_utf8 /.currentglobal /.gcheck /.imagepath /.currentoutputdevice |
||||||
|
/.type /.writecvs /.setSMask /.currentSMask /.needinput /.countexecstack /.execstack /.applypolicies |
||||||
|
+ /odef |
||||||
|
|
||||||
|
% Used by a free user in the Library of Congress. Apparently this is used to |
||||||
|
% draw a partial page, which is then filled in by the results of a barcode |
||||||
|
-- |
||||||
|
2.20.1 |
||||||
|
|
||||||
|
|
||||||
|
From 205591753126802da850ada6511a0ff8411aa287 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Ray Johnston <ray.johnston@artifex.com> |
||||||
|
Date: Thu, 14 Feb 2019 10:20:03 -0800 |
||||||
|
Subject: [PATCH 3/4] Fix bug 700585: Restrict superexec and remove it from |
||||||
|
internals and gs_cet.ps |
||||||
|
|
||||||
|
Also while changing things, restructure the CETMODE so that it will |
||||||
|
work with -dSAFER. The gs_cet.ps is now run when we are still at save |
||||||
|
level 0 with systemdict writeable. Allows us to undefine .makeoperator |
||||||
|
and .setCPSImode internal operators after CETMODE is handled. |
||||||
|
|
||||||
|
Change previous uses of superexec to using .forceput (with the usual |
||||||
|
.bind executeonly to hide it). |
||||||
|
--- |
||||||
|
Resource/Init/gs_cet.ps | 39 ++++++++++++++------------------------- |
||||||
|
Resource/Init/gs_dps1.ps | 2 +- |
||||||
|
Resource/Init/gs_fonts.ps | 8 ++++---- |
||||||
|
Resource/Init/gs_init.ps | 38 +++++++++++++++++++++++++++----------- |
||||||
|
Resource/Init/gs_ttf.ps | 6 +++--- |
||||||
|
Resource/Init/gs_type1.ps | 6 +++--- |
||||||
|
6 files changed, 52 insertions(+), 47 deletions(-) |
||||||
|
|
||||||
|
diff --git a/Resource/Init/gs_cet.ps b/Resource/Init/gs_cet.ps |
||||||
|
index dbc5c4e..58da404 100644 |
||||||
|
--- a/Resource/Init/gs_cet.ps |
||||||
|
+++ b/Resource/Init/gs_cet.ps |
||||||
|
@@ -1,37 +1,28 @@ |
||||||
|
-%!PS |
||||||
|
% Set defaults for Ghostscript to match Adobe CPSI behaviour for CET |
||||||
|
|
||||||
|
-/.odef { % <name> <proc> odef - |
||||||
|
- 1 index exch .makeoperator def |
||||||
|
-} bind def |
||||||
|
- |
||||||
|
+% skip if we've already run this -- based on fake "product" |
||||||
|
systemdict /product get (PhotoPRINT SE 5.0v2) readonly eq |
||||||
|
{ |
||||||
|
(%END GS_CET) .skipeof |
||||||
|
} if |
||||||
|
|
||||||
|
-% do this in the server level so it is persistent across jobs |
||||||
|
-//true 0 startjob not { |
||||||
|
- (*** Warning: CET startup is not in server default) = flush |
||||||
|
-} if |
||||||
|
+% Note: this must be run at save level 0 and when systemdict is writeable |
||||||
|
+currentglobal //true setglobal |
||||||
|
+systemdict dup dup dup |
||||||
|
+/version (3017.102) readonly .forceput % match CPSI 3017.102 |
||||||
|
+/product (PhotoPRINT SE 5.0v2) readonly .forceput % match CPSI 3017.102 |
||||||
|
+/revision 0 put % match CPSI 3017.103 Tek shows revision 5 |
||||||
|
+/serialnumber dup {233640} readonly .makeoperator .forceput % match CPSI 3017.102 Tek shows serialnumber 1401788461 |
||||||
|
+ |
||||||
|
+systemdict /.odef { % <name> <proc> odef - |
||||||
|
+ 1 index exch //.makeoperator def |
||||||
|
+} .bind .forceput % this will be undefined at the end |
||||||
|
|
||||||
|
300 .sethiresscreen % needed for language switch build since it |
||||||
|
% processes gs_init.ps BEFORE setting the resolution |
||||||
|
|
||||||
|
0 array 0 setdash % CET 09-08 wants local setdash |
||||||
|
|
||||||
|
-currentglobal //true setglobal |
||||||
|
- |
||||||
|
-{ |
||||||
|
- systemdict dup dup dup |
||||||
|
- /version (3017.102) readonly put % match CPSI 3017.102 |
||||||
|
- /product (PhotoPRINT SE 5.0v2) readonly put % match CPSI 3017.102 |
||||||
|
- /revision 0 put % match CPSI 3017.103 Tek shows revision 5 |
||||||
|
- /serialnumber dup {233640} readonly .makeoperator put % match CPSI 3017.102 Tek shows serialnumber 1401788461 |
||||||
|
- systemdict /deviceinfo undef % for CET 20-23-1 |
||||||
|
-% /UNROLLFORMS true put % CET files do unreasonable things inside forms |
||||||
|
-} 1183615869 internaldict /superexec get exec |
||||||
|
- |
||||||
|
/UNROLLFORMS true def |
||||||
|
|
||||||
|
(%.defaultbgrucrproc) cvn { } bind def |
||||||
|
@@ -118,9 +109,7 @@ userdict /.smoothness currentsmoothness put |
||||||
|
ofnfa |
||||||
|
} bind def |
||||||
|
|
||||||
|
-currentdict /.odef undef |
||||||
|
-% end of slightly nasty hack to give consistent cluster results |
||||||
|
- |
||||||
|
-//false 0 startjob pop % re-enter encapsulated mode |
||||||
|
+systemdict /.odef .undef |
||||||
|
|
||||||
|
+% end of slightly nasty hack to give consistent cluster results |
||||||
|
%END GS_CET |
||||||
|
diff --git a/Resource/Init/gs_dps1.ps b/Resource/Init/gs_dps1.ps |
||||||
|
index b75ea14..01475ac 100644 |
||||||
|
--- a/Resource/Init/gs_dps1.ps |
||||||
|
+++ b/Resource/Init/gs_dps1.ps |
||||||
|
@@ -85,7 +85,7 @@ level2dict begin |
||||||
|
% definition, copy it into the local directory. |
||||||
|
//systemdict /SharedFontDirectory .knownget |
||||||
|
{ 1 index .knownget |
||||||
|
- { //.FontDirectory 2 index 3 -1 roll { put } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse } % readonly |
||||||
|
+ { //.FontDirectory 2 index 3 -1 roll .forceput } % readonly |
||||||
|
if |
||||||
|
} |
||||||
|
if |
||||||
|
diff --git a/Resource/Init/gs_fonts.ps b/Resource/Init/gs_fonts.ps |
||||||
|
index 01eca35..ab062e1 100644 |
||||||
|
--- a/Resource/Init/gs_fonts.ps |
||||||
|
+++ b/Resource/Init/gs_fonts.ps |
||||||
|
@@ -512,11 +512,11 @@ buildfontdict 3 /.buildfont3 cvx put |
||||||
|
% the font in LocalFontDirectory. |
||||||
|
.currentglobal |
||||||
|
{ //systemdict /LocalFontDirectory .knownget |
||||||
|
- { 2 index 2 index { .growput } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse } % readonly |
||||||
|
+ { 2 index 2 index .forceput } % readonly |
||||||
|
if |
||||||
|
} |
||||||
|
if |
||||||
|
- dup //.FontDirectory 4 -2 roll { .growput } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse % readonly |
||||||
|
+ dup //.FontDirectory 4 -2 roll .forceput % readonly |
||||||
|
% If the font originated as a resource, register it. |
||||||
|
currentfile .currentresourcefile eq { dup .registerfont } if |
||||||
|
readonly |
||||||
|
@@ -1178,13 +1178,13 @@ currentdict /.putgstringcopy .forceundef |
||||||
|
//.FontDirectory 1 index known not { |
||||||
|
2 dict dup /FontName 3 index put |
||||||
|
dup /FontType 1 put |
||||||
|
- //.FontDirectory 3 1 roll { put } systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse % readonly |
||||||
|
+ //.FontDirectory 3 1 roll //.forceput exec % readonly |
||||||
|
} { |
||||||
|
pop |
||||||
|
} ifelse |
||||||
|
} forall |
||||||
|
} forall |
||||||
|
- } |
||||||
|
+ } executeonly % hide .forceput |
||||||
|
FAKEFONTS { exch } if pop def % don't bind, .current/setglobal get redefined |
||||||
|
|
||||||
|
% Install initial fonts from Fontmap. |
||||||
|
diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps |
||||||
|
index e5678b9..a054222 100644 |
||||||
|
--- a/Resource/Init/gs_init.ps |
||||||
|
+++ b/Resource/Init/gs_init.ps |
||||||
|
@@ -2184,9 +2184,6 @@ SAFER { .setsafeglobal } if |
||||||
|
/.endtransparencygroup % transparency-example.ps |
||||||
|
/.setdotlength % Bug687720.ps |
||||||
|
/.sort /.setdebug /.mementolistnewblocks /getenv |
||||||
|
- |
||||||
|
- /.makeoperator /.setCPSImode % gs_cet.ps, this won't work on cluster with -dSAFER |
||||||
|
- |
||||||
|
/unread |
||||||
|
] |
||||||
|
{systemdict exch .forceundef} forall |
||||||
|
@@ -2266,7 +2263,6 @@ SAFER { .setsafeglobal } if |
||||||
|
|
||||||
|
% Used by our own test suite files |
||||||
|
%/.fileposition %image-qa.ps |
||||||
|
- %/.makeoperator /.setCPSImode % gs_cet.ps |
||||||
|
|
||||||
|
% Either our code uses these in ways which mean they can't be undefined, or they are used directly by |
||||||
|
% test files/utilities, or engineers expressed a desire to keep them visible. |
||||||
|
@@ -2471,6 +2467,16 @@ end |
||||||
|
/vmreclaim where |
||||||
|
{ pop NOGC not { 2 .vmreclaim 0 vmreclaim } if |
||||||
|
} if |
||||||
|
+ |
||||||
|
+% Do this before systemdict is locked (see below for additional CETMODE setup using gs_cet.ps) |
||||||
|
+systemdict /CETMODE .knownget { |
||||||
|
+ { |
||||||
|
+ (gs_cet.ps) runlibfile |
||||||
|
+ } if |
||||||
|
+} if |
||||||
|
+systemdict /.makeoperator .undef % must be after gs_cet.ps |
||||||
|
+systemdict /.setCPSImode .undef % must be after gs_cet.ps |
||||||
|
+ |
||||||
|
DELAYBIND not { |
||||||
|
systemdict /.bindnow .undef % We only need this for DELAYBIND |
||||||
|
systemdict /.forcecopynew .undef % remove temptation |
||||||
|
@@ -2479,16 +2485,29 @@ DELAYBIND not { |
||||||
|
systemdict /.forceundef .undef % ditto |
||||||
|
} if |
||||||
|
|
||||||
|
-% Move superexec to internaldict if superexec is defined. |
||||||
|
-systemdict /superexec .knownget { |
||||||
|
- 1183615869 internaldict /superexec 3 -1 roll put |
||||||
|
- systemdict /superexec .undef |
||||||
|
+% Move superexec to internaldict if superexec is defined. (Level 2 or later) |
||||||
|
+systemdict /superexec known { |
||||||
|
+ % restrict superexec to single known use by PScript5.dll |
||||||
|
+ % We could do this only for SAFER mode, but internaldict and superexec are |
||||||
|
+ % not very well documented, and we don't want them to be used. |
||||||
|
+ 1183615869 internaldict /superexec { |
||||||
|
+ 2 index /Private eq % first check for typical use in PScript5.dll |
||||||
|
+ 1 index length 1 eq and % expected usage is: dict /Private <value> {put} superexec |
||||||
|
+ 1 index 0 get systemdict /put get eq and |
||||||
|
+ { |
||||||
|
+ //superexec exec % the only usage we allow |
||||||
|
+ } { |
||||||
|
+ /superexec load /invalidaccess signalerror |
||||||
|
+ } ifelse |
||||||
|
+ } bind cvx executeonly put |
||||||
|
+ systemdict /superexec .undef % get rid of the dangerous (unrestricted) operator |
||||||
|
} if |
||||||
|
|
||||||
|
%% Can't remove this one until the last minute :-) |
||||||
|
DELAYBIND not { |
||||||
|
systemdict /.undef .undef |
||||||
|
} if |
||||||
|
+ |
||||||
|
WRITESYSTEMDICT { |
||||||
|
SAFER { |
||||||
|
(\n *** WARNING - you have selected SAFER, indicating you want Ghostscript\n) print |
||||||
|
@@ -2515,7 +2534,4 @@ WRITESYSTEMDICT { |
||||||
|
% be 'true' in some cases. |
||||||
|
userdict /AGM_preserve_spots //false put |
||||||
|
|
||||||
|
-systemdict /CETMODE .knownget |
||||||
|
-{ { (gs_cet.ps) runlibfile } if } if |
||||||
|
- |
||||||
|
% The interpreter will run the initial procedure (start). |
||||||
|
diff --git a/Resource/Init/gs_ttf.ps b/Resource/Init/gs_ttf.ps |
||||||
|
index 05943c5..996d1e2 100644 |
||||||
|
--- a/Resource/Init/gs_ttf.ps |
||||||
|
+++ b/Resource/Init/gs_ttf.ps |
||||||
|
@@ -1421,7 +1421,7 @@ mark |
||||||
|
TTFDEBUG { (\n1 setting alias: ) print dup ==only |
||||||
|
( to be the same as ) print 2 index //== exec } if |
||||||
|
|
||||||
|
- 7 index 2 index 3 -1 roll exch //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse |
||||||
|
+ 7 index 2 index 3 -1 roll exch .forceput |
||||||
|
} forall |
||||||
|
pop pop pop |
||||||
|
} |
||||||
|
@@ -1439,7 +1439,7 @@ mark |
||||||
|
exch pop |
||||||
|
TTFDEBUG { (\n2 setting alias: ) print 1 index ==only |
||||||
|
( to use glyph index: ) print dup //== exec } if |
||||||
|
- 5 index 3 1 roll //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse |
||||||
|
+ 5 index 3 1 roll .forceput |
||||||
|
//false |
||||||
|
} |
||||||
|
{ |
||||||
|
@@ -1456,7 +1456,7 @@ mark |
||||||
|
{ % CharStrings(dict) isunicode(boolean) cmap(dict) RAGL(dict) gname(name) codep(integer) gindex(integer) |
||||||
|
TTFDEBUG { (\3 nsetting alias: ) print 1 index ==only |
||||||
|
( to be index: ) print dup //== exec } if |
||||||
|
- exch pop 5 index 3 1 roll //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse |
||||||
|
+ exch pop 5 index 3 1 roll .forceput |
||||||
|
} |
||||||
|
{ |
||||||
|
pop pop |
||||||
|
@@ -1486,7 +1486,7 @@ mark |
||||||
|
} ifelse |
||||||
|
] |
||||||
|
TTFDEBUG { (Encoding: ) print dup === flush } if |
||||||
|
-} bind def |
||||||
|
+} .bind executeonly odef % hides .forceput |
||||||
|
|
||||||
|
% to be removed 9.09...... |
||||||
|
currentdict /postalias undef |
||||||
|
diff --git a/Resource/Init/gs_type1.ps b/Resource/Init/gs_type1.ps |
||||||
|
index 2935d9c..1f38dd7 100644 |
||||||
|
--- a/Resource/Init/gs_type1.ps |
||||||
|
+++ b/Resource/Init/gs_type1.ps |
||||||
|
@@ -116,7 +116,7 @@ |
||||||
|
{ % scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname aglname |
||||||
|
CFFDEBUG { (\nsetting alias: ) print dup ==only |
||||||
|
( to be the same as glyph: ) print 1 index //== exec } if |
||||||
|
- 3 index exch 3 index //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse |
||||||
|
+ 3 index exch 3 index .forceput |
||||||
|
% scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname |
||||||
|
} |
||||||
|
{pop} ifelse |
||||||
|
@@ -135,7 +135,7 @@ |
||||||
|
3 1 roll pop pop |
||||||
|
} if |
||||||
|
pop |
||||||
|
- dup /.AGLprocessed~GS //true //.growput systemdict /superexec known {//superexec}{1183615869 internaldict /superexec get exec} ifelse |
||||||
|
+ dup /.AGLprocessed~GS //true .forceput |
||||||
|
} if |
||||||
|
|
||||||
|
%% We need to excute the C .buildfont1 in a stopped context so that, if there |
||||||
|
@@ -148,7 +148,7 @@ |
||||||
|
{//.buildfont1} stopped |
||||||
|
4 3 roll .setglobal |
||||||
|
{//.buildfont1 $error /errorname get signalerror} if |
||||||
|
- } bind def |
||||||
|
+ } .bind executeonly def % hide .forceput |
||||||
|
|
||||||
|
% If the diskfont feature isn't included, define a dummy .loadfontdict. |
||||||
|
/.loadfontdict where |
||||||
|
-- |
||||||
|
2.20.1 |
||||||
|
|
||||||
|
|
||||||
|
From d683d1e6450d74619e6277efeebfc222d9a5cb91 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Ray Johnston <ray.johnston@artifex.com> |
||||||
|
Date: Sun, 24 Feb 2019 22:01:04 -0800 |
||||||
|
Subject: [PATCH 4/4] Bug 700585: Obliterate "superexec". We don't need it, nor |
||||||
|
do any known apps. |
||||||
|
|
||||||
|
We were under the impression that the Windows driver 'PScript5.dll' used |
||||||
|
superexec, but after testing with our extensive suite of PostScript file, |
||||||
|
and analysis of the PScript5 "Adobe CoolType ProcSet, it does not appear |
||||||
|
that this operator is needed anymore. Get rid of superexec and all of the |
||||||
|
references to it, since it is a potential security hole. |
||||||
|
--- |
||||||
|
Resource/Init/gs_init.ps | 18 ------------------ |
||||||
|
psi/icontext.c | 1 - |
||||||
|
psi/icstate.h | 1 - |
||||||
|
psi/zcontrol.c | 30 ------------------------------ |
||||||
|
psi/zdict.c | 6 ++---- |
||||||
|
psi/zgeneric.c | 3 +-- |
||||||
|
6 files changed, 3 insertions(+), 56 deletions(-) |
||||||
|
|
||||||
|
diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps |
||||||
|
index a054222..ca20f12 100644 |
||||||
|
--- a/Resource/Init/gs_init.ps |
||||||
|
+++ b/Resource/Init/gs_init.ps |
||||||
|
@@ -2485,24 +2485,6 @@ DELAYBIND not { |
||||||
|
systemdict /.forceundef .undef % ditto |
||||||
|
} if |
||||||
|
|
||||||
|
-% Move superexec to internaldict if superexec is defined. (Level 2 or later) |
||||||
|
-systemdict /superexec known { |
||||||
|
- % restrict superexec to single known use by PScript5.dll |
||||||
|
- % We could do this only for SAFER mode, but internaldict and superexec are |
||||||
|
- % not very well documented, and we don't want them to be used. |
||||||
|
- 1183615869 internaldict /superexec { |
||||||
|
- 2 index /Private eq % first check for typical use in PScript5.dll |
||||||
|
- 1 index length 1 eq and % expected usage is: dict /Private <value> {put} superexec |
||||||
|
- 1 index 0 get systemdict /put get eq and |
||||||
|
- { |
||||||
|
- //superexec exec % the only usage we allow |
||||||
|
- } { |
||||||
|
- /superexec load /invalidaccess signalerror |
||||||
|
- } ifelse |
||||||
|
- } bind cvx executeonly put |
||||||
|
- systemdict /superexec .undef % get rid of the dangerous (unrestricted) operator |
||||||
|
-} if |
||||||
|
- |
||||||
|
%% Can't remove this one until the last minute :-) |
||||||
|
DELAYBIND not { |
||||||
|
systemdict /.undef .undef |
||||||
|
diff --git a/psi/icontext.c b/psi/icontext.c |
||||||
|
index 1fbe486..7462ea3 100644 |
||||||
|
--- a/psi/icontext.c |
||||||
|
+++ b/psi/icontext.c |
||||||
|
@@ -151,7 +151,6 @@ context_state_alloc(gs_context_state_t ** ppcst, |
||||||
|
pcst->rand_state = rand_state_initial; |
||||||
|
pcst->usertime_total = 0; |
||||||
|
pcst->keep_usertime = false; |
||||||
|
- pcst->in_superexec = 0; |
||||||
|
pcst->plugin_list = 0; |
||||||
|
make_t(&pcst->error_object, t__invalid); |
||||||
|
{ /* |
||||||
|
diff --git a/psi/icstate.h b/psi/icstate.h |
||||||
|
index 4c6a14d..1009d85 100644 |
||||||
|
--- a/psi/icstate.h |
||||||
|
+++ b/psi/icstate.h |
||||||
|
@@ -54,7 +54,6 @@ struct gs_context_state_s { |
||||||
|
long usertime_total; /* total accumulated usertime, */ |
||||||
|
/* not counting current time if running */ |
||||||
|
bool keep_usertime; /* true if context ever executed usertime */ |
||||||
|
- int in_superexec; /* # of levels of superexec */ |
||||||
|
/* View clipping is handled in the graphics state. */ |
||||||
|
ref error_object; /* t__invalid or error object from operator */ |
||||||
|
ref userparams; /* t_dictionary */ |
||||||
|
diff --git a/psi/zcontrol.c b/psi/zcontrol.c |
||||||
|
index 0362cf4..dc813e8 100644 |
||||||
|
--- a/psi/zcontrol.c |
||||||
|
+++ b/psi/zcontrol.c |
||||||
|
@@ -158,34 +158,6 @@ zexecn(i_ctx_t *i_ctx_p) |
||||||
|
return o_push_estack; |
||||||
|
} |
||||||
|
|
||||||
|
-/* <obj> superexec - */ |
||||||
|
-static int end_superexec(i_ctx_t *); |
||||||
|
-static int |
||||||
|
-zsuperexec(i_ctx_t *i_ctx_p) |
||||||
|
-{ |
||||||
|
- os_ptr op = osp; |
||||||
|
- es_ptr ep; |
||||||
|
- |
||||||
|
- check_op(1); |
||||||
|
- if (!r_has_attr(op, a_executable)) |
||||||
|
- return 0; /* literal object just gets pushed back */ |
||||||
|
- check_estack(2); |
||||||
|
- ep = esp += 3; |
||||||
|
- make_mark_estack(ep - 2, es_other, end_superexec); /* error case */ |
||||||
|
- make_op_estack(ep - 1, end_superexec); /* normal case */ |
||||||
|
- ref_assign(ep, op); |
||||||
|
- esfile_check_cache(); |
||||||
|
- pop(1); |
||||||
|
- i_ctx_p->in_superexec++; |
||||||
|
- return o_push_estack; |
||||||
|
-} |
||||||
|
-static int |
||||||
|
-end_superexec(i_ctx_t *i_ctx_p) |
||||||
|
-{ |
||||||
|
- i_ctx_p->in_superexec--; |
||||||
|
- return 0; |
||||||
|
-} |
||||||
|
- |
||||||
|
/* <array> <executable> .runandhide <obj> */ |
||||||
|
/* before executing <executable>, <array> is been removed from */ |
||||||
|
/* the operand stack and placed on the execstack with attributes */ |
||||||
|
@@ -971,8 +943,6 @@ const op_def zcontrol3_op_defs[] = { |
||||||
|
{"0%loop_continue", loop_continue}, |
||||||
|
{"0%repeat_continue", repeat_continue}, |
||||||
|
{"0%stopped_push", stopped_push}, |
||||||
|
- {"1superexec", zsuperexec}, |
||||||
|
- {"0%end_superexec", end_superexec}, |
||||||
|
{"2.runandhide", zrunandhide}, |
||||||
|
{"0%end_runandhide", end_runandhide}, |
||||||
|
op_def_end(0) |
||||||
|
diff --git a/psi/zdict.c b/psi/zdict.c |
||||||
|
index b0deaaa..e2e525d 100644 |
||||||
|
--- a/psi/zdict.c |
||||||
|
+++ b/psi/zdict.c |
||||||
|
@@ -212,8 +212,7 @@ zundef(i_ctx_t *i_ctx_p) |
||||||
|
int code; |
||||||
|
|
||||||
|
check_type(*op1, t_dictionary); |
||||||
|
- if (i_ctx_p->in_superexec == 0) |
||||||
|
- check_dict_write(*op1); |
||||||
|
+ check_dict_write(*op1); |
||||||
|
code = idict_undef(op1, op); |
||||||
|
if (code < 0 && code != gs_error_undefined) /* ignore undefined error */ |
||||||
|
return code; |
||||||
|
@@ -504,8 +503,7 @@ zsetmaxlength(i_ctx_t *i_ctx_p) |
||||||
|
int code; |
||||||
|
|
||||||
|
check_type(*op1, t_dictionary); |
||||||
|
- if (i_ctx_p->in_superexec == 0) |
||||||
|
- check_dict_write(*op1); |
||||||
|
+ check_dict_write(*op1); |
||||||
|
check_type(*op, t_integer); |
||||||
|
if (op->value.intval < 0) |
||||||
|
return_error(gs_error_rangecheck); |
||||||
|
diff --git a/psi/zgeneric.c b/psi/zgeneric.c |
||||||
|
index 8048e28..d4edddb 100644 |
||||||
|
--- a/psi/zgeneric.c |
||||||
|
+++ b/psi/zgeneric.c |
||||||
|
@@ -204,8 +204,7 @@ zput(i_ctx_t *i_ctx_p) |
||||||
|
|
||||||
|
switch (r_type(op2)) { |
||||||
|
case t_dictionary: |
||||||
|
- if (i_ctx_p->in_superexec == 0) |
||||||
|
- check_dict_write(*op2); |
||||||
|
+ check_dict_write(*op2); |
||||||
|
{ |
||||||
|
int code = idict_put(op2, op1, op); |
||||||
|
|
||||||
|
-- |
||||||
|
2.20.1 |
||||||
|
|
@ -0,0 +1,56 @@ |
|||||||
|
From ed9fcd95bb01f0768bf273b2526732e381202319 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Chris Liddell <chris.liddell@artifex.com> |
||||||
|
Date: Wed, 20 Feb 2019 09:54:28 +0000 |
||||||
|
Subject: [PATCH 1/2] Bug 700576: Make a transient proc executeonly (in |
||||||
|
DefineResource). |
||||||
|
|
||||||
|
This prevents access to .forceput |
||||||
|
|
||||||
|
Solution originally suggested by cbuissar@redhat.com. |
||||||
|
--- |
||||||
|
Resource/Init/gs_res.ps | 2 +- |
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-) |
||||||
|
|
||||||
|
diff --git a/Resource/Init/gs_res.ps b/Resource/Init/gs_res.ps |
||||||
|
index d9b3459..b646329 100644 |
||||||
|
--- a/Resource/Init/gs_res.ps |
||||||
|
+++ b/Resource/Init/gs_res.ps |
||||||
|
@@ -425,7 +425,7 @@ status { |
||||||
|
% so we have to use .forcedef here. |
||||||
|
/.Instances 1 index .forcedef % Category dict is read-only |
||||||
|
} executeonly if |
||||||
|
- } |
||||||
|
+ } executeonly |
||||||
|
{ .LocalInstances dup //.emptydict eq |
||||||
|
{ pop 3 dict localinstancedict Category 2 index put |
||||||
|
} |
||||||
|
-- |
||||||
|
2.20.1 |
||||||
|
|
||||||
|
|
||||||
|
From a82601e8f95a2f2147f3b3b9e44ec2b8f3a6be8b Mon Sep 17 00:00:00 2001 |
||||||
|
From: Chris Liddell <chris.liddell@artifex.com> |
||||||
|
Date: Fri, 22 Feb 2019 12:28:23 +0000 |
||||||
|
Subject: [PATCH 2/2] Bug 700576(redux): an extra transient proc needs |
||||||
|
executeonly'ed. |
||||||
|
|
||||||
|
--- |
||||||
|
Resource/Init/gs_res.ps | 2 +- |
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-) |
||||||
|
|
||||||
|
diff --git a/Resource/Init/gs_res.ps b/Resource/Init/gs_res.ps |
||||||
|
index b646329..8c1f29f 100644 |
||||||
|
--- a/Resource/Init/gs_res.ps |
||||||
|
+++ b/Resource/Init/gs_res.ps |
||||||
|
@@ -437,7 +437,7 @@ status { |
||||||
|
% Now make the resource value read-only. |
||||||
|
0 2 copy get { readonly } .internalstopped pop |
||||||
|
dup 4 1 roll put exch pop exch pop |
||||||
|
- } |
||||||
|
+ } executeonly |
||||||
|
{ /defineresource cvx /typecheck signaloperror |
||||||
|
} |
||||||
|
ifelse |
||||||
|
-- |
||||||
|
2.20.1 |
||||||
|
|
@ -0,0 +1,866 @@ |
|||||||
|
From 95aa78beae9489d5c9f898fe2032aa23f860867d Mon Sep 17 00:00:00 2001 |
||||||
|
From: Ray Johnston <ray.johnston@artifex.com> |
||||||
|
Date: Fri, 21 Sep 2018 11:16:18 -0700 |
||||||
|
Subject: [PATCH 1/6] Catch errors in setpagesize, .setpagesize and |
||||||
|
setpagedevice and cleanup |
||||||
|
|
||||||
|
Bug 699794 showed that attempt to change page size in SAFER mode when the |
||||||
|
nulldevice was the currentdevice would leave 'false' on the stack. Run |
||||||
|
.setdevice in stopped and clean up, and also clean up .setpagesize |
||||||
|
--- |
||||||
|
Resource/Init/gs_lev2.ps | 9 ++++++++- |
||||||
|
Resource/Init/gs_setpd.ps | 9 +++++++-- |
||||||
|
Resource/Init/gs_statd.ps | 22 ++++++++++++++++++---- |
||||||
|
3 files changed, 33 insertions(+), 7 deletions(-) |
||||||
|
|
||||||
|
diff --git a/Resource/Init/gs_lev2.ps b/Resource/Init/gs_lev2.ps |
||||||
|
index b69303d..ab0c32e 100644 |
||||||
|
--- a/Resource/Init/gs_lev2.ps |
||||||
|
+++ b/Resource/Init/gs_lev2.ps |
||||||
|
@@ -616,7 +616,14 @@ currentuserparams /WaitTimeout known |
||||||
|
.dicttomark setpagedevice |
||||||
|
/WaitTimeout exch mark /JobTimeout 5 2 roll .dicttomark setsystemparams |
||||||
|
} bind def |
||||||
|
-/.setpagesize { 2 array astore /PageSize .dict1 setpagedevice } bind def |
||||||
|
+/.setpagesize |
||||||
|
+ { 2 copy 2 array astore /PageSize .dict1 { setpagedevice } stopped { |
||||||
|
+ pop % the setpagedevice dict |
||||||
|
+ /setpagesize $error /errorname get signalerror |
||||||
|
+ } { |
||||||
|
+ pop pop % success -- pop the arguments |
||||||
|
+ } ifelse |
||||||
|
+ } bind def |
||||||
|
/setduplexmode { /Duplex .dict1 setpagedevice } bind def |
||||||
|
/setmargins |
||||||
|
{ exch 2 array astore /Margins .dict1 setpagedevice |
||||||
|
diff --git a/Resource/Init/gs_setpd.ps b/Resource/Init/gs_setpd.ps |
||||||
|
index 46e5810..7875d1f 100644 |
||||||
|
--- a/Resource/Init/gs_setpd.ps |
||||||
|
+++ b/Resource/Init/gs_setpd.ps |
||||||
|
@@ -932,10 +932,15 @@ SETPDDEBUG { (Recovering.) = pstack flush } if |
||||||
|
% Stack: mark ... <merged> <failed> <device> <eraseflag> |
||||||
|
SETPDDEBUG { (Installing.) = pstack flush } if |
||||||
|
|
||||||
|
- pop |
||||||
|
+ pop |
||||||
|
% .setdevice clears the current page device! |
||||||
|
.currentpagedevice pop exch |
||||||
|
- .setdevice pop |
||||||
|
+ { .setdevice } stopped { |
||||||
|
+ cleartomark exch pop |
||||||
|
+ /setpagedevice $error /errorname get |
||||||
|
+ signalerror |
||||||
|
+ } if |
||||||
|
+ pop |
||||||
|
.setpagedevice |
||||||
|
|
||||||
|
% Implement UseCIEColor directly if this is a LL3 system. |
||||||
|
diff --git a/Resource/Init/gs_statd.ps b/Resource/Init/gs_statd.ps |
||||||
|
index 64c6463..34b759c 100644 |
||||||
|
--- a/Resource/Init/gs_statd.ps |
||||||
|
+++ b/Resource/Init/gs_statd.ps |
||||||
|
@@ -39,7 +39,13 @@ statusdict begin |
||||||
|
% These procedures are also accessed as data structures during initialization, |
||||||
|
% so the page dimensions must be the first two elements of the procedure. |
||||||
|
|
||||||
|
-/.setpagesize { /statusdict .systemvar begin .setpagesize end } bind def |
||||||
|
+/.setpagesize { |
||||||
|
+ /statusdict .systemvar begin |
||||||
|
+ { .setpagesize } stopped { |
||||||
|
+ /setpagesize $error /errorname get signalerror |
||||||
|
+ } if |
||||||
|
+ end |
||||||
|
+} bind def |
||||||
|
|
||||||
|
% Page sizes defined by Adobe documentation |
||||||
|
% Note: these executable arrays should all begin with two |
||||||
|
@@ -261,9 +267,17 @@ readonly def |
||||||
|
% The Adobe documentation only defines setpagetype |
||||||
|
% (a Level 1 operator) as accepting the values 0 and 1, |
||||||
|
% so we do too. |
||||||
|
- {/letter /note} 1 index get |
||||||
|
- //systemdict /userdict get exch get cvx exec |
||||||
|
- /pagetype exch def |
||||||
|
+ dup type /integertype ne { |
||||||
|
+ /setpage /typecheck signalerror |
||||||
|
+ } { |
||||||
|
+ dup 0 ne 1 index 1 ne or { |
||||||
|
+ /setpage /rangecheck signalerror |
||||||
|
+ } { |
||||||
|
+ {/letter /note} 1 index get |
||||||
|
+ //systemdict /userdict get exch get cvx exec |
||||||
|
+ } ifelse |
||||||
|
+ /pagetype exch def |
||||||
|
+ } ifelse |
||||||
|
end |
||||||
|
} bind def |
||||||
|
|
||||||
|
-- |
||||||
|
2.20.1 |
||||||
|
|
||||||
|
|
||||||
|
From c29ec2fff76e45bbf9cd767ff541556c5d064be4 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Ray Johnston <ray.johnston@artifex.com> |
||||||
|
Date: Fri, 21 Sep 2018 12:00:50 -0700 |
||||||
|
Subject: [PATCH 2/6] Add parameter checking in setresolution |
||||||
|
|
||||||
|
Found in sequence for bug 699794 |
||||||
|
--- |
||||||
|
Resource/Init/gs_lev2.ps | 9 ++++++++- |
||||||
|
1 file changed, 8 insertions(+), 1 deletion(-) |
||||||
|
|
||||||
|
diff --git a/Resource/Init/gs_lev2.ps b/Resource/Init/gs_lev2.ps |
||||||
|
index ab0c32e..0f0d573 100644 |
||||||
|
--- a/Resource/Init/gs_lev2.ps |
||||||
|
+++ b/Resource/Init/gs_lev2.ps |
||||||
|
@@ -637,7 +637,14 @@ currentuserparams /WaitTimeout known |
||||||
|
.dicttomark setpagedevice |
||||||
|
} bind def |
||||||
|
/setresolution |
||||||
|
- { dup 2 array astore /HWResolution .dict1 setpagedevice |
||||||
|
+ { count 1 lt { /setresolution /stackunderflow signalerror } if |
||||||
|
+ dup type dup /integertype eq exch /realtype eq or not |
||||||
|
+ { |
||||||
|
+ /setresolution /typecheck signalerror |
||||||
|
+ } if |
||||||
|
+ dup 2 array astore /HWResolution .dict1 { setpagedevice } stopped { |
||||||
|
+ pop /setresolution $error /errorname get signalerror |
||||||
|
+ } if |
||||||
|
} bind def |
||||||
|
%END PAGEDEVICE |
||||||
|
|
||||||
|
-- |
||||||
|
2.20.1 |
||||||
|
|
||||||
|
|
||||||
|
From fe4c47d8e25d6366ecbb5ff487348148b908a89e Mon Sep 17 00:00:00 2001 |
||||||
|
From: Nancy Durgin <nancy.durgin@artifex.com> |
||||||
|
Date: Tue, 13 Nov 2018 14:23:41 -0800 |
||||||
|
Subject: [PATCH 3/6] Undefine some level2-related operators |
||||||
|
|
||||||
|
These are only a partial set. Undefine them in both the level2dict and |
||||||
|
systemdict. They are undef'd in gs_init.ps because they are used outside |
||||||
|
the scope of just gs_lev2.ps |
||||||
|
|
||||||
|
/.execform1 |
||||||
|
/.getdevparams |
||||||
|
/.setuserparams2 |
||||||
|
/.startjob |
||||||
|
/.checkFilePermitparams |
||||||
|
/.checksetparams |
||||||
|
/.copyparam |
||||||
|
/.setpagesize |
||||||
|
|
||||||
|
Rename .dict1 to .pair2dict and use immediate reference. |
||||||
|
|
||||||
|
Undef these at end of gs_lev2.ps (should never make it into systemdict): |
||||||
|
/.pair2dict |
||||||
|
/.checkprocesscomment |
||||||
|
--- |
||||||
|
Resource/Init/gs_init.ps | 18 ++++++++++++++++++ |
||||||
|
Resource/Init/gs_lev2.ps | 34 +++++++++++++++++++++------------- |
||||||
|
2 files changed, 39 insertions(+), 13 deletions(-) |
||||||
|
|
||||||
|
diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps |
||||||
|
index 48bb96d..e915f11 100644 |
||||||
|
--- a/Resource/Init/gs_init.ps |
||||||
|
+++ b/Resource/Init/gs_init.ps |
||||||
|
@@ -2271,6 +2271,24 @@ SAFER { .setsafeglobal } if |
||||||
|
] |
||||||
|
{systemdict exch .forceundef} forall |
||||||
|
|
||||||
|
+ % level 2 operators, undefine from both systemdict and level2dict |
||||||
|
+ [ |
||||||
|
+ /.execform1 |
||||||
|
+ /.getdevparams |
||||||
|
+ /.setuserparams2 |
||||||
|
+ /.startjob |
||||||
|
+ /.checkFilePermitparams |
||||||
|
+ /.checksetparams |
||||||
|
+ /.copyparam |
||||||
|
+ /.setpagesize |
||||||
|
+ |
||||||
|
+% Couldn't figure out how to do these yet |
||||||
|
+% /.checkparamtype |
||||||
|
+% /.startnewjob |
||||||
|
+ ] |
||||||
|
+ dup {level2dict exch .forceundef} forall |
||||||
|
+ {systemdict exch .forceundef} forall |
||||||
|
+ |
||||||
|
//systemdict /UndefinePostScriptOperators .forceundef |
||||||
|
} .bind executeonly def % must be bound and hidden for .forceundef |
||||||
|
|
||||||
|
diff --git a/Resource/Init/gs_lev2.ps b/Resource/Init/gs_lev2.ps |
||||||
|
index 0f0d573..e6f0645 100644 |
||||||
|
--- a/Resource/Init/gs_lev2.ps |
||||||
|
+++ b/Resource/Init/gs_lev2.ps |
||||||
|
@@ -64,7 +64,7 @@ level2dict begin |
||||||
|
pop |
||||||
|
} ifelse pop pop |
||||||
|
} forall pop pop |
||||||
|
-} .bind def % not odef, shouldn't reset stacks |
||||||
|
+} .bind odef |
||||||
|
|
||||||
|
% currentuser/systemparams creates and returns a dictionary in the |
||||||
|
% current VM. The easiest way to make this work is to copy any composite |
||||||
|
@@ -101,7 +101,7 @@ level2dict begin |
||||||
|
1 index length string exch .setglobal |
||||||
|
copy exch not { readonly } if |
||||||
|
} if |
||||||
|
-} .bind def |
||||||
|
+} .bind odef |
||||||
|
|
||||||
|
% Some user parameters are managed entirely at the PostScript level. |
||||||
|
% We take care of that here. |
||||||
|
@@ -345,13 +345,13 @@ end |
||||||
|
} ifelse |
||||||
|
} .bind def |
||||||
|
/ProcessComment //null .definepsuserparam |
||||||
|
-psuserparams /ProcessComment {.checkprocesscomment} put |
||||||
|
+psuserparams /ProcessComment {//.checkprocesscomment exec} put |
||||||
|
(%ProcessComment) cvn { |
||||||
|
/ProcessComment getuserparam |
||||||
|
dup //null eq { pop pop pop } { exec } ifelse |
||||||
|
} bind def |
||||||
|
/ProcessDSCComment //null .definepsuserparam |
||||||
|
-psuserparams /ProcessDSCComment {.checkprocesscomment} put |
||||||
|
+psuserparams /ProcessDSCComment {//.checkprocesscomment exec} put |
||||||
|
/.loadingfont //false def |
||||||
|
(%ProcessDSCComment) cvn { |
||||||
|
/ProcessDSCComment getuserparam |
||||||
|
@@ -556,7 +556,8 @@ end % serverdict |
||||||
|
% Note that statusdict must be allocated in local VM. |
||||||
|
% We don't bother with many of these yet. |
||||||
|
|
||||||
|
-/.dict1 { exch mark 3 1 roll .dicttomark } bind def |
||||||
|
+% convenience function to make a dictionary from an object and a key |
||||||
|
+/.pair2dict { exch mark 3 1 roll .dicttomark } bind def |
||||||
|
|
||||||
|
currentglobal //false setglobal 25 dict exch setglobal begin |
||||||
|
currentsystemparams |
||||||
|
@@ -569,11 +570,11 @@ systemdict /buildtime dup load put |
||||||
|
/checkpassword { .checkpassword 0 gt } bind def |
||||||
|
dup /DoStartPage known |
||||||
|
{ /dostartpage { /DoStartPage getsystemparam } bind def |
||||||
|
- /setdostartpage { /DoStartPage .dict1 setsystemparams } bind def |
||||||
|
+ /setdostartpage { /DoStartPage //.pair2dict exec setsystemparams } bind def |
||||||
|
} if |
||||||
|
dup /StartupMode known |
||||||
|
{ /dosysstart { /StartupMode getsystemparam 0 ne } bind def |
||||||
|
- /setdosysstart { { 1 } { 0 } ifelse /StartupMode .dict1 setsystemparams } bind def |
||||||
|
+ /setdosysstart { { 1 } { 0 } ifelse /StartupMode //.pair2dict exec setsystemparams } bind def |
||||||
|
} if |
||||||
|
%****** Setting jobname is supposed to set userparams.JobName, too. |
||||||
|
/jobname { /JobName getuserparam } bind def |
||||||
|
@@ -581,7 +582,7 @@ dup /StartupMode known |
||||||
|
/ramsize { /RamSize getsystemparam } bind def |
||||||
|
/realformat 1 index /RealFormat get def |
||||||
|
dup /PrinterName known |
||||||
|
- { /setprintername { /PrinterName .dict1 setsystemparams } bind def |
||||||
|
+ { /setprintername { /PrinterName //.pair2dict exec setsystemparams } bind def |
||||||
|
} if |
||||||
|
/printername |
||||||
|
{ currentsystemparams /PrinterName .knownget not { () } if exch copy |
||||||
|
@@ -617,18 +618,18 @@ currentuserparams /WaitTimeout known |
||||||
|
/WaitTimeout exch mark /JobTimeout 5 2 roll .dicttomark setsystemparams |
||||||
|
} bind def |
||||||
|
/.setpagesize |
||||||
|
- { 2 copy 2 array astore /PageSize .dict1 { setpagedevice } stopped { |
||||||
|
+ { 2 copy 2 array astore /PageSize //.pair2dict exec { setpagedevice } stopped { |
||||||
|
pop % the setpagedevice dict |
||||||
|
/setpagesize $error /errorname get signalerror |
||||||
|
} { |
||||||
|
pop pop % success -- pop the arguments |
||||||
|
} ifelse |
||||||
|
} bind def |
||||||
|
-/setduplexmode { /Duplex .dict1 setpagedevice } bind def |
||||||
|
+/setduplexmode { /Duplex //.pair2dict exec setpagedevice } bind def |
||||||
|
/setmargins |
||||||
|
- { exch 2 array astore /Margins .dict1 setpagedevice |
||||||
|
+ { exch 2 array astore /Margins //.pair2dict exec setpagedevice |
||||||
|
} bind def |
||||||
|
-/setpagemargin { 0 2 array astore /PageOffset .dict1 setpagedevice } bind def |
||||||
|
+/setpagemargin { 0 2 array astore /PageOffset //.pair2dict exec setpagedevice } bind def |
||||||
|
/setpageparams |
||||||
|
{ mark /PageSize 6 -2 roll |
||||||
|
4 index 1 and ORIENT1 { 1 } { 0 } ifelse ne { exch } if 2 array astore |
||||||
|
@@ -642,7 +643,7 @@ currentuserparams /WaitTimeout known |
||||||
|
{ |
||||||
|
/setresolution /typecheck signalerror |
||||||
|
} if |
||||||
|
- dup 2 array astore /HWResolution .dict1 { setpagedevice } stopped { |
||||||
|
+ dup 2 array astore /HWResolution //.pair2dict exec { setpagedevice } stopped { |
||||||
|
pop /setresolution $error /errorname get signalerror |
||||||
|
} if |
||||||
|
} bind def |
||||||
|
@@ -1254,3 +1255,10 @@ def |
||||||
|
%END TN 5044 psuedo-ops |
||||||
|
|
||||||
|
end % level2dict |
||||||
|
+ |
||||||
|
+% undefine things defined in this file and not referenced elsewhere |
||||||
|
+[ |
||||||
|
+ /.checkprocesscomment |
||||||
|
+ /.pair2dict |
||||||
|
+] |
||||||
|
+{level2dict exch .forceundef} forall |
||||||
|
-- |
||||||
|
2.20.1 |
||||||
|
|
||||||
|
|
||||||
|
From 932f4106a00e99e4ee32dcc02e57d3636f383ea1 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Nancy Durgin <nancy.durgin@artifex.com> |
||||||
|
Date: Wed, 28 Nov 2018 10:09:01 -0800 |
||||||
|
Subject: [PATCH 4/6] Undef internal functions from level2dict |
||||||
|
|
||||||
|
--- |
||||||
|
Resource/Init/gs_lev2.ps | 6 ++++-- |
||||||
|
1 file changed, 4 insertions(+), 2 deletions(-) |
||||||
|
|
||||||
|
diff --git a/Resource/Init/gs_lev2.ps b/Resource/Init/gs_lev2.ps |
||||||
|
index e6f0645..7638f2a 100644 |
||||||
|
--- a/Resource/Init/gs_lev2.ps |
||||||
|
+++ b/Resource/Init/gs_lev2.ps |
||||||
|
@@ -117,7 +117,7 @@ counttomark 2 idiv { |
||||||
|
} repeat pop |
||||||
|
/.definepsuserparam { % <name> <value> .definepsuserparam - |
||||||
|
psuserparams 3 copy pop |
||||||
|
- type cvlit /.checkparamtype cvx 2 packedarray cvx put |
||||||
|
+ type cvlit //.checkparamtype /exec load 3 packedarray cvx put |
||||||
|
userparams 3 1 roll put |
||||||
|
} .bind def |
||||||
|
end |
||||||
|
@@ -211,7 +211,7 @@ end |
||||||
|
} forall |
||||||
|
} if |
||||||
|
/setsystemparams //pssystemparams mark exch { |
||||||
|
- type cvlit /.checkparamtype cvx 2 packedarray cvx |
||||||
|
+ type cvlit //.checkparamtype /exec load 3 packedarray cvx |
||||||
|
} forall .dicttomark .checksetparams |
||||||
|
% Set the C-level system params. If this succeeds, we know that |
||||||
|
% the password check succeeded. |
||||||
|
@@ -1260,5 +1260,7 @@ end % level2dict |
||||||
|
[ |
||||||
|
/.checkprocesscomment |
||||||
|
/.pair2dict |
||||||
|
+ /.setcolorrendering1 |
||||||
|
+ /.checkparamtype |
||||||
|
] |
||||||
|
{level2dict exch .forceundef} forall |
||||||
|
-- |
||||||
|
2.20.1 |
||||||
|
|
||||||
|
|
||||||
|
From e7ff64cf9b756278f19c87d295ee0fd95c955c05 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Nancy Durgin <nancy.durgin@artifex.com> |
||||||
|
Date: Wed, 23 Jan 2019 12:00:30 -0800 |
||||||
|
Subject: [PATCH 5/6] Fixed bug caused by the way .checksetparams was undef'd |
||||||
|
|
||||||
|
Previously, had undef'd it by making it an operator. |
||||||
|
Now just use an immediate reference and undef it in the gs_lev2.ps file. |
||||||
|
|
||||||
|
This fixes bug introduced in commit fe4c47d8e25d6366ecbb5ff487348148b908a89e. |
||||||
|
|
||||||
|
Undef'ing .checksetparams by making it an operator doesn't work right because |
||||||
|
errors report .checksetparams as the offending function instead of |
||||||
|
the operator that uses it (setsystemparams in this case). |
||||||
|
|
||||||
|
This caused an error in file /tests_private/ps/ps3cet/27-09.PS on page 3, |
||||||
|
where it reports the offending function of some error-handling tests. |
||||||
|
Reporting function should be 'setsystemparams', not '.checksetparams' on |
||||||
|
this page. |
||||||
|
--- |
||||||
|
Resource/Init/gs_init.ps | 1 - |
||||||
|
Resource/Init/gs_lev2.ps | 7 ++++--- |
||||||
|
2 files changed, 4 insertions(+), 4 deletions(-) |
||||||
|
|
||||||
|
diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps |
||||||
|
index e915f11..a2503f1 100644 |
||||||
|
--- a/Resource/Init/gs_init.ps |
||||||
|
+++ b/Resource/Init/gs_init.ps |
||||||
|
@@ -2278,7 +2278,6 @@ SAFER { .setsafeglobal } if |
||||||
|
/.setuserparams2 |
||||||
|
/.startjob |
||||||
|
/.checkFilePermitparams |
||||||
|
- /.checksetparams |
||||||
|
/.copyparam |
||||||
|
/.setpagesize |
||||||
|
|
||||||
|
diff --git a/Resource/Init/gs_lev2.ps b/Resource/Init/gs_lev2.ps |
||||||
|
index 7638f2a..de1cc94 100644 |
||||||
|
--- a/Resource/Init/gs_lev2.ps |
||||||
|
+++ b/Resource/Init/gs_lev2.ps |
||||||
|
@@ -64,7 +64,7 @@ level2dict begin |
||||||
|
pop |
||||||
|
} ifelse pop pop |
||||||
|
} forall pop pop |
||||||
|
-} .bind odef |
||||||
|
+} .bind def |
||||||
|
|
||||||
|
% currentuser/systemparams creates and returns a dictionary in the |
||||||
|
% current VM. The easiest way to make this work is to copy any composite |
||||||
|
@@ -129,7 +129,7 @@ end |
||||||
|
/.setuserparams2 { |
||||||
|
% Check that we will be able to set the PostScript-level |
||||||
|
% user parameters. |
||||||
|
- /setuserparams /psuserparams .systemvar .checksetparams |
||||||
|
+ /setuserparams /psuserparams .systemvar //.checksetparams exec |
||||||
|
% Set the C-level user params. If this succeeds, we know that |
||||||
|
% the password check succeeded. |
||||||
|
dup .setuserparams |
||||||
|
@@ -212,7 +212,7 @@ end |
||||||
|
} if |
||||||
|
/setsystemparams //pssystemparams mark exch { |
||||||
|
type cvlit //.checkparamtype /exec load 3 packedarray cvx |
||||||
|
- } forall .dicttomark .checksetparams |
||||||
|
+ } forall .dicttomark //.checksetparams exec |
||||||
|
% Set the C-level system params. If this succeeds, we know that |
||||||
|
% the password check succeeded. |
||||||
|
dup .setsystemparams |
||||||
|
@@ -1262,5 +1262,6 @@ end % level2dict |
||||||
|
/.pair2dict |
||||||
|
/.setcolorrendering1 |
||||||
|
/.checkparamtype |
||||||
|
+ /.checksetparams |
||||||
|
] |
||||||
|
{level2dict exch .forceundef} forall |
||||||
|
-- |
||||||
|
2.20.1 |
||||||
|
|
||||||
|
|
||||||
|
From 4ec9ca74bed49f2a82acb4bf430eae0d8b3b75c9 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Ray Johnston <ray.johnston@artifex.com> |
||||||
|
Date: Thu, 31 Jan 2019 11:31:30 -0800 |
||||||
|
Subject: [PATCH 6/6] Hide pdfdict and GS_PDF_ProcSet (internal stuff for the |
||||||
|
PDF interp). |
||||||
|
|
||||||
|
We now keep GS_PDF_ProcSet in pdfdict, and immediately bind pdfdict |
||||||
|
where needed so we can undef it after the last PDF interp file has |
||||||
|
run (pdf_sec.ps). |
||||||
|
--- |
||||||
|
Resource/Init/pdf_base.ps | 11 ++++---- |
||||||
|
Resource/Init/pdf_draw.ps | 59 +++++++++++++++++++-------------------- |
||||||
|
Resource/Init/pdf_font.ps | 9 +++--- |
||||||
|
Resource/Init/pdf_main.ps | 25 +++++++++-------- |
||||||
|
Resource/Init/pdf_ops.ps | 11 ++++---- |
||||||
|
Resource/Init/pdf_sec.ps | 4 ++- |
||||||
|
6 files changed, 60 insertions(+), 59 deletions(-) |
||||||
|
|
||||||
|
diff --git a/Resource/Init/pdf_base.ps b/Resource/Init/pdf_base.ps |
||||||
|
index c62ac0e..d3c3a5f 100644 |
||||||
|
--- a/Resource/Init/pdf_base.ps |
||||||
|
+++ b/Resource/Init/pdf_base.ps |
||||||
|
@@ -23,7 +23,6 @@ |
||||||
|
|
||||||
|
/.setlanguagelevel where { pop 2 .setlanguagelevel } if |
||||||
|
.currentglobal //true .setglobal |
||||||
|
-/pdfdict where { pop } { /pdfdict 100 dict def } ifelse |
||||||
|
pdfdict begin |
||||||
|
|
||||||
|
% Define the name interpretation dictionary for reading values. |
||||||
|
@@ -130,11 +129,11 @@ currentdict /num-chars-dict .undef |
||||||
|
|
||||||
|
/.pdfexectoken { % <count> <opdict> <exectoken> .pdfexectoken ? |
||||||
|
PDFDEBUG { |
||||||
|
- pdfdict /PDFSTEPcount known not { pdfdict /PDFSTEPcount 1 .forceput } executeonly if |
||||||
|
+ //pdfdict /PDFSTEPcount known not { //pdfdict /PDFSTEPcount 1 .forceput } executeonly if |
||||||
|
PDFSTEP { |
||||||
|
- pdfdict /PDFtokencount 2 copy .knownget { 1 add } { 1 } ifelse .forceput |
||||||
|
+ //pdfdict /PDFtokencount 2 copy .knownget { 1 add } { 1 } ifelse .forceput |
||||||
|
PDFSTEPcount 1 gt { |
||||||
|
- pdfdict /PDFSTEPcount PDFSTEPcount 1 sub .forceput |
||||||
|
+ //pdfdict /PDFSTEPcount PDFSTEPcount 1 sub .forceput |
||||||
|
} executeonly |
||||||
|
{ |
||||||
|
dup ==only |
||||||
|
@@ -142,10 +141,10 @@ currentdict /num-chars-dict .undef |
||||||
|
( ? ) print flush 1 //false .outputpage |
||||||
|
(%stdin) (r) file 255 string readline { |
||||||
|
token { |
||||||
|
- exch pop pdfdict /PDFSTEPcount 3 -1 roll .forceput |
||||||
|
+ exch pop //pdfdict /PDFSTEPcount 3 -1 roll .forceput |
||||||
|
} executeonly |
||||||
|
{ |
||||||
|
- pdfdict /PDFSTEPcount 1 .forceput |
||||||
|
+ //pdfdict /PDFSTEPcount 1 .forceput |
||||||
|
} executeonly ifelse % token |
||||||
|
} { |
||||||
|
pop /PDFSTEP //false def % EOF on stdin |
||||||
|
diff --git a/Resource/Init/pdf_draw.ps b/Resource/Init/pdf_draw.ps |
||||||
|
index d743ae1..1add3f7 100644 |
||||||
|
--- a/Resource/Init/pdf_draw.ps |
||||||
|
+++ b/Resource/Init/pdf_draw.ps |
||||||
|
@@ -18,8 +18,7 @@ |
||||||
|
|
||||||
|
/.setlanguagelevel where { pop 2 .setlanguagelevel } if |
||||||
|
.currentglobal //true .setglobal |
||||||
|
-/pdfdict where { pop } { /pdfdict 100 dict def } ifelse |
||||||
|
-GS_PDF_ProcSet begin |
||||||
|
+/GS_PDF_ProcSet load begin |
||||||
|
pdfdict begin |
||||||
|
|
||||||
|
% For simplicity, we use a single interpretation dictionary for all |
||||||
|
@@ -113,7 +112,7 @@ pdfdict begin |
||||||
|
|
||||||
|
/resolvefunction { % <fndict> resolvefunction <function> |
||||||
|
.resolvefn |
||||||
|
- PDFDEBUG { pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%Function: ) print dup === flush } if } if |
||||||
|
+ PDFDEBUG { //pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%Function: ) print dup === flush } if } if |
||||||
|
} bind executeonly def |
||||||
|
|
||||||
|
/resolvefnproc { % <fndict> resolvefnproc <proc> |
||||||
|
@@ -1073,7 +1072,7 @@ currentdict end readonly def |
||||||
|
%% finished running the PaintProc. |
||||||
|
|
||||||
|
/.actual_pdfpaintproc { % <patdict> <resdict> .pdfpaintproc - |
||||||
|
- PDFDEBUG { pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%Begin PaintProc) print dup === flush } if } if |
||||||
|
+ PDFDEBUG { //pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%Begin PaintProc) print dup === flush } if } if |
||||||
|
PDFfile fileposition 3 1 roll |
||||||
|
q |
||||||
|
1 index /PaintType oget 1 eq { |
||||||
|
@@ -1108,21 +1107,21 @@ currentdict end readonly def |
||||||
|
Q |
||||||
|
}{ |
||||||
|
(\n **** Error: File has unbalanced q/Q operators \(too many Q's\)\n Output may be incorrect.\n) |
||||||
|
- pdfdict /.Qqwarning_issued .knownget |
||||||
|
+ //pdfdict /.Qqwarning_issued .knownget |
||||||
|
{ |
||||||
|
{ |
||||||
|
pop |
||||||
|
} |
||||||
|
{ |
||||||
|
- currentglobal pdfdict gcheck .setglobal |
||||||
|
- pdfdict /.Qqwarning_issued //true .forceput |
||||||
|
+ currentglobal //pdfdict gcheck .setglobal |
||||||
|
+ //pdfdict /.Qqwarning_issued //true .forceput |
||||||
|
.setglobal |
||||||
|
pdfformaterror |
||||||
|
} executeonly ifelse |
||||||
|
} |
||||||
|
{ |
||||||
|
- currentglobal pdfdict gcheck .setglobal |
||||||
|
- pdfdict /.Qqwarning_issued //true .forceput |
||||||
|
+ currentglobal //pdfdict gcheck .setglobal |
||||||
|
+ //pdfdict /.Qqwarning_issued //true .forceput |
||||||
|
.setglobal |
||||||
|
pdfformaterror |
||||||
|
} executeonly ifelse |
||||||
|
@@ -1131,21 +1130,21 @@ currentdict end readonly def |
||||||
|
} loop |
||||||
|
{ |
||||||
|
(\n **** Error: File has unbalanced q/Q operators \(too many q's\)\n Output may be incorrect.\n) |
||||||
|
- pdfdict /.Qqwarning_issued .knownget |
||||||
|
+ //pdfdict /.Qqwarning_issued .knownget |
||||||
|
{ |
||||||
|
{ |
||||||
|
pop |
||||||
|
} |
||||||
|
{ |
||||||
|
- currentglobal pdfdict gcheck .setglobal |
||||||
|
- pdfdict /.Qqwarning_issued //true .forceput |
||||||
|
+ currentglobal //pdfdict gcheck .setglobal |
||||||
|
+ //pdfdict /.Qqwarning_issued //true .forceput |
||||||
|
.setglobal |
||||||
|
pdfformaterror |
||||||
|
} executeonly ifelse |
||||||
|
} |
||||||
|
{ |
||||||
|
- currentglobal pdfdict gcheck .setglobal |
||||||
|
- pdfdict /.Qqwarning_issued //true .forceput |
||||||
|
+ currentglobal //pdfdict gcheck .setglobal |
||||||
|
+ //pdfdict /.Qqwarning_issued //true .forceput |
||||||
|
.setglobal |
||||||
|
pdfformaterror |
||||||
|
} executeonly ifelse |
||||||
|
@@ -1156,7 +1155,7 @@ currentdict end readonly def |
||||||
|
/pdfemptycount exch def |
||||||
|
|
||||||
|
Q |
||||||
|
- PDFDEBUG { pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%End PaintProc) print dup === flush } if } if |
||||||
|
+ PDFDEBUG { //pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%End PaintProc) print dup === flush } if } if |
||||||
|
PDFfile exch setfileposition |
||||||
|
} bind executeonly odef |
||||||
|
|
||||||
|
@@ -1227,7 +1226,7 @@ currentdict end readonly def |
||||||
|
] cvx put |
||||||
|
dup /BBox 2 copy knownoget { normrect FixPatternBBox put } { pop pop } ifelse |
||||||
|
dup /.pattern_uses_transparency 1 index patternusestransparency put |
||||||
|
- PDFDEBUG { pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%Pattern: ) print dup === flush } if } if |
||||||
|
+ PDFDEBUG { //pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%Pattern: ) print dup === flush } if } if |
||||||
|
} bind executeonly def |
||||||
|
|
||||||
|
/ignore_color_op ( **** Error: Ignoring a color operation in a cached context.\n Output may be incorrect.\n) readonly def |
||||||
|
@@ -2348,16 +2347,16 @@ currentdict /last-ditch-bpc-csp undef |
||||||
|
} bind executeonly def |
||||||
|
|
||||||
|
/IncrementAppearanceNumber { |
||||||
|
- pdfdict /AppearanceNumber .knownget { |
||||||
|
- 1 add pdfdict /AppearanceNumber 3 -1 roll .forceput |
||||||
|
+ //pdfdict /AppearanceNumber .knownget { |
||||||
|
+ 1 add //pdfdict /AppearanceNumber 3 -1 roll .forceput |
||||||
|
} executeonly |
||||||
|
{ |
||||||
|
- pdfdict /AppearanceNumber 0 .forceput |
||||||
|
+ //pdfdict /AppearanceNumber 0 .forceput |
||||||
|
} executeonly ifelse |
||||||
|
}bind executeonly odef |
||||||
|
|
||||||
|
/MakeAppearanceName { |
||||||
|
- pdfdict /AppearanceNumber get |
||||||
|
+ //pdfdict /AppearanceNumber get |
||||||
|
10 string cvs |
||||||
|
dup length 10 add string dup 0 (\{FormName) putinterval |
||||||
|
dup 3 -1 roll |
||||||
|
@@ -2378,17 +2377,17 @@ currentdict /last-ditch-bpc-csp undef |
||||||
|
gsave initclip |
||||||
|
MakeNewAppearanceName |
||||||
|
.pdfFormName |
||||||
|
- pdfdict /.PreservePDFForm known {pdfdict /.PreservePDFForm get} {//false}ifelse exch |
||||||
|
- pdfdict /.PreservePDFForm true .forceput |
||||||
|
+ //pdfdict /.PreservePDFForm known {//pdfdict /.PreservePDFForm get} {//false}ifelse exch |
||||||
|
+ //pdfdict /.PreservePDFForm true .forceput |
||||||
|
DoForm |
||||||
|
- pdfdict /.PreservePDFForm 3 -1 roll .forceput |
||||||
|
+ //pdfdict /.PreservePDFForm 3 -1 roll .forceput |
||||||
|
grestore |
||||||
|
} bind executeonly odef |
||||||
|
|
||||||
|
/DoForm { |
||||||
|
%% save the current value, if its true we will set it to false later, in order |
||||||
|
%% to prevent us preserving Forms which are used *from* an annotation /Appearance. |
||||||
|
- pdfdict /.PreservePDFForm known {pdfdict /.PreservePDFForm get} {//false}ifelse exch |
||||||
|
+ //pdfdict /.PreservePDFForm known {//pdfdict /.PreservePDFForm get} {//false}ifelse exch |
||||||
|
|
||||||
|
%% We may alter the Default* colour spaces, if the Resources |
||||||
|
%% ColorSpace entry contains one of them. But we don't want that |
||||||
|
@@ -2503,13 +2502,13 @@ currentdict /last-ditch-bpc-csp undef |
||||||
|
pdfemptycount countdictstack 3 -1 roll |
||||||
|
/pdfemptycount count 4 sub store |
||||||
|
|
||||||
|
- pdfdict /.PreservePDFForm known {pdfdict /.PreservePDFForm get}{//false} ifelse |
||||||
|
+ //pdfdict /.PreservePDFForm known {//pdfdict /.PreservePDFForm get}{//false} ifelse |
||||||
|
{ |
||||||
|
%% We must *not* preserve any subsidiary forms (curently at least) as PDF |
||||||
|
%% form preservation doesn't really work. This is used just for Annotation |
||||||
|
%% Appearances currently, and if they should happen to use a form, we do not |
||||||
|
%% want to preserve it. |
||||||
|
- pdfdict /.PreservePDFForm false .forceput |
||||||
|
+ //pdfdict /.PreservePDFForm false .forceput |
||||||
|
/q cvx /execform cvx 5 -2 roll |
||||||
|
} executeonly |
||||||
|
{ |
||||||
|
@@ -2542,7 +2541,7 @@ currentdict /last-ditch-bpc-csp undef |
||||||
|
saved_DCMYK /DefaultCMYK exch /ColorSpace defineresource pop |
||||||
|
end |
||||||
|
} if |
||||||
|
- pdfdict /.PreservePDFForm 3 -1 roll .forceput |
||||||
|
+ //pdfdict /.PreservePDFForm 3 -1 roll .forceput |
||||||
|
} bind executeonly odef |
||||||
|
|
||||||
|
/_dops_save 1 array def |
||||||
|
@@ -2701,13 +2700,13 @@ drawopdict begin |
||||||
|
% Start by getting the object number for a Form XObject |
||||||
|
dup Page /XObject obj_get dup 0 eq not { |
||||||
|
% Now get the recording dictionary and see if that object number has been seen |
||||||
|
- pdfdict /Recursive_XObject_D get 1 index known { |
||||||
|
+ //pdfdict /Recursive_XObject_D get 1 index known { |
||||||
|
( **** Error: Recursive XObject detected, ignoring ") print 1 index 256 string cvs print (", object number ) print 256 string cvs print (\n) print |
||||||
|
( Output may be incorrect.\n) pdfformaterror |
||||||
|
//false |
||||||
|
}{ |
||||||
|
% We haven't seen it yet, so record it. |
||||||
|
- pdfdict /Recursive_XObject_D get 1 index null put |
||||||
|
+ //pdfdict /Recursive_XObject_D get 1 index null put |
||||||
|
3 1 roll |
||||||
|
//true |
||||||
|
}ifelse |
||||||
|
@@ -2745,7 +2744,7 @@ drawopdict begin |
||||||
|
( Output may be incorrect.\n) pdfformaterror |
||||||
|
} ifelse |
||||||
|
PDFfile exch setfileposition |
||||||
|
- pdfdict /Recursive_XObject_D get exch undef |
||||||
|
+ //pdfdict /Recursive_XObject_D get exch undef |
||||||
|
}{ |
||||||
|
% Otherwise ignore it and tidy up the stacks |
||||||
|
pop pop |
||||||
|
diff --git a/Resource/Init/pdf_font.ps b/Resource/Init/pdf_font.ps |
||||||
|
index 46408f9..275b659 100644 |
||||||
|
--- a/Resource/Init/pdf_font.ps |
||||||
|
+++ b/Resource/Init/pdf_font.ps |
||||||
|
@@ -37,8 +37,7 @@ |
||||||
|
|
||||||
|
/.setlanguagelevel where { pop 2 .setlanguagelevel } if |
||||||
|
.currentglobal //true .setglobal |
||||||
|
-/pdfdict where { pop } { /pdfdict 100 dict def } ifelse |
||||||
|
-GS_PDF_ProcSet begin |
||||||
|
+/GS_PDF_ProcSet load begin % from userdict at this point |
||||||
|
pdfdict begin |
||||||
|
|
||||||
|
% We cache the PostScript font in an additional element of the |
||||||
|
@@ -1219,11 +1218,11 @@ currentdict /eexec_pdf_param_dict .undef |
||||||
|
.pdfruncontext |
||||||
|
countdictstack BuildCharDictDepth sub |
||||||
|
{ |
||||||
|
- pdfdict /.Qqwarning_issued .knownget {not}{//true} ifelse |
||||||
|
+ //pdfdict /.Qqwarning_issued .knownget {not}{//true} ifelse |
||||||
|
{ |
||||||
|
(\n **** Warning: Type 3 glyph has unbalanced q/Q operators \(too many q's\)\n Output may be incorrect.\n) |
||||||
|
pdfformatwarning |
||||||
|
- pdfdict /.Qqwarning_issued //true .forceput |
||||||
|
+ //pdfdict /.Qqwarning_issued //true .forceput |
||||||
|
} executeonly if |
||||||
|
Q |
||||||
|
} repeat |
||||||
|
@@ -2334,7 +2333,7 @@ currentdict /bndef undef |
||||||
|
dup //null eq |
||||||
|
{pop} |
||||||
|
{ |
||||||
|
- pdfdict /InputPDFFileName .knownget {.CRCHashFilenameAndObject} if |
||||||
|
+ //pdfdict /InputPDFFileName .knownget {.CRCHashFilenameAndObject} if |
||||||
|
exch dup /.OrigUniqueIDXUID .knownget not |
||||||
|
{ |
||||||
|
dup /XUID .knownget not |
||||||
|
diff --git a/Resource/Init/pdf_main.ps b/Resource/Init/pdf_main.ps |
||||||
|
index dd1480b..e44288e 100644 |
||||||
|
--- a/Resource/Init/pdf_main.ps |
||||||
|
+++ b/Resource/Init/pdf_main.ps |
||||||
|
@@ -18,8 +18,9 @@ |
||||||
|
|
||||||
|
/.setlanguagelevel where { pop 2 .setlanguagelevel } if |
||||||
|
.currentglobal //true .setglobal |
||||||
|
-/pdfdict where { pop } { /pdfdict 100 dict def } ifelse |
||||||
|
pdfdict begin |
||||||
|
+/GS_PDF_ProcSet dup load def % keep in pdfdict to hide it |
||||||
|
+userdict /GS_PDF_ProcSet undef |
||||||
|
|
||||||
|
% Patch in an obsolete variable used by some third-party software. |
||||||
|
/#? //false def |
||||||
|
@@ -304,8 +305,8 @@ currentdict /runpdfstring .undef |
||||||
|
/Page //null def |
||||||
|
/DSCPageCount 0 def |
||||||
|
/PDFSave //null def |
||||||
|
- GS_PDF_ProcSet begin |
||||||
|
- pdfdict begin |
||||||
|
+ //pdfdict /GS_PDF_ProcSet get begin |
||||||
|
+ //pdfdict begin |
||||||
|
pdfopen begin |
||||||
|
/CumulativePageCount currentpagedevice /PageCount get def |
||||||
|
} bind executeonly def |
||||||
|
@@ -624,7 +625,7 @@ currentdict /runpdfstring .undef |
||||||
|
%% copied to a temporary file) and store it in pdfdict. We will use this for |
||||||
|
%% hashing fonts to detect if fonts with the same name are from different files. |
||||||
|
%% |
||||||
|
- dup currentglobal exch true setglobal .getfilename exch setglobal /InputPDFFileName exch pdfdict 3 1 roll .forceput |
||||||
|
+ dup currentglobal exch true setglobal .getfilename exch setglobal /InputPDFFileName exch //pdfdict 3 1 roll .forceput |
||||||
|
|
||||||
|
//runpdfbegin exec |
||||||
|
//pdf_collection_files exec |
||||||
|
@@ -1390,7 +1391,7 @@ currentdict /xref-char-dict undef |
||||||
|
} bind executeonly def |
||||||
|
|
||||||
|
/pdfopenfile { % <file> pdfopenfile <dict> |
||||||
|
- pdfdict readonly pop % can't do it any earlier than this |
||||||
|
+ //pdfdict readonly pop % can't do it any earlier than this |
||||||
|
32 dict begin |
||||||
|
/LocalResources 0 dict def |
||||||
|
/DefaultQstate //null def % establish binding |
||||||
|
@@ -2684,21 +2685,21 @@ currentdict /PDF2PS_matrix_key undef |
||||||
|
StreamRunAborted not { |
||||||
|
(\n **** Error: File has unbalanced q/Q operators \(too many q's\)\n Output may be incorrect.\n) |
||||||
|
|
||||||
|
- pdfdict /.Qqwarning_issued .knownget |
||||||
|
+ //pdfdict /.Qqwarning_issued .knownget |
||||||
|
{ |
||||||
|
{ |
||||||
|
pop |
||||||
|
} |
||||||
|
{ |
||||||
|
- currentglobal pdfdict gcheck .setglobal |
||||||
|
- pdfdict /.Qqwarning_issued //true .forceput |
||||||
|
+ currentglobal //pdfdict gcheck .setglobal |
||||||
|
+ //pdfdict /.Qqwarning_issued //true .forceput |
||||||
|
.setglobal |
||||||
|
pdfformaterror |
||||||
|
} executeonly ifelse |
||||||
|
} |
||||||
|
{ |
||||||
|
- currentglobal pdfdict gcheck .setglobal |
||||||
|
- pdfdict /.Qqwarning_issued //true .forceput |
||||||
|
+ currentglobal //pdfdict gcheck .setglobal |
||||||
|
+ //pdfdict /.Qqwarning_issued //true .forceput |
||||||
|
.setglobal |
||||||
|
pdfformaterror |
||||||
|
} executeonly ifelse |
||||||
|
@@ -2710,8 +2711,8 @@ currentdict /PDF2PS_matrix_key undef |
||||||
|
Repaired % pass Repaired state around the restore |
||||||
|
RepairedAnError |
||||||
|
PDFSave restore |
||||||
|
- currentglobal pdfdict gcheck .setglobal |
||||||
|
- pdfdict /.Qqwarning_issued //false .forceput |
||||||
|
+ currentglobal //pdfdict gcheck .setglobal |
||||||
|
+ //pdfdict /.Qqwarning_issued //false .forceput |
||||||
|
.setglobal |
||||||
|
/RepairedAnError exch def |
||||||
|
/Repaired exch def |
||||||
|
diff --git a/Resource/Init/pdf_ops.ps b/Resource/Init/pdf_ops.ps |
||||||
|
index aa09641..c2e7461 100644 |
||||||
|
--- a/Resource/Init/pdf_ops.ps |
||||||
|
+++ b/Resource/Init/pdf_ops.ps |
||||||
|
@@ -24,6 +24,7 @@ |
||||||
|
systemdict /pdfmark known not |
||||||
|
{ userdict /pdfmark { cleartomark } bind executeonly put } if |
||||||
|
|
||||||
|
+systemdict /pdfdict where { pop } { /pdfdict 100 dict put } ifelse |
||||||
|
userdict /GS_PDF_ProcSet 256 dict dup begin |
||||||
|
|
||||||
|
% ---------------- Abbreviations ---------------- % |
||||||
|
@@ -174,21 +175,21 @@ currentdict /gput_always_allow .undef |
||||||
|
{ |
||||||
|
(\n **** Error: File has unbalanced q/Q operators \(too many Q's\)\n Output may be incorrect.\n) |
||||||
|
|
||||||
|
- pdfdict /.Qqwarning_issued .knownget |
||||||
|
+ //pdfdict /.Qqwarning_issued .knownget |
||||||
|
{ |
||||||
|
{ |
||||||
|
pop |
||||||
|
} |
||||||
|
{ |
||||||
|
- currentglobal pdfdict gcheck .setglobal |
||||||
|
- pdfdict /.Qqwarning_issued //true .forceput |
||||||
|
+ currentglobal //pdfdict gcheck .setglobal |
||||||
|
+ //pdfdict /.Qqwarning_issued //true .forceput |
||||||
|
.setglobal |
||||||
|
pdfformaterror |
||||||
|
} executeonly ifelse |
||||||
|
} |
||||||
|
{ |
||||||
|
- currentglobal pdfdict gcheck .setglobal |
||||||
|
- pdfdict /.Qqwarning_issued //true .forceput |
||||||
|
+ currentglobal //pdfdict gcheck .setglobal |
||||||
|
+ //pdfdict /.Qqwarning_issued //true .forceput |
||||||
|
.setglobal |
||||||
|
pdfformaterror |
||||||
|
} executeonly ifelse |
||||||
|
diff --git a/Resource/Init/pdf_sec.ps b/Resource/Init/pdf_sec.ps |
||||||
|
index 143efb7..a8e3d2e 100644 |
||||||
|
--- a/Resource/Init/pdf_sec.ps |
||||||
|
+++ b/Resource/Init/pdf_sec.ps |
||||||
|
@@ -39,7 +39,6 @@ |
||||||
|
|
||||||
|
/.setlanguagelevel where { pop 2 .setlanguagelevel } if |
||||||
|
.currentglobal //true .setglobal |
||||||
|
-/pdfdict where { pop } { /pdfdict 100 dict def } ifelse |
||||||
|
pdfdict begin |
||||||
|
|
||||||
|
% Older ghostscript versions do not have .pdftoken, so we use 'token' instead. |
||||||
|
@@ -748,4 +747,7 @@ currentdict /PDFScanRules_null undef |
||||||
|
} bind executeonly def |
||||||
|
|
||||||
|
end % pdfdict |
||||||
|
+ |
||||||
|
+systemdict /pdfdict .forceundef % hide pdfdict |
||||||
|
+ |
||||||
|
.setglobal |
||||||
|
-- |
||||||
|
2.20.1 |
||||||
|
|
@ -0,0 +1,39 @@ |
|||||||
|
diff --git a/Resource/Init/gs_dps.ps b/Resource/Init/gs_dps.ps |
||||||
|
index 00c14d5..2a6f4f3 100644 |
||||||
|
--- a/Resource/Init/gs_dps.ps |
||||||
|
+++ b/Resource/Init/gs_dps.ps |
||||||
|
@@ -117,7 +117,7 @@ |
||||||
|
.dicttomark readonly /localdicts exch put |
||||||
|
% localdicts is now defined in userdict. |
||||||
|
% Copy the definitions into systemdict. |
||||||
|
- localdicts { .forcedef } forall |
||||||
|
+ localdicts { .forcedef } executeonly forall |
||||||
|
% Set the user parameters. |
||||||
|
userparams readonly .setuserparams |
||||||
|
% Establish the initial gstate(s). |
||||||
|
diff --git a/Resource/Init/gs_fonts.ps b/Resource/Init/gs_fonts.ps |
||||||
|
index 4807f81..01eca35 100644 |
||||||
|
--- a/Resource/Init/gs_fonts.ps |
||||||
|
+++ b/Resource/Init/gs_fonts.ps |
||||||
|
@@ -1136,7 +1136,7 @@ $error /SubstituteFont { } put |
||||||
|
% Stack: fontdict |
||||||
|
} executeonly |
||||||
|
if pop % Stack: origfontname fontdirectory path |
||||||
|
- } |
||||||
|
+ } executeonly |
||||||
|
if pop pop % Stack: origfontname |
||||||
|
|
||||||
|
% The font definitely did not load correctly. |
||||||
|
diff --git a/Resource/Init/pdf_font.ps b/Resource/Init/pdf_font.ps |
||||||
|
index f1d1728..46408f9 100644 |
||||||
|
--- a/Resource/Init/pdf_font.ps |
||||||
|
+++ b/Resource/Init/pdf_font.ps |
||||||
|
@@ -692,7 +692,7 @@ currentdict end readonly def |
||||||
|
currentglobal exch dup gcheck setglobal |
||||||
|
dup /GlyphNames2Unicode 100 dict dup 4 1 roll .forceput |
||||||
|
3 2 roll setglobal |
||||||
|
- } if % font-res font-dict encoding|null font-info g2u |
||||||
|
+ } executeonly if % font-res font-dict encoding|null font-info g2u |
||||||
|
exch pop exch % font-res font-dict g2u encoding|null |
||||||
|
userdict /.lastToUnicode get % font-res font-dict g2u Encoding|null CMap |
||||||
|
.convert_ToUnicode-into-g2u % font-res font-dict |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,201 @@ |
|||||||
|
From f31702b38fba21153e26c3417c838618e7cfd16f Mon Sep 17 00:00:00 2001 |
||||||
|
From: Ken Sharp <ken.sharp@artifex.com> |
||||||
|
Date: Fri, 21 Sep 2018 15:28:15 +0100 |
||||||
|
Subject: [PATCH] pdfwrite - fix DSC comment parsing |
||||||
|
|
||||||
|
This may affect other DSC parsing utilities. For some reason double |
||||||
|
comment (%%) marks are being interpreted 'sometimes' in gs_init.ps |
||||||
|
as DSC comments. This only happens when reading the init files from disk |
||||||
|
becuase the ROM file system strips comments. |
||||||
|
|
||||||
|
Passing these to pdfwrite causes it to drop later DSC comments, such |
||||||
|
as %%Title: and %%Creator: which meant the information wasn't being |
||||||
|
embedded in the document information dictionary. |
||||||
|
|
||||||
|
Fix by converting double %% to single % comments, document this in the |
||||||
|
header of gs_init.ps. |
||||||
|
--- |
||||||
|
Resource/Init/gs_init.ps | 93 +++++++++++++++++++++------------------- |
||||||
|
1 file changed, 49 insertions(+), 44 deletions(-) |
||||||
|
|
||||||
|
diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps |
||||||
|
index ca20f12..d1278ea 100644 |
||||||
|
--- a/Resource/Init/gs_init.ps |
||||||
|
+++ b/Resource/Init/gs_init.ps |
||||||
|
@@ -20,6 +20,11 @@ |
||||||
|
% %% Replace <n> <file(s)> |
||||||
|
% indicate places where the next <n> lines should be replaced by |
||||||
|
% the contents of <file(s)>, when creating a single merged init file. |
||||||
|
+% |
||||||
|
+% For reasons not clear to me, some cases of %% are being treated as |
||||||
|
+% DSC comments when (and only when) the resource files are disk based |
||||||
|
+% This can kill DSC parsing for pdfwrite at least, so avoid using |
||||||
|
+% double % comments in this file. |
||||||
|
|
||||||
|
% The interpreter can call out to PostScript code. All procedures |
||||||
|
% called in this way, and no other procedures defined in these |
||||||
|
@@ -136,12 +141,12 @@ currentdict /PDFNOCIDFALLBACK known /PDFNOCIDFALLBACK exch def |
||||||
|
ifelse |
||||||
|
.bind def |
||||||
|
|
||||||
|
-%% This was a debugging switch removed in 9.22, no other software |
||||||
|
-%% should have had any regard for it, and even if testing its value |
||||||
|
-%% should have checked its existence first. However pstotext, an |
||||||
|
-%% ancient and no longer maintained piece of softare, did check |
||||||
|
-%% its value unconditionally. So we retain this key in the dictionary |
||||||
|
-%% purely for backward compatibility. |
||||||
|
+% This was a debugging switch removed in 9.22, no other software |
||||||
|
+% should have had any regard for it, and even if testing its value |
||||||
|
+% should have checked its existence first. However pstotext, an |
||||||
|
+% ancient and no longer maintained piece of softare, did check |
||||||
|
+% its value unconditionally. So we retain this key in the dictionary |
||||||
|
+% purely for backward compatibility. |
||||||
|
/NOBIND false def |
||||||
|
|
||||||
|
currentdict /BATCH known /BATCH exch def |
||||||
|
@@ -2123,12 +2128,12 @@ currentdict /tempfilepaths undef |
||||||
|
//SAFETY /safe //true .forceput % overrides readonly |
||||||
|
} .bind executeonly odef |
||||||
|
|
||||||
|
-%% This is only used during startup. Its required so that |
||||||
|
-%% we can detect in setpagdevice that we are in fact in startup |
||||||
|
-%% and allocate a *global* instead of local VM. We need it to be |
||||||
|
-%% global to satisfy Display PostScript (see start of /setpagdevice |
||||||
|
-%% in gs_setpd.ps) |
||||||
|
-%% |
||||||
|
+% This is only used during startup. Its required so that |
||||||
|
+% we can detect in setpagdevice that we are in fact in startup |
||||||
|
+% and allocate a *global* instead of local VM. We need it to be |
||||||
|
+% global to satisfy Display PostScript (see start of /setpagdevice |
||||||
|
+% in gs_setpd.ps) |
||||||
|
+% |
||||||
|
/.locksafeglobal { |
||||||
|
.locksafe_userparams |
||||||
|
systemdict /getenv {pop //false} put |
||||||
|
@@ -2157,8 +2162,8 @@ currentdict /tempfilepaths undef |
||||||
|
.locksafe |
||||||
|
} .bind executeonly odef |
||||||
|
|
||||||
|
-%% See /.locksafeglobal above. |
||||||
|
-%% |
||||||
|
+% See /.locksafeglobal above. |
||||||
|
+% |
||||||
|
/.setsafeglobal { |
||||||
|
SAFETY /safe get not { |
||||||
|
<< |
||||||
|
@@ -2193,22 +2198,22 @@ SAFER { .setsafeglobal } if |
||||||
|
|
||||||
|
/UndefinePostScriptOperators { |
||||||
|
|
||||||
|
- %% This list is of Display PostScript operators. We believe that Display PostScript |
||||||
|
- %% was never fully implemented and the only known user, GNUStep, is no longer |
||||||
|
- %% using it. So lets remove it. |
||||||
|
+ % This list is of Display PostScript operators. We believe that Display PostScript |
||||||
|
+ % was never fully implemented and the only known user, GNUStep, is no longer |
||||||
|
+ % using it. So lets remove it. |
||||||
|
[ |
||||||
|
/condition /currentcontext /detach /.fork /join /.localfork /lock /monitor /notify |
||||||
|
/wait /yield /.currentscreenphase /.setscreenphase /.image2 /eoviewclip /initviewclip |
||||||
|
/viewclip /viewclippath /defineusername |
||||||
|
- %% NeXT DPS extensions |
||||||
|
+ % NeXT DPS extensions |
||||||
|
/currentalpha /setalpha /.alphaimage /composite /compositerect /dissolve /sizeimagebox /.sizeimageparams |
||||||
|
] |
||||||
|
{systemdict exch .forceundef} forall |
||||||
|
|
||||||
|
- %% This list is of operators which no longer appear to be used, and which we do not believe |
||||||
|
- %% to have any real use. For now we will undefine the operstors so they cannot easily be used |
||||||
|
- %% but can be easily restored (just delete the name from the list in the array). In future |
||||||
|
- %% we may remove the operator and the code implementation entirely. |
||||||
|
+ % This list is of operators which no longer appear to be used, and which we do not believe |
||||||
|
+ % to have any real use. For now we will undefine the operstors so they cannot easily be used |
||||||
|
+ % but can be easily restored (just delete the name from the list in the array). In future |
||||||
|
+ % we may remove the operator and the code implementation entirely. |
||||||
|
[ |
||||||
|
/.bitadd /.charboxpath /.cond /.runandhide /.popdevicefilter |
||||||
|
/.execfile /.filenamesplit /.file_name_parent |
||||||
|
@@ -2217,15 +2222,15 @@ SAFER { .setsafeglobal } if |
||||||
|
/.currentlimitclamp /.dotorientation /.setaccuratecurves /.setcurvejoin /.setdashadapt /.setdotorientation |
||||||
|
/.setlimitclamp /.currentscreenlevels /.dashpath /.pathbbox /.identeq /.identne /.tokenexec /.forgetsave /.pantonecallback |
||||||
|
|
||||||
|
- %% Used by our own test suite files |
||||||
|
- %%/.setdotlength % Bug687720.ps |
||||||
|
+ % Used by our own test suite files |
||||||
|
+ %/.setdotlength % Bug687720.ps |
||||||
|
] |
||||||
|
{systemdict exch .forceundef} forall |
||||||
|
|
||||||
|
- %% This list of operators are used internally by various parts of the Ghostscript startup code. |
||||||
|
- %% Since each operator is a potential security vulnerability, and any operator listed here |
||||||
|
- %% is not required once the initialisation is complete and functions are bound, we undefine |
||||||
|
- %% the ones that aren't needed at runtime. |
||||||
|
+ % This list of operators are used internally by various parts of the Ghostscript startup code. |
||||||
|
+ % Since each operator is a potential security vulnerability, and any operator listed here |
||||||
|
+ % is not required once the initialisation is complete and functions are bound, we undefine |
||||||
|
+ % the ones that aren't needed at runtime. |
||||||
|
[ |
||||||
|
/.callinstall /.callbeginpage /.callendpage |
||||||
|
/.currentstackprotect /.setstackprotect /.errorexec /.finderrorobject /.installsystemnames /.bosobject /.fontbbox |
||||||
|
@@ -2297,12 +2302,12 @@ SAFER { .setsafeglobal } if |
||||||
|
} .bind executeonly def % must be bound and hidden for .forceundef |
||||||
|
|
||||||
|
/UndefinePDFOperators { |
||||||
|
- %% This list of operators are used internally by various parts of the Ghostscript PDF interpreter. |
||||||
|
- %% Since each operator is a potential security vulnerability, and any operator listed here |
||||||
|
- %% is not required once the initislisation is complete and functions are bound, we undefine |
||||||
|
- %% the ones that aren't needed at runtime. |
||||||
|
- %% This function is only called if DELAYBIND is true. It is a copy of the code at the end of pdf_main.ps |
||||||
|
- %% and must be maintained in parallel with it. |
||||||
|
+ % This list of operators are used internally by various parts of the Ghostscript PDF interpreter. |
||||||
|
+ % Since each operator is a potential security vulnerability, and any operator listed here |
||||||
|
+ % is not required once the initislisation is complete and functions are bound, we undefine |
||||||
|
+ % the ones that aren't needed at runtime. |
||||||
|
+ % This function is only called if DELAYBIND is true. It is a copy of the code at the end of pdf_main.ps |
||||||
|
+ % and must be maintained in parallel with it. |
||||||
|
[ |
||||||
|
/.pdfawidthshow /.pdfwidthshow /.currentblackptcomp /.setblackptcomp |
||||||
|
/.setfillcolor /.setfillcolorspace /.setstrokecolor /.setstrokecolorspace /.currentrenderingintent /.setrenderingintent |
||||||
|
@@ -2411,13 +2416,13 @@ $error /.nosetlocal //false put |
||||||
|
|
||||||
|
(END GLOBAL) VMDEBUG |
||||||
|
|
||||||
|
-%% .savelocalstate is part of Display PostScript (if included). Part of the function of |
||||||
|
-%% the .savelocalstate routine is to store the 'initial saved gstate' (savedinitialgstate) |
||||||
|
-%% in systemdict. The code in dps1.c, gstate_check_space, disallows writing or creating |
||||||
|
-%% gstates in global VM in certain conditions. If we execute setpagedevice before we |
||||||
|
-%% reach this point, we must ensure that we do so using /..StartupGlobal so that |
||||||
|
-%% the dictionary is defined in global VM, because the gstate contains a pointer to the |
||||||
|
-%% device dictionary, and if that is allocated in local VM we will fail the gstate check. |
||||||
|
+% .savelocalstate is part of Display PostScript (if included). Part of the function of |
||||||
|
+% the .savelocalstate routine is to store the 'initial saved gstate' (savedinitialgstate) |
||||||
|
+% in systemdict. The code in dps1.c, gstate_check_space, disallows writing or creating |
||||||
|
+% gstates in global VM in certain conditions. If we execute setpagedevice before we |
||||||
|
+% reach this point, we must ensure that we do so using /..StartupGlobal so that |
||||||
|
+% the dictionary is defined in global VM, because the gstate contains a pointer to the |
||||||
|
+% device dictionary, and if that is allocated in local VM we will fail the gstate check. |
||||||
|
/.savelocalstate where { |
||||||
|
% If we might create new contexts, save away copies of all dictionaries |
||||||
|
% referenced from systemdict that are stored in local VM, |
||||||
|
@@ -2452,8 +2457,8 @@ currentdict /.shadingtypes .undef |
||||||
|
currentdict /.wheredict .undef |
||||||
|
currentdict /.renderingintentdict .undef |
||||||
|
|
||||||
|
-%% If we are using DELAYBIND we have to defer the undefinition |
||||||
|
-%% until .bindnow. |
||||||
|
+% If we are using DELAYBIND we have to defer the undefinition |
||||||
|
+% until .bindnow. |
||||||
|
DELAYBIND not { |
||||||
|
SAFER { |
||||||
|
//systemdict /SAFERUndefinePostScriptOperators get exec |
||||||
|
@@ -2485,7 +2490,7 @@ DELAYBIND not { |
||||||
|
systemdict /.forceundef .undef % ditto |
||||||
|
} if |
||||||
|
|
||||||
|
-%% Can't remove this one until the last minute :-) |
||||||
|
+% Can't remove this one until the last minute :-) |
||||||
|
DELAYBIND not { |
||||||
|
systemdict /.undef .undef |
||||||
|
} if |
||||||
|
-- |
||||||
|
2.20.1 |
||||||
|
|
@ -0,0 +1,56 @@ |
|||||||
|
From db24f253409d5d085c2760c814c3e1d3fa2dac59 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Ray Johnston <ray.johnston@artifex.com> |
||||||
|
Date: Tue, 19 Mar 2019 09:25:48 -0700 |
||||||
|
Subject: Fix lib/pdf2dsc.ps to use documented Ghostscript pdf procedures. |
||||||
|
|
||||||
|
We eliminated GS_PDF_ProcSet and pdfdict, but runpdfbegin, dopdfpages, |
||||||
|
and runpdfend are still available. |
||||||
|
|
||||||
|
diff --git a/lib/pdf2dsc.ps b/lib/pdf2dsc.ps |
||||||
|
index 4547849c2..d836bf320 100644 |
||||||
|
--- a/lib/pdf2dsc.ps |
||||||
|
+++ b/lib/pdf2dsc.ps |
||||||
|
@@ -52,10 +52,7 @@ systemdict /.setsafe known { .setsafe } if |
||||||
|
/DSCstring 255 string def |
||||||
|
/MediaTypes 10 dict def |
||||||
|
|
||||||
|
- GS_PDF_ProcSet begin |
||||||
|
- pdfdict begin |
||||||
|
- PDFfile |
||||||
|
- pdfopen begin |
||||||
|
+ PDFfile runpdfbegin |
||||||
|
/FirstPage where { pop } { /FirstPage 1 def } ifelse |
||||||
|
/LastPage where { pop } { /LastPage pdfpagecount def } ifelse |
||||||
|
|
||||||
|
@@ -108,13 +105,12 @@ systemdict /.setsafe known { .setsafe } if |
||||||
|
(%%BeginProlog\n) puts |
||||||
|
(/Page null def\n/Page# 0 def\n/PDFSave null def\n) puts |
||||||
|
(/DSCPageCount 0 def\n) puts |
||||||
|
- (/DoPDFPage {dup /Page# exch store pdfgetpage pdfshowpage } def\n) puts |
||||||
|
- (GS_PDF_ProcSet begin\npdfdict begin\n) puts |
||||||
|
+ (/DoPDFPage {dup /Page# exch store dup dopdfpages } def\n) puts |
||||||
|
(%%EndProlog\n) puts |
||||||
|
(%%BeginSetup\n) puts |
||||||
|
DSCfile PDFname write==only |
||||||
|
( \(r\) file { DELAYSAFER { .setsafe } if } stopped pop\n) puts |
||||||
|
- ( pdfopen begin\n) puts |
||||||
|
+ ( runpdfbegin\n) puts |
||||||
|
( process_trailer_attrs\n) puts |
||||||
|
(%%EndSetup\n) puts |
||||||
|
|
||||||
|
@@ -239,13 +235,10 @@ systemdict /.setsafe known { .setsafe } if |
||||||
|
DSCfile exch DSCstring cvs writestring |
||||||
|
( DoPDFPage\n) puts |
||||||
|
} for |
||||||
|
- currentdict pdfclose |
||||||
|
- end |
||||||
|
- end |
||||||
|
- end |
||||||
|
+ runpdfend |
||||||
|
% write trailer |
||||||
|
(%%Trailer\n) puts |
||||||
|
-(currentdict pdfclose\nend\nend\nend\n) puts |
||||||
|
+(runpdfend\n) puts |
||||||
|
(%%EOF\n) puts |
||||||
|
% close output file and exit |
||||||
|
DSCfile closefile |
Loading…
Reference in new issue