From c253752ef731f49922e0a97490d1ef09ca697c91 Mon Sep 17 00:00:00 2001 From: Ray Johnston Date: Thu, 31 Jan 2019 11:31:30 -0800 Subject: [PATCH] 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). CVE: CVE-2019-3839 Upstream-Status: Backport [http://git.ghostscript.com/?p=ghostpdl.git;a=commit;h=4ec9ca74bed49f2a82acb4bf430eae0d8b3b75c9] Signed-off-by: Naveen Saini --- 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 e35e0e373..13dd51f46 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. @@ -133,11 +132,11 @@ currentdict /num-chars-dict .undef /.pdfexectoken { % .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 @@ -145,10 +144,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 36c41a9a3..2e39c87d2 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 { % resolvefunction .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 { % resolvefnproc @@ -1086,7 +1085,7 @@ currentdict end readonly def %% finished running the PaintProc. /.actual_pdfpaintproc { % .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 { @@ -1121,21 +1120,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 @@ -1144,21 +1143,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 @@ -1169,7 +1168,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 @@ -1240,7 +1239,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 @@ -2361,16 +2360,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 @@ -2391,17 +2390,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 @@ -2516,13 +2515,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 { @@ -2555,7 +2554,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 @@ -2714,13 +2713,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 @@ -2758,7 +2757,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 7e35c02ac..6b09be61f 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 @@ -1227,11 +1226,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 @@ -2361,7 +2360,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 0a8929a2a..c1de1b0ef 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 { % pdfopenfile - 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 @@ -2717,21 +2718,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 @@ -2743,8 +2744,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 34e2fbd58..46de547f7 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 d8cc94c86..163dd6877 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.17.1