6bfa55
From 8d19fdf63f91f50466b08f23e2d93d37a4c5ea0b Mon Sep 17 00:00:00 2001
6bfa55
From: Ken Sharp <ken.sharp@artifex.com>
6bfa55
Date: Mon, 15 Oct 2018 11:28:28 +0100
6bfa55
Subject: [PATCH] Make .forceput unavailable from '.policyprocs' helper
6bfa55
 dictionary
6bfa55
6bfa55
Bug #69963 "1Policy is a dangerous operator, any callers should be odef"
6bfa55
6bfa55
Leaving the .policyprocs dictionary with a procedure which is a simple
6bfa55
wrapper for .forceput effectively leaves .forceput available.
6bfa55
6bfa55
It seems that the only reason to have .policyprocs is to minimise the
6bfa55
code in .applypolicies, so we can remove the dictionary and put the
6bfa55
code straight into .applypolicies, which we can then bind and make
6bfa55
executeonly, which hides the .forceput. Also, since we don't need
6bfa55
.applypolicies after startup, we can undefine that from systemdict too.
6bfa55
6bfa55
While we're here, review all the uses of .force* to make certain that
6bfa55
there are no other similar cases. This showed a few places where we
6bfa55
hadn't made a function executeonly, so do that too. Its probably not
6bfa55
required, since I'm reasonably sure its impossible to load those
6bfa55
functions as packed arrays (they are all defined as operators), but lets
6bfa55
have a belt and braces approach, the additional time cost is negligible.
6bfa55
---
6bfa55
 Resource/Init/gs_diskn.ps |   2 +-
6bfa55
 Resource/Init/gs_dps.ps   |   2 +-
6bfa55
 Resource/Init/gs_epsf.ps  |   2 +-
6bfa55
 Resource/Init/gs_fonts.ps |   4 +-
6bfa55
 Resource/Init/gs_init.ps  |   2 +-
6bfa55
 Resource/Init/gs_setpd.ps | 100 ++++++++++++++++++++------------------
6bfa55
 6 files changed, 58 insertions(+), 54 deletions(-)
6bfa55
6bfa55
diff --git a/Resource/Init/gs_diskn.ps b/Resource/Init/gs_diskn.ps
6bfa55
index 26ec0b5..fd694bc 100644
6bfa55
--- a/Resource/Init/gs_diskn.ps
6bfa55
+++ b/Resource/Init/gs_diskn.ps
6bfa55
@@ -61,7 +61,7 @@ systemdict begin
6bfa55
   % doesn't get run enough to justify the complication
6bfa55
   //.putdevparams
6bfa55
   //systemdict /.searchabledevs .forceundef
6bfa55
-} .bind odef % must be bound and hidden for .forceundef
6bfa55
+} .bind executeonly odef % must be bound and hidden for .forceundef
6bfa55
 
6bfa55
 % ------ extend filenameforall to handle wildcards in %dev% part of pattern -------%
6bfa55
 /filenameforall {
6bfa55
diff --git a/Resource/Init/gs_dps.ps b/Resource/Init/gs_dps.ps
6bfa55
index daf7b0f..00c14d5 100644
6bfa55
--- a/Resource/Init/gs_dps.ps
6bfa55
+++ b/Resource/Init/gs_dps.ps
6bfa55
@@ -124,7 +124,7 @@
6bfa55
   /savedinitialgstate .systemvar setgstate gsave
6bfa55
                 % Wrap up.
6bfa55
   end .setglobal
6bfa55
-} odef
6bfa55
+} bind executeonly odef
6bfa55
 
6bfa55
 % Check whether an object is a procedure.
6bfa55
 /.proccheck {			% <obj> .proccheck <bool>
6bfa55
diff --git a/Resource/Init/gs_epsf.ps b/Resource/Init/gs_epsf.ps
6bfa55
index e4037d9..2d0f677 100644
6bfa55
--- a/Resource/Init/gs_epsf.ps
6bfa55
+++ b/Resource/Init/gs_epsf.ps
6bfa55
@@ -31,7 +31,7 @@
6bfa55
 /EPSBoundingBoxState 5 def
6bfa55
 /EPSBoundingBoxSetState {
6bfa55
   //systemdict /EPSBoundingBoxState 3 -1 roll .forceput
6bfa55
-} .bind odef % .forceput must be bound and hidden
6bfa55
+} .bind executeonly odef % .forceput must be bound and hidden
6bfa55
 
6bfa55
 % Parse 4 numbers for a bounding box
