Commit 94b4e900b21c3ce61f55e118c570782556600490

Authored by Jay Berkenbilt
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.
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-&gt;runtest(&quot;generate object streams for gen &gt; 0&quot;, @@ -82,8 +82,22 @@ $td-&gt;runtest(&quot;generate object streams for gen &gt; 0&quot;,
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 + /PDF
  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 /PDF 71 /PDF
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