[gs-cvs] rev 6979 - trunk/gs/lib

dan at ghostscript.com dan at ghostscript.com
Tue Aug 8 17:32:13 PDT 2006


Author: dan
Date: 2006-08-08 17:32:12 -0700 (Tue, 08 Aug 2006)
New Revision: 6979

Modified:
   trunk/gs/lib/pdf_main.ps
   trunk/gs/lib/pdf_rbld.ps
Log:
Fix for 688822 failure to repair broken xref table.

DETAILS:

The given test file has problems.  The file was not mangled.  the
application that created the file has some problems.  However Acrobat
7.0 is able to display the file.

The file does not specify the application which created the file.

The file misspells the key word startxref (it says startref).  The
xref location is given as 54593016.  The file only has 2,210,991 bytes.
The the location is off by over a factor of 20.

The fix consists of making the xref rebuild logic tolerant of the
misspelling and verifying that the given xref location is within the
file.


Modified: trunk/gs/lib/pdf_main.ps
===================================================================
--- trunk/gs/lib/pdf_main.ps	2006-08-09 00:17:29 UTC (rev 6978)
+++ trunk/gs/lib/pdf_main.ps	2006-08-09 00:32:12 UTC (rev 6979)
@@ -218,6 +218,7 @@
 %  /null null		% ibid.
   /R { /resolveR cvx 3 packedarray cvx } bind	% see Objects below
   /startxref /exit load
+  /startref /exit load	% Some application (unknown) misspells startxref
 .dicttomark readonly def
 
 % Because of EOL conversion, lines with fixed contents might be followed
@@ -406,7 +407,14 @@
 % entry in the prior trailer dictionary.
 /readxref		% <pos> readxref <trailerdict>
  {
-   PDFoffset add PDFfile exch setfileposition
+   PDFoffset add PDFfile exch
+   % Check that the given location is within the file.
+   dup PDFfilelen gt {
+       (   **** Warning:  Specified xref location is beyond end of file.\n)
+       pdfformaterror
+       /readxref cvx /invalidaccess signalerror
+   } if
+   setfileposition
 		% In some PDF files, this position actually points to
 		% white space before the xref line.  Skip over this here.
    {
@@ -467,7 +475,7 @@
 % Verify that each entry in the xref table is pointing at an object with
 % the correct object number and generation number.
 /verify_xref				% - verify_xref -
-{ PDFfile dup 0 setfileposition bytesavailable	% Determine the size of the file
+{ PDFfilelen
   1 1 Objects llength 1 sub	% stack: filesize 1 1 <number of objects - 1>
   {	% Check if the object is free (i.e. not used).  The values in
 	% Generations is the generation number plus 1.  If the value in

Modified: trunk/gs/lib/pdf_rbld.ps
===================================================================
--- trunk/gs/lib/pdf_rbld.ps	2006-08-09 00:17:29 UTC (rev 6978)
+++ trunk/gs/lib/pdf_rbld.ps	2006-08-09 00:32:12 UTC (rev 6979)
@@ -194,13 +194,23 @@
   % read block of data
   dup string 0 1 4 -1 roll 1 sub { 2 copy PDFfile read pop put pop } for
   % search for last occurance of 'startxref'
-  (startxref) { search not { exit } if pop } loop
-  % determine where the trailer is in the file
-  %   trailer loc = end loc - remaing string length
-  length sub 9 sub
-  % move the file to this position and read startxref and position
-  PDFfile exch setfileposition
-  PDFfile token pop pop PDFfile token pop
+  false				% Assume that startxref not present
+  exch (startxref) { 
+     search not { exit } if	% Exit loop when no more startxref's
+     pop 3 -1 roll pop true 3 1 roll	% Idicate that we have found starxref
+  } loop
+  exch				% Exch last string and 'found' flag
+  { 
+     % determine where the startxref is in the file
+     %   'startxref' loc = end loc - remaing string length - 9 bytes
+     length sub 9 sub
+     % move the file to this position and read startxref and position
+     PDFfile exch setfileposition PDFfile token
+     pop pop PDFfile token pop
+  } {
+     % startxref not found.  We will search the end of the file for trailer.
+     pop pop PDFfilelen
+  } ifelse
   % compare xref position to 1/2 the length of the file and search for trailer
   exch 2 div lt { search_start_trailer } { search_end_trailer } ifelse
   % get the trailer
@@ -215,8 +225,7 @@
 % stuff when we are scanning for objects.
 /determine_post_eof_count		% - determine_post_eof_count <count>
 { % Position to read block of data from the end of the file. 
-  PDFfile 0 setfileposition
-  PDFfile bytesavailable	% size of file
+  PDFfilelen			% size of file
   dup 4096 .min			% block size to read
   % stack: <file size> <file size> <block size>
   % move file position to the start of the block



More information about the gs-cvs mailing list