Commit b356b9dfa2fd1b1d15cbd09720d6d8185fa613e5

Authored by Jay Berkenbilt
1 parent cf43882e

fix-qdf: handle object streams with > 255 objects

fix-qdf was previously hard-coding the number of bytes for the f2
field of the xref stream entry. This addresses issue #37. Thanks
aluebcke for reporting.
ChangeLog
1 2015-05-24 Jay Berkenbilt <ejb@ql.org> 1 2015-05-24 Jay Berkenbilt <ejb@ql.org>
2 2
  3 + * Bug fix: fix-qdf was not handling object streams with more than
  4 + 255 objects in them.
  5 +
3 * Handle Microsoft crypt provider initialization properly for case 6 * Handle Microsoft crypt provider initialization properly for case
4 where no keys have been previously created, such as in a fresh 7 where no keys have been previously created, such as in a fresh
5 Windows installation. 8 Windows installation.
qpdf/fix-qdf
@@ -53,6 +53,7 @@ my $stream_start = 0; @@ -53,6 +53,7 @@ my $stream_start = 0;
53 my $stream_length = 0; 53 my $stream_length = 0;
54 my $xref_offset = 0; 54 my $xref_offset = 0;
55 my $xref_f1_nbytes = 0; 55 my $xref_f1_nbytes = 0;
  56 +my $xref_f2_nbytes = 0;
56 my $xref_size = 0; 57 my $xref_size = 0;
57 58
58 my $cur_state = 0; 59 my $cur_state = 0;
@@ -122,11 +123,28 @@ while (defined($line = get_line())) @@ -122,11 +123,28 @@ while (defined($line = get_line()))
122 $t >>= 8; 123 $t >>= 8;
123 ++$xref_f1_nbytes; 124 ++$xref_f1_nbytes;
124 } 125 }
125 - my $esize = $xref_f1_nbytes + 2; 126 + # Figure out how many bytes we need for ostream index.
  127 + # Make sure we get at least 1 byte even if there are no
  128 + # object streams.
  129 + my $max_objects = 1;
  130 + foreach my $e (@xref)
  131 + {
  132 + my ($type, $f1, $f2) = @$e;
  133 + if ((defined $f2) && ($f2 > $max_objects))
  134 + {
  135 + $max_objects = $f2;
  136 + }
  137 + }
  138 + while ($max_objects)
  139 + {
  140 + $max_objects >>=8;
  141 + ++$xref_f2_nbytes;
  142 + }
  143 + my $esize = 1 + $xref_f1_nbytes + $xref_f2_nbytes;
126 $xref_size = 1 + @xref; 144 $xref_size = 1 + @xref;
127 my $length = $xref_size * $esize; 145 my $length = $xref_size * $esize;
128 print " /Length $length\n"; 146 print " /Length $length\n";
129 - print " /W [ 1 $xref_f1_nbytes 1 ]\n"; 147 + print " /W [ 1 $xref_f1_nbytes $xref_f2_nbytes ]\n";
130 $state = $st_in_xref_stream_dict; 148 $state = $st_in_xref_stream_dict;
131 } 149 }
132 } 150 }
@@ -200,19 +218,25 @@ while (defined($line = get_line())) @@ -200,19 +218,25 @@ while (defined($line = get_line()))
200 } 218 }
201 if ($line =~ m/^stream\n/) 219 if ($line =~ m/^stream\n/)
202 { 220 {
203 - my $pack = "(C C$xref_f1_nbytes C)"; 221 + my $pack = "(C C$xref_f1_nbytes C$xref_f2_nbytes)";
204 print pack($pack, 0, 0, 0); 222 print pack($pack, 0, 0, 0);
205 foreach my $x (@xref) 223 foreach my $x (@xref)
206 { 224 {
207 my ($type, $f1, $f2) = @$x; 225 my ($type, $f1, $f2) = @$x;
208 $f2 = 0 unless defined $f2; 226 $f2 = 0 unless defined $f2;
209 - my @f1 = ();  
210 - for (my $i = 0; $i < $xref_f1_nbytes; ++$i)  
211 - {  
212 - unshift(@f1, $f1 & 0xff);  
213 - $f1 >>= 8;  
214 - }  
215 - print pack($pack, $type, @f1, $f2); 227 + my @f1 = ();
  228 + my @f2 = ();
  229 + foreach my $d ([\@f1, $f1, $xref_f1_nbytes],
  230 + [\@f2, $f2, $xref_f2_nbytes])
  231 + {
  232 + my ($fa, $f, $nbytes) = @$d;
  233 + for (my $i = 0; $i < $nbytes; ++$i)
  234 + {
  235 + unshift(@$fa, $f & 0xff);
  236 + $f >>= 8;
  237 + }
  238 + }
  239 + print pack($pack, $type, @f1, @f2);
216 } 240 }
217 print "\nendstream\nendobj\n\n"; 241 print "\nendstream\nendobj\n\n";
218 print "startxref\n$xref_offset\n\%\%EOF\n"; 242 print "startxref\n$xref_offset\n\%\%EOF\n";
qpdf/qtest/qpdf.test
@@ -1993,7 +1993,7 @@ compare_pdfs(&quot;inline-images-cr.pdf&quot;, &quot;a.pdf&quot;); @@ -1993,7 +1993,7 @@ compare_pdfs(&quot;inline-images-cr.pdf&quot;, &quot;a.pdf&quot;);
1993 show_ntests(); 1993 show_ntests();
1994 # ---------- 1994 # ----------
1995 $td->notify("--- fix-qdf Tests ---"); 1995 $td->notify("--- fix-qdf Tests ---");
1996 -$n_tests += 4; 1996 +$n_tests += 5;
1997 1997
1998 for (my $n = 1; $n <= 2; ++$n) 1998 for (my $n = 1; $n <= 2; ++$n)
1999 { 1999 {
@@ -2007,6 +2007,10 @@ for (my $n = 1; $n &lt;= 2; ++$n) @@ -2007,6 +2007,10 @@ for (my $n = 1; $n &lt;= 2; ++$n)
2007 {$td->FILE => "fix$n.qdf.out", 2007 {$td->FILE => "fix$n.qdf.out",
2008 $td->EXIT_STATUS => 0}); 2008 $td->EXIT_STATUS => 0});
2009 } 2009 }
  2010 +$td->runtest("fix-qdf with big object stream", # > 255 objects in a stream
  2011 + {$td->COMMAND => "fix-qdf big-ostream.pdf"},
  2012 + {$td->FILE => "big-ostream.pdf",
  2013 + $td->EXIT_STATUS => 0});
2010 2014
2011 show_ntests(); 2015 show_ntests();
2012 # ---------- 2016 # ----------
qpdf/qtest/qpdf/big-ostream.pdf 0 → 100644
No preview for this file type