6bfa55
 /EPSBoundingBoxParse { % (llx lly urx ury) -- llx lly urx ury true OR false
6bfa55
diff --git a/Resource/Init/gs_fonts.ps b/Resource/Init/gs_fonts.ps
6bfa55
index 7a57366..052a191 100644
6bfa55
--- a/Resource/Init/gs_fonts.ps
6bfa55
+++ b/Resource/Init/gs_fonts.ps
6bfa55
@@ -583,7 +583,7 @@ buildfontdict 3 /.buildfont3 cvx put
6bfa55
 } bind def
6bfa55
 /.setloadingfont {
6bfa55
    //systemdict /.loadingfont 3 -1 roll .forceput
6bfa55
-} .bind odef % .forceput must be bound and hidden
6bfa55
+} .bind executeonly odef % .forceput must be bound and hidden
6bfa55
 /.loadfont
6bfa55
  {              % Some buggy fonts leave extra junk on the stack,
6bfa55
                 % so we have to make a closure that records the stack depth
6bfa55
@@ -1012,7 +1012,7 @@ $error /SubstituteFont { } put
6bfa55
     dup length string copy
6bfa55
     .forceput setglobal
6bfa55
   } ifelse
6bfa55
-} .bind odef % must be bound and hidden for .forceput
6bfa55
+} .bind executeonly odef % must be bound and hidden for .forceput
6bfa55
 
6bfa55
 % Attempt to load a font from a file.
