From 8d19fdf63f91f50466b08f23e2d93d37a4c5ea0b Mon Sep 17 00:00:00 2001 From: Ken Sharp 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 { % .proccheck 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 { % .tryloadfont 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 dictionary with its prior value % (or remove it if it had no prior value). +% These procedures are called with the following on the stack: +% +% 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: -% -% 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 % .applypolicies % - { 1 index /Policies get 1 index - { type /integertype eq - { pop % already processed - } - { 2 copy .knownget not { 1 index /PolicyNotFound get } if - % Stack: - % - .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: + % + 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