Commit b356b9dfa2fd1b1d15cbd09720d6d8185fa613e5
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.
Showing
4 changed files
with
2249 additions
and
11 deletions
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("inline-images-cr.pdf", "a.pdf"); |
| 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 <= 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