6bfa55
 /.tryloadfont {         % <fontname> .tryloadfont <font> true
6bfa55
diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps
6bfa55
index 2114a2a..0b900e6 100644
6bfa55
--- a/Resource/Init/gs_init.ps
6bfa55
+++ b/Resource/Init/gs_init.ps
6bfa55
@@ -2244,7 +2244,7 @@ SAFER { .setsafeglobal } if
6bfa55
   /.localvmarray /.localvmdict /.localvmpackedarray /.localvmstring /.systemvmarray /.systemvmdict /.systemvmpackedarray /.systemvmstring /.systemvmfile /.systemvmlibfile
6bfa55
   /.systemvmSFD /.settrapparams /.currentsystemparams /.currentuserparams /.getsystemparam /.getuserparam /.setsystemparams /.setuserparams
6bfa55
   /.checkpassword /.locale_to_utf8 /.currentglobal /.gcheck /.imagepath /.currentoutputdevice
6bfa55
-  /.type /.writecvs /.setSMask /.currentSMask /.needinput /.countexecstack /.execstack
6bfa55
+  /.type /.writecvs /.setSMask /.currentSMask /.needinput /.countexecstack /.execstack /.applypolicies
6bfa55
 
6bfa55
   % Used by a free user in the Library of Congress. Apparently this is used to
6bfa55
   % draw a partial page, which is then filled in by the results of a barcode
6bfa55
diff --git a/Resource/Init/gs_setpd.ps b/Resource/Init/gs_setpd.ps
6bfa55
index fab8b84..71eb622 100644
6bfa55
--- a/Resource/Init/gs_setpd.ps
6bfa55
+++ b/Resource/Init/gs_setpd.ps
6bfa55
@@ -609,6 +609,23 @@ NOMEDIAATTRS {
6bfa55
 % and we replace the key in the <merged> dictionary with its prior value
6bfa55
 % (or remove it if it had no prior value).
6bfa55
 
6bfa55
+% These procedures are called with the following on the stack:
6bfa55
+%   <orig> <merged> <failed> <Policies> <key> <policy>
6bfa55
+% They are expected to consume the top 2 operands.
6bfa55
+% NOTE: we currently treat all values other than 0, 1, or 7 (for PageSize)
6bfa55
+% the same as 0, i.e., we signal an error.
6bfa55
+/0Policy {		% Set errorinfo and signal a configurationerror.
6bfa55
+  NOMEDIAATTRS {
6bfa55
+    % NOMEDIAATTRS means that the default policy is 7...
6bfa55
+    pop 2 index exch 7 put
6bfa55
+  } {
6bfa55
+    pop dup 4 index exch get 2 array astore
6bfa55
+    $error /errorinfo 3 -1 roll put
6bfa55
+    cleartomark
6bfa55
+    /setpagedevice .systemvar /configurationerror signalerror
6bfa55
+  } ifelse
6bfa55
+} bind executeonly odef
6bfa55
+
6bfa55
 % Making this an operator means we can properly hide
6bfa55
 % the contents - specifically .forceput
6bfa55
 /1Policy
6bfa55
@@ -617,59 +634,46 @@ NOMEDIAATTRS {
6bfa55
   SETPDDEBUG { (Rolling back.) = pstack flush } if
6bfa55
   3 index 2 index 3 -1 roll .forceput
6bfa55
   4 index 1 index .knownget
6bfa55
-   { 4 index 3 1 roll .forceput }
6bfa55
-   { 3 index exch .undef }
6bfa55
+  { 4 index 3 1 roll .forceput }
6bfa55
+  { 3 index exch .undef }
6bfa55
   ifelse
6bfa55
 } bind executeonly odef
6bfa55
 
6bfa55
-/.policyprocs mark
6bfa55
-% These procedures are called with the following on the stack:
6bfa55
-%   <orig> <merged> <failed> <Policies> <key> <policy>
6bfa55
-% They are expected to consume the top 2 operands.
6bfa55
-% NOTE: we currently treat all values other than 0, 1, or 7 (for PageSize)
6bfa55
-% the same as 0, i.e., we signal an error.
6bfa55
-%
6bfa55
-% M. Sweet, Easy Software Products:
6bfa55
-%
6bfa55
-% Define NOMEDIAATTRS to turn off the default (but unimplementable) media
6bfa55
-% selection policies for setpagedevice.  This is used by CUPS to support
6bfa55
-% the standard Adobe media attributes.
6bfa55
-  0 {		% Set errorinfo and signal a configurationerror.
6bfa55
-      NOMEDIAATTRS {
6bfa55
-        % NOMEDIAATTRS means that the default policy is 7...
6bfa55
-        pop 2 index exch 7 put
6bfa55
-      } {
6bfa55
-        pop dup 4 index exch get 2 array astore
6bfa55
-        $error /errorinfo 3 -1 roll put
6bfa55
-        cleartomark
6bfa55
-        /setpagedevice .systemvar /configurationerror signalerror
6bfa55
-      } ifelse
6bfa55
-  } bind
6bfa55
-  1 /1Policy load
6bfa55
-  7 {		% For PageSize only, just impose the request.
6bfa55
-        1 index /PageSize eq
6bfa55
-         { pop pop 1 index /PageSize 7 put }
6bfa55
-         { .policyprocs 0 get exec }
6bfa55
-        ifelse
6bfa55
-  } bind
6bfa55
-.dicttomark readonly def
6bfa55
-currentdict /1Policy undef
6bfa55
+/7Policy {		% For PageSize only, just impose the request.
6bfa55
+  1 index /PageSize eq
6bfa55
+  { pop pop 1 index /PageSize 7 put }
6bfa55
+  { .policyprocs 0 get exec }
6bfa55
+  ifelse
6bfa55
+} bind executeonly odef
6bfa55
 
6bfa55
 /.applypolicies		% <orig> <merged> <failed> .applypolicies
6bfa55
                         %   <orig> <merged'> <failed'>
6bfa55
- { 1 index /Policies get 1 index
6bfa55
-    { type /integertype eq
6bfa55
-       { pop		% already processed
6bfa55
-       }
6bfa55
-       { 2 copy .knownget not { 1 index /PolicyNotFound get } if
6bfa55
-                        % Stack: <orig> <merged> <failed> <Policies> <key>
6bfa55
-                        %   <policy>
6bfa55
-         .policyprocs 1 index .knownget not { .policyprocs 0 get } if exec
6bfa55
-       }
6bfa55
-      ifelse
6bfa55
-    }
6bfa55
-   forall pop
6bfa55
- } bind def
6bfa55
+{
6bfa55
+  1 index /Policies get 1 index
6bfa55
+  { type /integertype eq
6bfa55
+     {
6bfa55
+       pop		% already processed
6bfa55
+     }{
6bfa55
+       2 copy .knownget not { 1 index /PolicyNotFound get } if
6bfa55
+                      % Stack: <orig> <merged> <failed> <Policies> <key>
6bfa55
+                      %   <policy>
6bfa55
+        dup 1 eq {
6bfa55
+          1Policy
6bfa55
+        }{
6bfa55
+          dup 7 eq {
6bfa55
+            7Policy
6bfa55
+          }{
6bfa55
+            0Policy
6bfa55
+          } ifelse
6bfa55
+        } ifelse
6bfa55
+     } ifelse
6bfa55
+  }
6bfa55
+  forall pop
6bfa55
+} bind executeonly odef
6bfa55
+
6bfa55
+currentdict /0Policy undef
6bfa55
+currentdict /1Policy undef
6bfa55
+currentdict /7Policy undef
6bfa55
 
6bfa55
 % Prepare to present parameters to the device, by spreading them onto the
6bfa55
 % operand stack and removing any that shouldn't be presented.
6bfa55
@@ -1012,7 +1016,7 @@ SETPDDEBUG { (Installing.) = pstack flush } if
6bfa55
     .postinstall
6bfa55
   } ifelse
6bfa55
   setglobal           % return to original VM allocation mode
6bfa55
-} odef
6bfa55
+} bind executeonly odef
6bfa55
 
6bfa55
 % We break out the code after calling the Install procedure into a
6bfa55
 % separate procedure, since it is executed even if Install causes an error.
6bfa55
-- 
6bfa55
2.17.2
6bfa55