Commit 94b4e900b21c3ce61f55e118c570782556600490
1 parent
d54bd7b2
Add better tests for generation > 0 with object streams
This includes an expected failure for a file with a dangling reference to an old generation.
Showing
6 changed files
with
308 additions
and
44 deletions
qpdf/qtest/incremental.test
| @@ -18,7 +18,8 @@ my $n_tests = 6; | @@ -18,7 +18,8 @@ my $n_tests = 6; | ||
| 18 | 18 | ||
| 19 | # Since the beginning but discovered at the time of releasing 11.8.0: | 19 | # Since the beginning but discovered at the time of releasing 11.8.0: |
| 20 | # qpdf doesn't delete earlier generations of an object when they are | 20 | # qpdf doesn't delete earlier generations of an object when they are |
| 21 | -# reused. | 21 | +# reused. See also EXPECT_FAILURE in object-stream.test and |
| 22 | +# linearization.test. | ||
| 22 | $td->runtest("handle delete and reuse", | 23 | $td->runtest("handle delete and reuse", |
| 23 | {$td->COMMAND => "qpdf --qdf --static-id incremental-1.pdf a.pdf"}, | 24 | {$td->COMMAND => "qpdf --qdf --static-id incremental-1.pdf a.pdf"}, |
| 24 | {$td->STRING => "", $td->EXIT_STATUS => 0}, | 25 | {$td->STRING => "", $td->EXIT_STATUS => 0}, |
qpdf/qtest/linearization.test
| @@ -39,7 +39,8 @@ my @to_linearize = | @@ -39,7 +39,8 @@ my @to_linearize = | ||
| 39 | 'lin-delete-and-reuse', # linearized, then delete and reuse | 39 | 'lin-delete-and-reuse', # linearized, then delete and reuse |
| 40 | 'object-stream', # contains object streams | 40 | 'object-stream', # contains object streams |
| 41 | 'hybrid-xref', # contains both xref tables and streams | 41 | 'hybrid-xref', # contains both xref tables and streams |
| 42 | - 'gen1', # has objects with generation > 0 | 42 | + 'gen1', # has objects with generation > 0 and dangling references |
| 43 | + 'gen1-no-dangling', # has objects with generation > 0 | ||
| 43 | 'direct-outlines', # /Outlines is a direct object | 44 | 'direct-outlines', # /Outlines is a direct object |
| 44 | @linearized_files, # we should be able to relinearize | 45 | @linearized_files, # we should be able to relinearize |
| 45 | ); | 46 | ); |
| @@ -83,23 +84,29 @@ foreach my $base (@to_linearize) | @@ -83,23 +84,29 @@ foreach my $base (@to_linearize) | ||
| 83 | { | 84 | { |
| 84 | foreach my $omode (qw(disable preserve generate)) | 85 | foreach my $omode (qw(disable preserve generate)) |
| 85 | { | 86 | { |
| 87 | + my $xflags = 0; | ||
| 88 | + if ($base eq 'gen1') | ||
| 89 | + { | ||
| 90 | + $xflags = $td->EXPECT_FAILURE; | ||
| 91 | + } | ||
| 86 | my $oarg = "-object-streams=$omode"; | 92 | my $oarg = "-object-streams=$omode"; |
| 87 | my $sdarg = ""; | 93 | my $sdarg = ""; |
| 88 | if (($base eq 'lin-special') || ($base eq 'object-stream')) | 94 | if (($base eq 'lin-special') || ($base eq 'object-stream')) |
| 89 | { | 95 | { |
| 90 | $sdarg = "--stream-data=uncompress"; | 96 | $sdarg = "--stream-data=uncompress"; |
| 91 | } | 97 | } |
| 98 | + unlink "a.pdf", "b.pdf", "c.pdf"; | ||
| 92 | $td->runtest("linearize $base ($omode)", | 99 | $td->runtest("linearize $base ($omode)", |
| 93 | {$td->COMMAND => | 100 | {$td->COMMAND => |
| 94 | "qpdf -linearize $oarg $sdarg" . | 101 | "qpdf -linearize $oarg $sdarg" . |
| 95 | " --static-id $base.pdf a.pdf"}, | 102 | " --static-id $base.pdf a.pdf"}, |
| 96 | - {$td->STRING => "", | ||
| 97 | - $td->EXIT_STATUS => 0}); | 103 | + {$td->STRING => "", $td->EXIT_STATUS => 0}, |
| 104 | + $xflags); | ||
| 98 | $td->runtest("check linearization", | 105 | $td->runtest("check linearization", |
| 99 | {$td->COMMAND => "qpdf --check-linearization a.pdf"}, | 106 | {$td->COMMAND => "qpdf --check-linearization a.pdf"}, |
| 100 | {$td->STRING => "a.pdf: no linearization errors\n", | 107 | {$td->STRING => "a.pdf: no linearization errors\n", |
| 101 | $td->EXIT_STATUS => 0}, | 108 | $td->EXIT_STATUS => 0}, |
| 102 | - $td->NORMALIZE_NEWLINES); | 109 | + $td->NORMALIZE_NEWLINES | $xflags); |
| 103 | # Relinearizing twice should produce identical results. We | 110 | # Relinearizing twice should produce identical results. We |
| 104 | # have to do it twice because, if objects changed ordering | 111 | # have to do it twice because, if objects changed ordering |
| 105 | # during the original linearization, the hint tables won't | 112 | # during the original linearization, the hint tables won't |
| @@ -110,16 +117,17 @@ foreach my $base (@to_linearize) | @@ -110,16 +117,17 @@ foreach my $base (@to_linearize) | ||
| 110 | $td->runtest("relinearize $base 1", | 117 | $td->runtest("relinearize $base 1", |
| 111 | {$td->COMMAND => | 118 | {$td->COMMAND => |
| 112 | "qpdf -linearize $sdarg --static-id a.pdf b.pdf"}, | 119 | "qpdf -linearize $sdarg --static-id a.pdf b.pdf"}, |
| 113 | - {$td->STRING => "", | ||
| 114 | - $td->EXIT_STATUS => 0}); | 120 | + {$td->STRING => "", $td->EXIT_STATUS => 0}, |
| 121 | + $xflags); | ||
| 115 | $td->runtest("relinearize $base 2", | 122 | $td->runtest("relinearize $base 2", |
| 116 | {$td->COMMAND => | 123 | {$td->COMMAND => |
| 117 | "qpdf -linearize $sdarg --static-id b.pdf c.pdf"}, | 124 | "qpdf -linearize $sdarg --static-id b.pdf c.pdf"}, |
| 118 | - {$td->STRING => "", | ||
| 119 | - $td->EXIT_STATUS => 0}); | 125 | + {$td->STRING => "", $td->EXIT_STATUS => 0}, |
| 126 | + $xflags); | ||
| 120 | $td->runtest("compare files ($omode)", | 127 | $td->runtest("compare files ($omode)", |
| 121 | {$td->FILE => "b.pdf"}, | 128 | {$td->FILE => "b.pdf"}, |
| 122 | - {$td->FILE => "c.pdf"}); | 129 | + {$td->FILE => "c.pdf"}, |
| 130 | + $xflags); | ||
| 123 | if (($base eq 'lin-special') || ($base eq 'object-stream')) | 131 | if (($base eq 'lin-special') || ($base eq 'object-stream')) |
| 124 | { | 132 | { |
| 125 | $td->runtest("check $base ($omode)", | 133 | $td->runtest("check $base ($omode)", |
qpdf/qtest/object-stream.test
| @@ -16,7 +16,7 @@ cleanup(); | @@ -16,7 +16,7 @@ cleanup(); | ||
| 16 | 16 | ||
| 17 | my $td = new TestDriver('object-stream'); | 17 | my $td = new TestDriver('object-stream'); |
| 18 | 18 | ||
| 19 | -my $n_tests = 5 + (36 * 4) + (12 * 2); | 19 | +my $n_tests = 7 + (36 * 4) + (12 * 2); |
| 20 | my $n_compare_pdfs = 36; | 20 | my $n_compare_pdfs = 36; |
| 21 | 21 | ||
| 22 | for (my $n = 16; $n <= 19; ++$n) | 22 | for (my $n = 16; $n <= 19; ++$n) |
| @@ -82,8 +82,22 @@ $td->runtest("generate object streams for gen > 0", | @@ -82,8 +82,22 @@ $td->runtest("generate object streams for gen > 0", | ||
| 82 | {$td->COMMAND => "qpdf --qdf --static-id" . | 82 | {$td->COMMAND => "qpdf --qdf --static-id" . |
| 83 | " --object-streams=generate gen1.pdf a.pdf"}, | 83 | " --object-streams=generate gen1.pdf a.pdf"}, |
| 84 | {$td->STRING => "", $td->EXIT_STATUS => 0}); | 84 | {$td->STRING => "", $td->EXIT_STATUS => 0}); |
| 85 | +# qpdf 11.8.0 -- it was discovered that qpdf was incorrectly handling | ||
| 86 | +# references to older generations of reused objects in incrementally | ||
| 87 | +# updated files. | ||
| 85 | $td->runtest("check file", | 88 | $td->runtest("check file", |
| 86 | {$td->FILE => "a.pdf"}, | 89 | {$td->FILE => "a.pdf"}, |
| 90 | + {$td->FILE => "gen1.qdf"}, | ||
| 91 | + $td->EXPECT_FAILURE); | ||
| 92 | + | ||
| 93 | +$td->runtest("generate object streams for gen > 0", | ||
| 94 | + {$td->COMMAND => "qpdf --qdf --static-id" . | ||
| 95 | + " --object-streams=generate gen1-no-dangling.pdf a.pdf"}, | ||
| 96 | + {$td->STRING => "", $td->EXIT_STATUS => 0}); | ||
| 97 | +$td->runtest("check file", | ||
| 98 | + {$td->FILE => "a.pdf"}, | ||
| 99 | + # Intentionally compare against gen1.pdf -- should have | ||
| 100 | + # the same results as above. | ||
| 87 | {$td->FILE => "gen1.qdf"}); | 101 | {$td->FILE => "gen1.qdf"}); |
| 88 | 102 | ||
| 89 | 103 |
qpdf/qtest/qpdf/gen1-no-dangling.pdf
0 โ 100644
| 1 | +%PDF-1.3 | ||
| 2 | +%ยฟรทยขรพ | ||
| 3 | +%QDF-1.0 | ||
| 4 | + | ||
| 5 | +1 0 obj | ||
| 6 | +<< | ||
| 7 | + /Pages 2 0 R | ||
| 8 | + /Type /Catalog | ||
| 9 | +>> | ||
| 10 | +endobj | ||
| 11 | + | ||
| 12 | +2 0 obj | ||
| 13 | +<< | ||
| 14 | + /Count 1 | ||
| 15 | + /Kids [ | ||
| 16 | + 3 0 R | ||
| 17 | + ] | ||
| 18 | + /Type /Pages | ||
| 19 | +>> | ||
| 20 | +endobj | ||
| 21 | + | ||
| 22 | +%% Page 1 | ||
| 23 | +3 0 obj | ||
| 24 | +<< | ||
| 25 | + /Contents 4 0 R | ||
| 26 | + /MediaBox [ | ||
| 27 | + 0 | ||
| 28 | + 0 | ||
| 29 | + 612 | ||
| 30 | + 792 | ||
| 31 | + ] | ||
| 32 | + /Parent 2 0 R | ||
| 33 | + /Resources 6 0 R | ||
| 34 | + /Type /Page | ||
| 35 | +>> | ||
| 36 | +endobj | ||
| 37 | + | ||
| 38 | +%% Contents for page 1 | ||
| 39 | +4 0 obj | ||
| 40 | +<< | ||
| 41 | + /Length 5 0 R | ||
| 42 | +>> | ||
| 43 | +stream | ||
| 44 | +BT | ||
| 45 | + /F1 24 Tf | ||
| 46 | + 72 720 Td | ||
| 47 | + (Potato) Tj | ||
| 48 | +ET | ||
| 49 | +endstream | ||
| 50 | +endobj | ||
| 51 | + | ||
| 52 | +5 0 obj | ||
| 53 | +44 | ||
| 54 | +endobj | ||
| 55 | + | ||
| 56 | +6 0 obj | ||
| 57 | +<< | ||
| 58 | + /Font 7 0 R | ||
| 59 | + %ProcSet 8 0 R | ||
| 60 | +>> | ||
| 61 | +endobj | ||
| 62 | + | ||
| 63 | +7 0 obj | ||
| 64 | +<< | ||
| 65 | + /F1 9 0 R | ||
| 66 | +>> | ||
| 67 | +endobj | ||
| 68 | + | ||
| 69 | +8 0 obj | ||
| 70 | +[ | ||
| 71 | |||
| 72 | + /Text | ||
| 73 | +] | ||
| 74 | +endobj | ||
| 75 | + | ||
| 76 | +9 0 obj | ||
| 77 | +<< | ||
| 78 | + /BaseFont /Helvetica | ||
| 79 | + /Encoding /WinAnsiEncoding | ||
| 80 | + /Name /F1 | ||
| 81 | + /Subtype /Type1 | ||
| 82 | + /Type /Font | ||
| 83 | +>> | ||
| 84 | +endobj | ||
| 85 | + | ||
| 86 | +xref | ||
| 87 | +0 10 | ||
| 88 | +0000000000 65535 f | ||
| 89 | +0000000025 00000 n | ||
| 90 | +0000000079 00000 n | ||
| 91 | +0000000161 00000 n | ||
| 92 | +0000000319 00000 n | ||
| 93 | +0000000418 00000 n | ||
| 94 | +0000000437 00000 n | ||
| 95 | +0000000490 00000 n | ||
| 96 | +0000000524 00000 n | ||
| 97 | +0000000559 00000 n | ||
| 98 | +trailer << | ||
| 99 | + /Root 1 0 R | ||
| 100 | + /Size 10 | ||
| 101 | + /ID [<6b7a9692034323b8032e358b75d57a4c><44f7cee2c1913f0970a8a391cd03f327>] | ||
| 102 | +>> | ||
| 103 | +startxref | ||
| 104 | +677 | ||
| 105 | +%%EOF | ||
| 106 | + | ||
| 107 | +% Delete object 8. | ||
| 108 | +xref | ||
| 109 | +0 1 | ||
| 110 | +0000000008 65535 f | ||
| 111 | +8 1 | ||
| 112 | +0000000000 00001 f | ||
| 113 | +trailer << | ||
| 114 | + /Root 1 0 R | ||
| 115 | + /Size 10 | ||
| 116 | + /Prev 677 | ||
| 117 | + /ID [<6b7a9692034323b8032e358b75d57a4c><44f7cee2c1913f0970a8a391cd03f327>] | ||
| 118 | +>> | ||
| 119 | +startxref | ||
| 120 | +1043 | ||
| 121 | +%%EOF | ||
| 122 | + | ||
| 123 | +% Reuse object 8 such that we have to traverse through it to get to a | ||
| 124 | +% compressible object. | ||
| 125 | +7 0 obj | ||
| 126 | +<< | ||
| 127 | + /F1 8 1 R | ||
| 128 | +>> | ||
| 129 | +endobj | ||
| 130 | + | ||
| 131 | +8 1 obj | ||
| 132 | +<< | ||
| 133 | + /BaseFont 9 0 R | ||
| 134 | + /Encoding /WinAnsiEncoding | ||
| 135 | + /Name /F1 | ||
| 136 | + /Subtype /Type1 | ||
| 137 | + /Type /Font | ||
| 138 | +>> | ||
| 139 | +endobj | ||
| 140 | + | ||
| 141 | +9 0 obj | ||
| 142 | +/Times-Roman | ||
| 143 | +endobj | ||
| 144 | + | ||
| 145 | +xref | ||
| 146 | +0 1 | ||
| 147 | +0000000000 65535 f | ||
| 148 | +7 3 | ||
| 149 | +0000001339 00000 n | ||
| 150 | +0000001373 00001 n | ||
| 151 | +0000001486 00000 n | ||
| 152 | +trailer << | ||
| 153 | + /Root 1 0 R | ||
| 154 | + /Size 10 | ||
| 155 | + /Prev 1043 | ||
| 156 | + /ID [<6b7a9692034323b8032e358b75d57a4c><44f7cee2c1913f0970a8a391cd03f327>] | ||
| 157 | +>> | ||
| 158 | +startxref | ||
| 159 | +1515 | ||
| 160 | +%%EOF |
qpdf/qtest/qpdf/gen1.pdf
| 1 | %PDF-1.3 | 1 | %PDF-1.3 |
| 2 | -1 1 obj | 2 | +%ยฟรทยขรพ |
| 3 | +%QDF-1.0 | ||
| 4 | + | ||
| 5 | +1 0 obj | ||
| 3 | << | 6 | << |
| 7 | + /Pages 2 0 R | ||
| 4 | /Type /Catalog | 8 | /Type /Catalog |
| 5 | - /Pages 2 1 R | ||
| 6 | >> | 9 | >> |
| 7 | endobj | 10 | endobj |
| 8 | 11 | ||
| 9 | -2 1 obj | 12 | +2 0 obj |
| 10 | << | 13 | << |
| 11 | - /Type /Pages | 14 | + /Count 1 |
| 12 | /Kids [ | 15 | /Kids [ |
| 13 | - 3 1 R | 16 | + 3 0 R |
| 14 | ] | 17 | ] |
| 15 | - /Count 1 | 18 | + /Type /Pages |
| 16 | >> | 19 | >> |
| 17 | endobj | 20 | endobj |
| 18 | 21 | ||
| 19 | -3 1 obj | 22 | +%% Page 1 |
| 23 | +3 0 obj | ||
| 20 | << | 24 | << |
| 25 | + /Contents 4 0 R | ||
| 26 | + /MediaBox [ | ||
| 27 | + 0 | ||
| 28 | + 0 | ||
| 29 | + 612 | ||
| 30 | + 792 | ||
| 31 | + ] | ||
| 32 | + /Parent 2 0 R | ||
| 33 | + /Resources 6 0 R | ||
| 21 | /Type /Page | 34 | /Type /Page |
| 22 | - /Parent 2 1 R | ||
| 23 | - /MediaBox [0 0 612 792] | ||
| 24 | - /Contents 4 1 R | ||
| 25 | - /Resources << | ||
| 26 | - /ProcSet 5 1 R | ||
| 27 | - /Font << | ||
| 28 | - /F1 6 1 R | ||
| 29 | - >> | ||
| 30 | - >> | ||
| 31 | >> | 35 | >> |
| 32 | endobj | 36 | endobj |
| 33 | 37 | ||
| 34 | -4 1 obj | 38 | +%% Contents for page 1 |
| 39 | +4 0 obj | ||
| 35 | << | 40 | << |
| 36 | - /Length 44 | 41 | + /Length 5 0 R |
| 37 | >> | 42 | >> |
| 38 | stream | 43 | stream |
| 39 | BT | 44 | BT |
| @@ -44,36 +49,112 @@ ET | @@ -44,36 +49,112 @@ ET | ||
| 44 | endstream | 49 | endstream |
| 45 | endobj | 50 | endobj |
| 46 | 51 | ||
| 47 | -5 1 obj | 52 | +5 0 obj |
| 53 | +44 | ||
| 54 | +endobj | ||
| 55 | + | ||
| 56 | +6 0 obj | ||
| 57 | +<< | ||
| 58 | + /Font 7 0 R | ||
| 59 | + /ProcSet 8 0 R | ||
| 60 | +>> | ||
| 61 | +endobj | ||
| 62 | + | ||
| 63 | +7 0 obj | ||
| 64 | +<< | ||
| 65 | + /F1 9 0 R | ||
| 66 | +>> | ||
| 67 | +endobj | ||
| 68 | + | ||
| 69 | +8 0 obj | ||
| 48 | [ | 70 | [ |
| 49 | 71 | ||
| 50 | /Text | 72 | /Text |
| 51 | ] | 73 | ] |
| 52 | endobj | 74 | endobj |
| 53 | 75 | ||
| 54 | -6 1 obj | 76 | +9 0 obj |
| 55 | << | 77 | << |
| 56 | - /Type /Font | ||
| 57 | - /Subtype /Type1 | ||
| 58 | - /Name /F1 | ||
| 59 | /BaseFont /Helvetica | 78 | /BaseFont /Helvetica |
| 60 | /Encoding /WinAnsiEncoding | 79 | /Encoding /WinAnsiEncoding |
| 80 | + /Name /F1 | ||
| 81 | + /Subtype /Type1 | ||
| 82 | + /Type /Font | ||
| 61 | >> | 83 | >> |
| 62 | endobj | 84 | endobj |
| 63 | 85 | ||
| 64 | xref | 86 | xref |
| 65 | -0 7 | 87 | +0 10 |
| 88 | +0000000000 65535 f | ||
| 89 | +0000000025 00000 n | ||
| 90 | +0000000079 00000 n | ||
| 91 | +0000000161 00000 n | ||
| 92 | +0000000319 00000 n | ||
| 93 | +0000000418 00000 n | ||
| 94 | +0000000437 00000 n | ||
| 95 | +0000000490 00000 n | ||
| 96 | +0000000524 00000 n | ||
| 97 | +0000000559 00000 n | ||
| 98 | +trailer << | ||
| 99 | + /Root 1 0 R | ||
| 100 | + /Size 10 | ||
| 101 | + /ID [<6b7a9692034323b8032e358b75d57a4c><44f7cee2c1913f0970a8a391cd03f327>] | ||
| 102 | +>> | ||
| 103 | +startxref | ||
| 104 | +677 | ||
| 105 | +%%EOF | ||
| 106 | + | ||
| 107 | +% Delete object 8. | ||
| 108 | +xref | ||
| 109 | +0 1 | ||
| 110 | +0000000008 65535 f | ||
| 111 | +8 1 | ||
| 112 | +0000000000 00001 f | ||
| 113 | +trailer << | ||
| 114 | + /Root 1 0 R | ||
| 115 | + /Size 10 | ||
| 116 | + /Prev 677 | ||
| 117 | + /ID [<6b7a9692034323b8032e358b75d57a4c><44f7cee2c1913f0970a8a391cd03f327>] | ||
| 118 | +>> | ||
| 119 | +startxref | ||
| 120 | +1043 | ||
| 121 | +%%EOF | ||
| 122 | + | ||
| 123 | +% Reuse object 8 such that we have to traverse through it to get to a | ||
| 124 | +% compressible object. | ||
| 125 | +7 0 obj | ||
| 126 | +<< | ||
| 127 | + /F1 8 1 R | ||
| 128 | +>> | ||
| 129 | +endobj | ||
| 130 | + | ||
| 131 | +8 1 obj | ||
| 132 | +<< | ||
| 133 | + /BaseFont 9 0 R | ||
| 134 | + /Encoding /WinAnsiEncoding | ||
| 135 | + /Name /F1 | ||
| 136 | + /Subtype /Type1 | ||
| 137 | + /Type /Font | ||
| 138 | +>> | ||
| 139 | +endobj | ||
| 140 | + | ||
| 141 | +9 0 obj | ||
| 142 | +/Times-Roman | ||
| 143 | +endobj | ||
| 144 | + | ||
| 145 | +xref | ||
| 146 | +0 1 | ||
| 66 | 0000000000 65535 f | 147 | 0000000000 65535 f |
| 67 | -0000000009 00001 n | ||
| 68 | -0000000063 00001 n | ||
| 69 | -0000000135 00001 n | ||
| 70 | -0000000307 00001 n | ||
| 71 | -0000000403 00001 n | ||
| 72 | -0000000438 00001 n | 148 | +7 3 |
| 149 | +0000001339 00000 n | ||
| 150 | +0000001373 00001 n | ||
| 151 | +0000001486 00000 n | ||
| 73 | trailer << | 152 | trailer << |
| 74 | - /Size 7 | ||
| 75 | - /Root 1 1 R | 153 | + /Root 1 0 R |
| 154 | + /Size 10 | ||
| 155 | + /Prev 1043 | ||
| 156 | + /ID [<6b7a9692034323b8032e358b75d57a4c><44f7cee2c1913f0970a8a391cd03f327>] | ||
| 76 | >> | 157 | >> |
| 77 | startxref | 158 | startxref |
| 78 | -556 | 159 | +1515 |
| 79 | %%EOF | 160 | %%EOF |
qpdf/qtest/qpdf/gen1.qdf
No preview for this file type