summaryrefslogtreecommitdiff
path: root/Master/tlpkg/tlgs/Resource/Init/pdf_main.ps
diff options
context:
space:
mode:
Diffstat (limited to 'Master/tlpkg/tlgs/Resource/Init/pdf_main.ps')
-rw-r--r--Master/tlpkg/tlgs/Resource/Init/pdf_main.ps403
1 files changed, 332 insertions, 71 deletions
diff --git a/Master/tlpkg/tlgs/Resource/Init/pdf_main.ps b/Master/tlpkg/tlgs/Resource/Init/pdf_main.ps
index 85b5848e160..a16f5806734 100644
--- a/Master/tlpkg/tlgs/Resource/Init/pdf_main.ps
+++ b/Master/tlpkg/tlgs/Resource/Init/pdf_main.ps
@@ -85,6 +85,9 @@ pdfdict begin
pdfformaterror
( Output may be incorrect.\n) pdfformaterror
} bind
+
+ /Recursive_XObject_D 1 dict def
+
.dicttomark readonly def
% ======================== Main program ======================== %
@@ -948,9 +951,17 @@ currentdict /xref-char-dict undef
%% Bug #695883 the test file has an XRefStm which points beyond the end of the file.
%% We check that here and simply fall back to thje classic xref if this error occurs.
dup PDFfilelen lt{
- readpdf15xref pop
+ PDFSTOPONERROR not {
+ mark exch {readpdf15xref pop} stopped
+ {
+ ( **** Error: This hybrid file's XRefStm does not point to a valid stream.\n Ignoring error, output may be incorrect.\n) pdfformaterror
+ } if
+ cleartomark
+ } {
+ readpdf15xref pop
+ } ifelse
} {
- ( **** Error: This hybrid file's XRefStm points beyond the end of file.\n Ignoring error, output may be incorrect.\n) pdfformaterror
+ ( **** Error: This hybrid file's XRefStm points beyond the end of file.\n Ignoring error, output may be incorrect.\n) pdfformaterror
pop
}ifelse
} if
@@ -1129,7 +1140,37 @@ currentdict /xref-char-dict undef
( **** ) stderrprint stderrprint
} ifelse
} ifelse
- } if
+ } {
+ % If the user told us to use a named OutputIntent
+ systemdict /UseOutputIntent .knownget {
+ cvn
+ Trailer /Root oget /OutputIntents knownoget {
+ {
+ dup /OutputConditionIdentifier get cvn
+ dup /Custom eq {
+ pop
+ dup /Info get cvn
+ }if
+ 2 index eq {
+ %% Found the required OutputIntent
+ /DestOutputProfile knownoget {
+ [ /ICCBased 3 -1 roll ] ICCBased-resolve
+ 1 get .set_outputintent
+ ()
+ } if
+ pop
+ exit
+ }{
+ pop
+ } ifelse
+ }
+ forall
+ pop
+ }{
+ pop
+ }ifelse
+ } if
+ }ifelse
Trailer /Root knownoget { /PageLabels knownoget {
%% Currenlty only the pdfwrite device can handle PageLabels
%% because we deal with these using putparams, not pdfmarks
@@ -1283,6 +1324,8 @@ currentdict /xref-char-dict undef
% Read any previous cross-reference tables. When we are done,
% verify that the entries in the xref tables are valid if NoVerifyXref
% is not defined.
+ /PrevArray [] def % Empty array, we use this to detect circular /Prev entries in xref (see below)
+ % For some reqason, leaving this on the stack messes up seom files.
Trailer
{ /Prev knownoget not { % If no previous xref table then ...
Classic-xref {
@@ -1290,10 +1333,43 @@ currentdict /xref-char-dict undef
} if
exit
} if
+
+ %% This code is used to detect circular references in xref tables. Every time
+ %% we detect a /Prev in the xref, we check the given offset of the /Prev xref
+ %% against a list of all previously encountered /Prev offsets. If we find that
+ %% we have previously seen this one, we raise an error, stop processing the xref
+ %% but carry on with the PDF file (unless PDFSTOPONERROR is true).
+ //false exch PrevArray %% Used to determine if the looop found a circular ref
+ { %% //false offset 'array entry'
+ 1 index eq {
+ exch pop //true exch %% We've seen this offset before, pop the false and replace with true
+ exit %% //true offset
+ } if
+ } forall
+
+ exch %% [...] offset bool
+ {
+ (\n **** Error: Circular /Prev entry while reading xref.\n Aborting xref read, output may be incorrect.\n)
+ pdfformaterror
+ PDFSTOPONERROR {
+ /readxref /syntaxerror cvx signalerror
+ } if
+ pop exit %% [...] and then exit this loop
+ } if
+
+ PrevArray dup %% offset [...] [...]
+ length 1 add array %% offset [...] [ ]
+ dup 3 1 roll %% offset [ ] [...] [ ]
+ copy pop %% offset [... ]
+ dup dup length 1 sub %% offset [... ] [... ] index
+ 3 index %% offset [... ] [... ] index offset
+ put /PrevArray exch def
+
{ readxref }
PDFSTOPONERROR not {
.internalstopped {
recover_xref_data % Read failed. Attempt to recover xref data.
+ /PrevArray where {/PrevArray undef} if %% remove the array we were using to detect circular references
exit % Exit loop since recover gets all obj data.
} if % If readxref stopped
} {
@@ -1312,6 +1388,7 @@ currentdict /xref-char-dict undef
} ifelse
} forall
} loop % Loop to previous trailer
+ /PrevArray where {/PrevArray undef} if %% remove the array we were using to detect circular references
} if
/NumObjects Objects length def % To check that obj# < NumObjects
@@ -1584,10 +1661,32 @@ currentdict /xref-char-dict undef
{
2 copy knownoget
{ exch pop exch pop //true }
- { exch /Parent knownoget
- { exch pget }
+ {
+ %% Check to see if there's a Parent
+ 1 index
+ 3 1 roll
+ exch /Parent knownoget
+ {
+ %% If there is a Parent, check to see if this dictionary has a stored object number
+ 3 -1 roll /.gs.pdfobj# .knownget {
+ %% if it does, check the Parent as wwell
+ 1 index /.gs.pdfobj# .knownget {
+ %% Both have object numbers, are they the same (ie its self-referencing)
+ eq {
+ pop pop
+ //false
+ }{
+ exch pget
+ }ifelse
+ }{
+ pop exch pget
+ }ifelse
+ } {
+ exch pget
+ }ifelse
+ }
% finally see if the key is (misplaced) in the Root Catalog dict
- { dup Trailer /Root oget exch knownoget dup {
+ { exch pop dup Trailer /Root oget exch knownoget dup {
3 -1 roll ( **** Error: The /) pdfformaterror 50 string cvs pdfformaterror
( key is missing from the Page tree.\n) pdfformaterror
( Output may be incorrect.\n) pdfformaterror
@@ -1600,6 +1699,30 @@ currentdict /xref-char-dict undef
ifelse
} bind def
+/obj_get {
+ LocalResources 1 index knownoget {
+ dup 4 index known {
+ 3 index get
+ 0 get 4 1 roll pop pop pop
+ } if
+ } {
+ 1 index /Resources pget {
+ 1 index knownoget {
+ dup 4 index known {
+ 3 index get
+ 0 get 4 1 roll pop pop pop
+ }{
+ pop pop pop 0
+ }ifelse
+ }{
+ pop pop pop 0
+ } ifelse
+ } {
+ pop pop pop 0
+ }ifelse
+ }ifelse
+}bind def
+
% Get the value of a resource on a given page.
/rget { % <resname> <pagedict> <restype> rget <value> -true-
% <resname> <pagedict> <restype> rget -false-
@@ -2109,14 +2232,61 @@ end readonly def
/MediaBox exch get_media_box pop
} {
oforce_elems % <<pdict>> /SomeBox x0 y0 x1 y1
+ %% Complicated stuff. We need to use the 'Box' we identified (if any), but we
+ %% need to clamp the boundaries of the 'Box' to the MediaBox. This appears to
+ %% be what Acrobat does. The complication arises because the Box values don't
+ %% have to be sensibly positive, its permissible to have the MediaBox set up
+ %% so that it extends down and left instead of up and right. We take care of the
+ %% content when we st up the CTM, but we do need to make sure that we clamp
+ %% the BoundingBox, and that means we need to take direcitonality into account...
+
6 -1 roll get_media_box { % /SomeBox x0 y0 x1 y1 [MediaBox]
aload pop % /SomeBox x0 y0 x1 y1 X0 Y0 X1 Y1
- 5 -1 roll .min exch % /SomeBox x0 y0 x1 X0 Y0 mY1 X1
- 5 -1 roll .min exch % /SomeBox x0 y0 X0 Y0 mX1 mY1
- 4 2 roll % /SomeBox x0 y0 mX1 mY1 X0 Y0
- 5 -1 roll .max exch % /SomeBox x0 mX1 mY1 mY0 X0
- 5 -1 roll .max exch % /SomeBox mX1 mY1 mX0 mY0
- 4 2 roll % /SomeBox mX0 mY0 mX1 mY1
+
+ %% Start with the width, get the X0 and X1 values of the MediaBox
+ 3 index % /SomeBox x0 y0 x1 y1 X0 Y0 X1 Y1 X0
+ 2 index % /SomeBox x0 y0 x1 y1 X0 Y0 X1 Y1 X0 X1
+ gt {
+ %% Media extends to left
+ 4 -1 roll % /SomeBox x0 y0 x1 y1 Y0 X1 Y1 X0
+ 8 -1 roll % /SomeBox y0 x1 y1 Y0 X1 Y1 X0 x0
+ .min % /SomeBox y0 x1 y1 Y0 X1 Y1 mX0
+ 7 1 roll % /SomeBox mX0 y0 x1 y1 Y0 X1 Y1
+ exch % /SomeBox mX0 y0 x1 y1 Y0 Y1 X1
+ 5 -1 roll % /SomeBox mX0 y0 y1 Y0 Y1 X1 x1
+ .max % /SomeBox mX0 y0 y1 Y0 Y1 mX1
+ 5 1 roll % /SomeBox mX0 mX1 y0 y1 Y0 Y1
+ }{
+ %% Media extends to right
+ 4 -1 roll % /SomeBox x0 y0 x1 y1 Y0 X1 Y1 X0
+ 8 -1 roll % /SomeBox y0 x1 y1 Y0 X1 Y1 X0 x0
+ .max % /SomeBox y0 x1 y1 Y0 X1 Y1 mX0
+ 7 1 roll % /SomeBox mX0 y0 x1 y1 Y0 X1 Y1
+ exch % /SomeBox mX0 y0 x1 y1 Y0 Y1 X1
+ 5 -1 roll % /SomeBox mX0 y0 y1 Y0 Y1 X1 x1
+ .min % /SomeBox mX0 y0 y1 Y0 Y1 mX1
+ 5 1 roll % /SomeBox mX0 mX1 y0 y1 Y0 Y1
+ } ifelse
+
+ %% Now deal with the height
+ 2 copy % /SomeBox mX0 mX1 y0 y1 Y0 Y1 Y0 Y1
+ gt {
+ %% Media extends down
+ exch % /SomeBox mX0 mX1 y0 y1 Y1 Y0
+ 4 -1 roll % /SomeBox mX0 mX1 y1 Y1 Y0 y0
+ .min % /SomeBox mX0 mX1 y1 Y1 mY0
+ 3 1 roll % /SomeBox mX0 mX1 mY0 y1 Y1
+ .max % /SomeBox mX0 mX1 mY0 mY1
+ }{
+ %% Media extends up
+ exch % /SomeBox mX0 mX1 y0 y1 Y1 Y0
+ 4 -1 roll % /SomeBox mX0 mX1 y1 Y1 Y0 y0
+ .max % /SomeBox mX0 mX1 y1 Y1 mY0
+ 3 1 roll % /SomeBox mX0 mX1 mY0 y1 Y1
+ .min % /SomeBox mX0 mX1 mY0 mY1
+ } ifelse
+ exch % /SomeBox mX0 mX1 mY1 mY0
+ 3 1 roll % /SomeBox mX0 mY0 mX1 mY1
} {
pop
} ifelse
@@ -2268,6 +2438,37 @@ currentdict /PDF2PS_matrix_key undef
% is not actually used on the page.
currentpagedevice /PageSpotColors known { /PageSpotColors 2 index countspotcolors def } if
+ % If the user told us to use a named OutputIntent
+ systemdict /UseOutputIntent .knownget {
+ cvn
+ % Check to see if this page has such an OutputIntent
+ 2 index /OutputIntents knownoget {
+ {
+ dup /OutputConditionIdentifier get cvn
+ dup /Custom eq {
+ pop
+ dup /Info get cvn
+ }if
+ 2 index eq {
+ %% Found the required OutputIntent
+ /DestOutputProfile knownoget {
+ [ /ICCBased 3 -1 roll ] ICCBased-resolve
+ 1 get .set_outputintent
+ ()
+ } if
+ pop
+ exit
+ }{
+ pop
+ } ifelse
+ }
+ forall
+ pop
+ }{
+ pop
+ }ifelse
+ } if
+
% Let the device know if we will be using PDF 1.4 transparency.
% The clist logic may need to adjust the size of bands.
1 index pageusestransparency /PageUsesTransparency exch def
@@ -2541,7 +2742,22 @@ currentdict /PDF2PS_matrix_key undef
} {
dup //false exch {
4 dict 1 index resourceusestransparency { pop not exit } if
- /Parent knownoget not { exit } if
+ %% Check the current dictionary and its Parent (if any) to see
+ %% if they both have stored object numbers. If they do then
+ %% check the numbers, don't allow self-references.
+ dup /Parent knownoget not { pop exit }
+ {
+ exch /.gs.pdfobj# .knownget
+ {
+ 1 index /.gs.pdfobj# .knownget {
+ eq {
+ pop exit
+ }if
+ }{
+ pop
+ }ifelse
+ }if
+ } ifelse
} loop
% Also check for transparency in the annotation (if not in resources).
{ pop //true } { annotsusetransparency } ifelse
@@ -2884,74 +3100,87 @@ currentdict /PDF2PS_matrix_key undef
} if
} bind def
-%%<Objectdict> <calling obj_num> pdfform_detect_cspacesub <boolean>
+%% <loopdict> <Objectdict> <calling obj_num> pdfform_detect_cspacesub <boolean>
%%
/pdf_object_detect_cspacesub {
- exch %% <calling obj_num> <Objectdict>
- dup pdf_colorspace_detect_cspacesub {
- pop //true
- }{ %% <calling obj_num> <Objectdict>
- /Resources knownoget { %% <calling obj_num> <Resourcesdict>
- /XObject knownoget { %% <calling obj_num> <XObjectdict>
- //false exch %% <calling obj_num> <XObjectdict> false
- %% We have files where the XObject Resource is not a dictionary
- dup type /dicttype eq { %% <calling obj_num> <XObjectdict> false
-
- %% check each Xobject entry in the dictionary,
- %% forall purs a key/value pair on the stack for us.
- %%
- { %% <calling obj_num> <XObjectdict> false key value
- exch pop %% <calling obj_num> <XObjectdict> false value
-
- %% If this is an indirect reference, check if its the smae object
- %% as the current one. If its not indirect, make the object number 0
- %% for comparison purposes.
- dup type /packedarraytype eq {
- dup 0 get dup 4 index
- eq
- } {
- 0 false
- }ifelse
+ %% use loop operator for an exitable context
+ %% we need this to detect recursion/looping
+ {
+ exch %% <loopdict> <calling obj_num> <Objectdict>
+ dup pdf_colorspace_detect_cspacesub {
+ pop pop //true exit
+ }{ %% <loopdict> <calling obj_num> <Objectdict>
+ /Resources knownoget { %% <loopdict> <calling obj_num> <Resourcesdict>
+ 2 index 1 index known {
+ %% We've already seen this object, ignore it and exit
+ pop pop //false exit
+ }{
+ 2 index 1 index //null put
+ } ifelse
- %% <calling obj_num> <XObjectdict> false value <form object or 0 if not indirect> <boolean>
- not {
- %% swap object number and value, and dereference value
- exch oforce
- %% Apparently we have files where the content of the XObject Resource dictionary is null
- dup //null ne {
- %% and files where the indivudal XObjects are not dictionaries
- dup type /dicttype eq {
- dup /Subtype get /Form eq {
- exch
- pdf_object_detect_cspacesub {
- pop //true exit
- } if
- } {
+ /XObject knownoget { %% <loopdict> <calling obj_num> <XObjectdict>
+ //false exch %% <loopdict> <calling obj_num> <XObjectdict> false
+ %% We have files where the XObject Resource is not a dictionary
+ dup type /dicttype eq { %% <loopdict> <calling obj_num> <XObjectdict> false
+
+ %% check each Xobject entry in the dictionary,
+ %% forall purs a key/value pair on the stack for us.
+ %%
+ { %% <loopdict> <calling obj_num> <XObjectdict> false key value
+ exch pop %% <loopdict> <calling obj_num> <XObjectdict> false value
+
+ %% If this is an indirect reference, check if its the smae object
+ %% as the current one. If its not indirect, make the object number 0
+ %% for comparison purposes.
+ dup type /packedarraytype eq {
+ dup 0 get dup 4 index
+ eq
+ } {
+ 0 false
+ }ifelse
+
+ %% <calling obj_num> <XObjectdict> false value <form object or 0 if not indirect> <boolean>
+ not {
+ %% swap object number and value, and dereference value
+ exch oforce
+ %% Apparently we have files where the content of the XObject Resource dictionary is null
+ dup //null ne {
+ %% and files where the indivudal XObjects are not dictionaries
+ dup type /dicttype eq {
+ dup /Subtype get /Form eq {
+ exch
+ 4 index 3 1 roll pdf_object_detect_cspacesub {
+ pop //true exit
+ } if
+ } {
+ pop pop
+ }ifelse
+ }{
pop pop
- }ifelse
+ } ifelse
}{
pop pop
- } ifelse
+ }
+ ifelse
}{
pop pop
- }
- ifelse
- }{
- pop pop
- } ifelse
- } forall
- }{
- pop
+ } ifelse
+ } forall
+ }{
+ pop
+ }ifelse
+ } {
+ %% No forms, so can't be any Default* spaces
+ //false
}ifelse
} {
- %% No forms, so can't be any Default* spaces
//false
- }ifelse
- } {
- //false
+ } ifelse
} ifelse
- } ifelse
- %% Remove the calling object ID, return our boolean
+ %% Remove the calling object ID, return our boolean
+ exch pop exit
+ } loop
+ %% remove and discard the loopdict
exch pop
} bind def
@@ -2966,12 +3195,11 @@ currentdict /PDF2PS_matrix_key undef
% not using UseCIEColor with pdfwrite.
%
/pdfshowpage_detect_cspacesub {
- dup 0 pdf_object_detect_cspacesub
+ dup 0 1 dict 3 1 roll pdf_object_detect_cspacesub
/HighLevelDevice /GetDeviceParam .special_op {
exch pop not exch pop
}if
-
} bind def
%
@@ -3110,3 +3338,36 @@ currentdict /PDF2PS_matrix_key undef
end % pdfdict
.setglobal
+
+DELAYBIND not {
+%% 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.
+[
+/.pdfawidthshow /.pdfwidthshow
+/.setfillcolor /.setfillcolorspace /.setstrokecolor /.setstrokecolorspace /.currentrenderingintent /.setrenderingintent
+/.currenttextrenderingmode /.settextspacing /.currenttextspacing /.settextleading /.currenttextleading
+/.settextrise /.currenttextrise /.setwordspacing /.currentwordspacing /.settexthscaling /.currenttexthscaling
+/.settextlinematrix /.currenttextlinematrix /.currenttextmatrix /.settextmatrix /.currentblendmode
+/.currentopacityalpha /.currentshapealpha /.currenttextknockout
+/.pushextendedgstate /.popextendedgstate /.begintransparencytextgroup
+/.endtransparencytextgroup /.begintransparencymaskgroup /.begintransparencymaskimage /.endtransparencymask /.image3x
+/.abortpdf14devicefilter /.pdfinkpath /.pdfFormName /.setstrokeconstantalpha
+/.setfillconstantalpha /.setalphaisshape /.currentalphaisshape
+/.settextspacing /.currenttextspacing /.settextleading /.currenttextleading /.settextrise /.currenttextrise
+/.setwordspacing /.currentwordspacing /.settexthscaling /.currenttexthscaling
+
+% Used by our own test suite files
+%/.pushpdf14devicefilter % transparency-example.ps
+%/.poppdf14devicefilter % transparency-example.ps
+%/.setopacityalpha % transparency-example.ps
+%/.setshapealpha % transparency-example.ps
+%/.endtransparencygroup % transparency-example.ps
+
+% undefining these causes errors/incorrect output
+%/.settextrenderingmode /.setblendmode /.begintransparencygroup /.settextknockout /check_r6_password /.setstrokeoverprint /.setfilloverprint
+%/.currentstrokeoverprint /.currentfilloverprint /.currentfillconstantalpha /.currentstrokeconstantalpha
+]
+{systemdict exch .undef} forall
+} if