[lfs-patches] r3811 - trunk/ghostscript

ken at higgs.linuxfromscratch.org ken at higgs.linuxfromscratch.org
Tue Oct 9 13:47:49 PDT 2018


Author: ken
Date: Tue Oct  9 13:47:49 2018
New Revision: 3811

Log:
Patch ghostscript again.

Added:
   trunk/ghostscript/ghostscript-9.25-security_fixes-1.patch

Added: trunk/ghostscript/ghostscript-9.25-security_fixes-1.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/ghostscript/ghostscript-9.25-security_fixes-1.patch	Tue Oct  9 13:47:49 2018	(r3811)
@@ -0,0 +1,550 @@
+not yet Submitted By: Ken Moffat <ken at linuxfromscratch dot org>
+Date: 2018-10-09
+Initial Package Version: 9.25
+Upstream Status: Applied
+Origin: Upstream
+Description: Fixes another -dSAFER sandbox escape, probably in all
+all versions still in use.  This is exploitable from e.g. gimp,
+evince, and probably from some other applications which can use
+postscript files.
+
+http://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=a54c9e61e7d0
+ (manually fixed up)
+http://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=a6807394bd94
+http://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=1778db6bc10a
+
+diff -Naur a/psi/interp.c b/psi/interp.c
+--- a/psi/interp.c	2018-09-13 11:02:01.000000000 +0100
++++ b/psi/interp.c	2018-10-09 20:45:18.442954528 +0100
+@@ -662,31 +662,24 @@
+     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. */
+     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) {
+@@ -695,6 +688,37 @@
+         }
+         *osp = *perror_object;
+         errorexec_find(i_ctx_p, osp);
++
++        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 {
++                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);
++            }
++        }
+     }
+     goto again;
+ }
+diff -Naur a/Resource/Init/gs_diskn.ps b/Resource/Init/gs_diskn.ps
+--- a/Resource/Init/gs_diskn.ps	2018-09-13 11:02:01.000000000 +0100
++++ b/Resource/Init/gs_diskn.ps	2018-10-09 20:35:56.075373644 +0100
+@@ -53,7 +53,7 @@
+     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 -Naur a/Resource/Init/gs_dps1.ps b/Resource/Init/gs_dps1.ps
+--- a/Resource/Init/gs_dps1.ps	2018-09-13 11:02:01.000000000 +0100
++++ b/Resource/Init/gs_dps1.ps	2018-10-09 20:45:18.442954528 +0100
+@@ -21,7 +21,7 @@
+ % ------ 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 -Naur a/Resource/Init/gs_dps.ps b/Resource/Init/gs_dps.ps
+--- a/Resource/Init/gs_dps.ps	2018-09-13 11:02:01.000000000 +0100
++++ b/Resource/Init/gs_dps.ps	2018-10-09 20:35:56.075373644 +0100
+@@ -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 -Naur a/Resource/Init/gs_fntem.ps b/Resource/Init/gs_fntem.ps
+--- a/Resource/Init/gs_fntem.ps	2018-09-13 11:02:01.000000000 +0100
++++ b/Resource/Init/gs_fntem.ps	2018-10-09 20:35:56.075373644 +0100
+@@ -408,7 +408,7 @@
+     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 -Naur a/Resource/Init/gs_fonts.ps b/Resource/Init/gs_fonts.ps
+--- a/Resource/Init/gs_fonts.ps	2018-09-13 11:02:01.000000000 +0100
++++ b/Resource/Init/gs_fonts.ps	2018-10-09 20:38:27.925450703 +0100
+@@ -373,7 +373,7 @@
+ % and the access path.
+ /.setnativefontmapbuilt { % set whether we've been run
+   systemdict exch /.nativefontmapbuilt exch .forceput
+-} .bind executeonly def
++} .bind executeonly odef
+ systemdict /NONATIVEFONTMAP known .setnativefontmapbuilt
+ /.buildnativefontmap {   % - .buildnativefontmap <bool>
+   systemdict /.nativefontmapbuilt .knownget not
+@@ -1098,7 +1098,7 @@
+ 
+                 % 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
+ 
+@@ -1110,7 +1110,7 @@
+          {            % 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 -Naur a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps
+--- a/Resource/Init/gs_init.ps	2018-09-13 11:02:01.000000000 +0100
++++ b/Resource/Init/gs_init.ps	2018-10-09 20:41:04.779497336 +0100
+@@ -188,6 +188,16 @@
+   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
+@@ -1123,12 +1133,23 @@
+  } 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
+@@ -1760,18 +1781,15 @@
+ 
+ % 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 -Naur a/Resource/Init/gs_lev2.ps b/Resource/Init/gs_lev2.ps
+--- a/Resource/Init/gs_lev2.ps	2018-09-13 11:02:01.000000000 +0100
++++ b/Resource/Init/gs_lev2.ps	2018-10-09 20:35:56.076373638 +0100
+@@ -163,10 +163,11 @@
+         % 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 @@
+ 
+ % 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 @@
+     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 -Naur a/Resource/Init/gs_pdfwr.ps b/Resource/Init/gs_pdfwr.ps
+--- a/Resource/Init/gs_pdfwr.ps	2018-09-13 11:02:01.000000000 +0100
++++ b/Resource/Init/gs_pdfwr.ps	2018-10-09 20:35:56.076373638 +0100
+@@ -660,7 +660,7 @@
+   {
+     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 -Naur a/Resource/Init/gs_setpd.ps b/Resource/Init/gs_setpd.ps
+--- a/Resource/Init/gs_setpd.ps	2018-09-13 11:02:01.000000000 +0100
++++ b/Resource/Init/gs_setpd.ps	2018-10-09 20:35:56.076373638 +0100
+@@ -608,6 +608,20 @@
+ % 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 @@
+         /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 @@
+         ifelse
+   } bind
+ .dicttomark readonly def
++currentdict /1Policy undef
++
+ /.applypolicies		% <orig> <merged> <failed> .applypolicies
+                         %   <orig> <merged'> <failed'>
+  { 1 index /Policies get 1 index
+diff -Naur a/Resource/Init/gs_typ32.ps b/Resource/Init/gs_typ32.ps
+--- a/Resource/Init/gs_typ32.ps	2018-09-13 11:02:01.000000000 +0100
++++ b/Resource/Init/gs_typ32.ps	2018-10-09 20:35:56.076373638 +0100
+@@ -79,15 +79,19 @@
+ .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 -Naur a/Resource/Init/gs_type1.ps b/Resource/Init/gs_type1.ps
+--- a/Resource/Init/gs_type1.ps	2018-09-13 11:02:01.000000000 +0100
++++ b/Resource/Init/gs_type1.ps	2018-10-09 20:35:56.076373638 +0100
+@@ -283,7 +283,7 @@
+   } if
+   2 copy /WeightVector exch .forceput
+   .setweightvector
+-} .bind executeonly def
++} .bind executeonly odef
+ end
+ 
+ % Register the font types for definefont.
+diff -Naur a/Resource/Init/pdf_base.ps b/Resource/Init/pdf_base.ps
+--- a/Resource/Init/pdf_base.ps	2018-09-13 11:02:01.000000000 +0100
++++ b/Resource/Init/pdf_base.ps	2018-10-09 20:35:56.076373638 +0100
+@@ -218,7 +218,7 @@
+       } ifelse
+     } ifelse
+   } ifelse
+-} bind executeonly def
++} bind executeonly odef
+ /PDFScanRules_true << /PDFScanRules //true >> def
+ /PDFScanRules_null << /PDFScanRules //null >> def
+ /.pdfrun {			% <file> <opdict> .pdfrun -
+diff -Naur a/Resource/Init/pdf_draw.ps b/Resource/Init/pdf_draw.ps
+--- a/Resource/Init/pdf_draw.ps	2018-09-13 11:02:01.000000000 +0100
++++ b/Resource/Init/pdf_draw.ps	2018-10-09 20:35:56.076373638 +0100
+@@ -1158,7 +1158,7 @@
+   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 @@
+     {
+       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 @@
+   }{
+     pdfdict /AppearanceNumber 0 .forceput
+   } ifelse
+-}bind executeonly def
++}bind executeonly odef
+ 
+ /MakeAppearanceName {
+   pdfdict /AppearanceNumber get
+@@ -2382,7 +2382,7 @@
+   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 @@
+     end
+   } if
+   pdfdict /.PreservePDFForm 3 -1 roll .forceput
+-} bind executeonly def
++} bind executeonly odef
+ 
+ /_dops_save 1 array def
+ 
+diff -Naur a/Resource/Init/pdf_font.ps b/Resource/Init/pdf_font.ps
+--- a/Resource/Init/pdf_font.ps	2018-09-13 11:02:01.000000000 +0100
++++ b/Resource/Init/pdf_font.ps	2018-10-09 20:35:56.076373638 +0100
+@@ -718,7 +718,7 @@
+   {pop pop pop}
+   ifelse
+ 
+-} bind executeonly def
++} bind executeonly odef
+ 
+ currentdict /.DoToUnicode? .forceundef
+ 
+@@ -1241,7 +1241,7 @@
+     } 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 @@
+     } 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 @@
+   /Type0 //buildType0
+   /Type1 //buildType1
+   /MMType1 //buildType1
+-  /Type3 //buildType3
++  /Type3 /buildType3 load
+   /TrueType //buildTrueType
+   /CIDFontType0 //buildCIDType0
+   /CIDFontType2 //buildCIDType2
+diff -Naur a/Resource/Init/pdf_main.ps b/Resource/Init/pdf_main.ps
+--- a/Resource/Init/pdf_main.ps	2018-09-13 11:02:01.000000000 +0100
++++ b/Resource/Init/pdf_main.ps	2018-10-09 20:35:56.077373631 +0100
+@@ -660,7 +660,7 @@
+     } forall
+     pop
+   } ifelse
+-} bind executeonly def
++} bind executeonly odef
+ 
+ currentdict /pdf_collection_files .undef
+ 
+@@ -2715,7 +2715,7 @@
+   .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 -Naur a/Resource/Init/pdf_ops.ps b/Resource/Init/pdf_ops.ps
+--- a/Resource/Init/pdf_ops.ps	2018-09-13 11:02:01.000000000 +0100
++++ b/Resource/Init/pdf_ops.ps	2018-10-09 20:35:56.077373631 +0100
+@@ -193,7 +193,7 @@
+       pdfformaterror
+     } ifelse
+   } if
+-} bind executeonly def
++} bind executeonly odef
+ 
+ % Save PDF gstate
+ /qstate {       % - qstate <qstate>
+@@ -451,7 +451,7 @@
+   %% 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 @@
+     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 @@
+     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 {


More information about the patches mailing list