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 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 6 * Handle Microsoft crypt provider initialization properly for case
4 7 where no keys have been previously created, such as in a fresh
5 8 Windows installation.
... ...
qpdf/fix-qdf
... ... @@ -53,6 +53,7 @@ my $stream_start = 0;
53 53 my $stream_length = 0;
54 54 my $xref_offset = 0;
55 55 my $xref_f1_nbytes = 0;
  56 +my $xref_f2_nbytes = 0;
56 57 my $xref_size = 0;
57 58  
58 59 my $cur_state = 0;
... ... @@ -122,11 +123,28 @@ while (defined($line = get_line()))
122 123 $t >>= 8;
123 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 144 $xref_size = 1 + @xref;
127 145 my $length = $xref_size * $esize;
128 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 148 $state = $st_in_xref_stream_dict;
131 149 }
132 150 }
... ... @@ -200,19 +218,25 @@ while (defined($line = get_line()))
200 218 }
201 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 222 print pack($pack, 0, 0, 0);
205 223 foreach my $x (@xref)
206 224 {
207 225 my ($type, $f1, $f2) = @$x;
208 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 241 print "\nendstream\nendobj\n\n";
218 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 1993 show_ntests();
1994 1994 # ----------
1995 1995 $td->notify("--- fix-qdf Tests ---");
1996   -$n_tests += 4;
  1996 +$n_tests += 5;
1997 1997  
1998 1998 for (my $n = 1; $n <= 2; ++$n)
1999 1999 {
... ... @@ -2007,6 +2007,10 @@ for (my $n = 1; $n &lt;= 2; ++$n)
2007 2007 {$td->FILE => "fix$n.qdf.out",
2008 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 2015 show_ntests();
2012 2016 # ----------
... ...
qpdf/qtest/qpdf/big-ostream.pdf 0 → 100644
No preview for this file type