Commit 6d4e3ba8a43d8a084a94f9cea4669cb35812fb67

Authored by Jay Berkenbilt
1 parent 5a2aa594

Test (and fix) handling of dangling references

libqpdf/QPDF_json.cc
... ... @@ -147,6 +147,7 @@ QPDF::JSONReactor::arrayStart()
147 147 void
148 148 QPDF::JSONReactor::containerEnd(JSON const& value)
149 149 {
  150 + auto from_state = state;
150 151 state = state_stack.back();
151 152 state_stack.pop_back();
152 153 if (state == st_initial) {
... ... @@ -215,10 +216,13 @@ QPDF::JSONReactor::containerEnd(JSON const& value)
215 216 if (!parse_error) {
216 217 object_stack.pop_back();
217 218 }
218   - } else if (state == st_qpdf) {
  219 + } else if ((state == st_top) && (from_state == st_qpdf)) {
219 220 for (auto const& og: this->reserved) {
220   - // QXXXQ
221   - // QTC::TC("qpdf", "QPDF_json non-trivial null reserved");
  221 + // Handle dangling indirect object references which the
  222 + // PDF spec says to treat as nulls. It's tempting to make
  223 + // this an error, but that would be wrong since valid
  224 + // input files may have these.
  225 + QTC::TC("qpdf", "QPDF_json non-trivial null reserved");
222 226 this->pdf.replaceObject(og, QPDFObjectHandle::newNull());
223 227 }
224 228 this->reserved.clear();
... ...
qpdf/qpdf.testcov
... ... @@ -675,3 +675,4 @@ QPDF_json ignore second-level key 0
675 675 QPDF_json ignore unknown key in object_top 0
676 676 QPDF_json ignore unknown key in trailer 0
677 677 QPDF_json ignore unknown key in stream 0
  678 +QPDF_json non-trivial null reserved 0
... ...
qpdf/qtest/qpdf/good13.out
1 1 /QTest is indirect and has type dictionary (9)
2 2 /QTest is a dictionary
  3 + /dangling-ref-for-json-test is direct
3 4 /hex strings is direct
4 5 /indirect is indirect
5 6 /names is direct
6 7 /nesting is direct
7 8 /strings is direct
8 9 unparse: 7 0 R
9   -unparseResolved: << /hex#20strings [ (Potato) <01020300040560> (AB) ] /indirect 8 0 R /names [ /nesting /hex#20strings /text#2fplain ] /nesting << /a [ 1 2 << /x (y) >> [ (z) ] ] /b << / (legal) /a [ 1 2 ] >> >> /strings [ (one) <24a2> () (\(\)) (\() (\)) (a\f\b\t\r\nb) (") ("") ("\("\)") <410042> (a\nb) (a b) <efbbbfcf80> <efbbbff09fa594> ] >>
  10 +unparseResolved: << /dangling-ref-for-json-test [ 9 0 R ] /hex#20strings [ (Potato) <01020300040560> (AB) ] /indirect 8 0 R /names [ /nesting /hex#20strings /text#2fplain ] /nesting << /a [ 1 2 << /x (y) >> [ (z) ] ] /b << / (legal) /a [ 1 2 ] >> >> /strings [ (one) <24a2> () (\(\)) (\() (\)) (a\f\b\t\r\nb) (") ("") ("\("\)") <410042> (a\nb) (a b) <efbbbfcf80> <efbbbff09fa594> ] >>
10 11 test 1 done
... ...
qpdf/qtest/qpdf/good13.pdf
... ... @@ -74,6 +74,7 @@ b) (π) (🥔)]
74 74 /b <</a [1 2] / (legal)>>
75 75 >>
76 76 /names [/n#65sting /hex#20strings /text#2fplain]
  77 + /dangling-ref-for-json-test [9 0 R]
77 78 >>
78 79 endobj
79 80  
... ... @@ -81,6 +82,12 @@ endobj
81 82 (hello)
82 83 endobj
83 84  
  85 +% NOTE:
  86 +%
  87 +% If adding a new object, update /dangling-ref-for-json-test to point
  88 +% to something that's not here.
  89 +%
  90 +
84 91 xref
85 92 0 9
86 93 0000000000 65535 f
... ... @@ -91,12 +98,12 @@ xref
91 98 0000000403 00000 n
92 99 0000000438 00000 n
93 100 0000000556 00000 n
94   -0000000908 00000 n
  101 +0000000946 00000 n
95 102 trailer <<
96 103 /Size 9
97 104 /Root 1 0 R
98 105 /QTest 7 0 R
99 106 >>
100 107 startxref
101   -932
  108 +1085
102 109 %%EOF
... ...
qpdf/qtest/qpdf/good13.qdf
... ... @@ -13,12 +13,15 @@ endobj
13 13 %% Original object ID: 7 0
14 14 2 0 obj
15 15 <<
  16 + /dangling-ref-for-json-test [
  17 + 4 0 R
  18 + ]
16 19 /hex#20strings [
17 20 (Potato)
18 21 <01020300040560>
19 22 (AB)
20 23 ]
21   - /indirect 4 0 R
  24 + /indirect 5 0 R
22 25 /names [
23 26 /nesting
24 27 /hex#20strings
... ... @@ -68,22 +71,27 @@ endobj
68 71 <<
69 72 /Count 1
70 73 /Kids [
71   - 5 0 R
  74 + 6 0 R
72 75 ]
73 76 /Type /Pages
74 77 >>
75 78 endobj
76 79  
77   -%% Original object ID: 8 0
  80 +%% Original object ID: 9 0
78 81 4 0 obj
  82 +null
  83 +endobj
  84 +
  85 +%% Original object ID: 8 0
  86 +5 0 obj
79 87 (hello)
80 88 endobj
81 89  
82 90 %% Page 1
83 91 %% Original object ID: 3 0
84   -5 0 obj
  92 +6 0 obj
85 93 <<
86   - /Contents 6 0 R
  94 + /Contents 7 0 R
87 95 /MediaBox [
88 96 0
89 97 0
... ... @@ -93,9 +101,9 @@ endobj
93 101 /Parent 3 0 R
94 102 /Resources <<
95 103 /Font <<
96   - /F1 8 0 R
  104 + /F1 9 0 R
97 105 >>
98   - /ProcSet 9 0 R
  106 + /ProcSet 10 0 R
99 107 >>
100 108 /Type /Page
101 109 >>
... ... @@ -103,9 +111,9 @@ endobj
103 111  
104 112 %% Contents for page 1
105 113 %% Original object ID: 4 0
106   -6 0 obj
  114 +7 0 obj
107 115 <<
108   - /Length 7 0 R
  116 + /Length 8 0 R
109 117 >>
110 118 stream
111 119 BT
... ... @@ -116,12 +124,12 @@ ET
116 124 endstream
117 125 endobj
118 126  
119   -7 0 obj
  127 +8 0 obj
120 128 44
121 129 endobj
122 130  
123 131 %% Original object ID: 6 0
124   -8 0 obj
  132 +9 0 obj
125 133 <<
126 134 /BaseFont /Helvetica
127 135 /Encoding /WinAnsiEncoding
... ... @@ -132,7 +140,7 @@ endobj
132 140 endobj
133 141  
134 142 %% Original object ID: 5 0
135   -9 0 obj
  143 +10 0 obj
136 144 [
137 145 /PDF
138 146 /Text
... ... @@ -140,23 +148,24 @@ endobj
140 148 endobj
141 149  
142 150 xref
143   -0 10
  151 +0 11
144 152 0000000000 65535 f
145 153 0000000052 00000 n
146 154 0000000133 00000 n
147   -0000000710 00000 n
148   -0000000809 00000 n
149   -0000000870 00000 n
150   -0000001112 00000 n
151   -0000001211 00000 n
152   -0000001257 00000 n
153   -0000001402 00000 n
  155 +0000000756 00000 n
  156 +0000000855 00000 n
  157 +0000000903 00000 n
  158 +0000000964 00000 n
  159 +0000001207 00000 n
  160 +0000001306 00000 n
  161 +0000001352 00000 n
  162 +0000001497 00000 n
154 163 trailer <<
155 164 /QTest 2 0 R
156 165 /Root 1 0 R
157   - /Size 10
  166 + /Size 11
158 167 /ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
159 168 >>
160 169 startxref
161   -1437
  170 +1533
162 171 %%EOF
... ...
qpdf/qtest/qpdf/json-changed-good13.pdf
... ... @@ -13,12 +13,15 @@ endobj
13 13 %% Original object ID: 7 0
14 14 2 0 obj
15 15 <<
  16 + /dangling-ref-for-json-test [
  17 + 4 0 R
  18 + ]
16 19 /hex#20strings [
17 20 (Potato)
18 21 <01020300040560>
19 22 (AB)
20 23 ]
21   - /indirect 4 0 R
  24 + /indirect 5 0 R
22 25 /names [
23 26 /nesting
24 27 /hex#20strings
... ... @@ -68,22 +71,27 @@ endobj
68 71 <<
69 72 /Count 1
70 73 /Kids [
71   - 5 0 R
  74 + 6 0 R
72 75 ]
73 76 /Type /Pages
74 77 >>
75 78 endobj
76 79  
77   -%% Original object ID: 8 0
  80 +%% Original object ID: 9 0
78 81 4 0 obj
  82 +null
  83 +endobj
  84 +
  85 +%% Original object ID: 8 0
  86 +5 0 obj
79 87 (hello)
80 88 endobj
81 89  
82 90 %% Page 1
83 91 %% Original object ID: 3 0
84   -5 0 obj
  92 +6 0 obj
85 93 <<
86   - /Contents 6 0 R
  94 + /Contents 7 0 R
87 95 /MediaBox [
88 96 0
89 97 0
... ... @@ -93,9 +101,9 @@ endobj
93 101 /Parent 3 0 R
94 102 /Resources <<
95 103 /Font <<
96   - /F1 8 0 R
  104 + /F1 9 0 R
97 105 >>
98   - /ProcSet 9 0 R
  106 + /ProcSet 10 0 R
99 107 >>
100 108 /Type /Page
101 109 >>
... ... @@ -103,9 +111,9 @@ endobj
103 111  
104 112 %% Contents for page 1
105 113 %% Original object ID: 4 0
106   -6 0 obj
  114 +7 0 obj
107 115 <<
108   - /Length 7 0 R
  116 + /Length 8 0 R
109 117 >>
110 118 stream
111 119 BT
... ... @@ -116,12 +124,12 @@ ET
116 124 endstream
117 125 endobj
118 126  
119   -7 0 obj
  127 +8 0 obj
120 128 44
121 129 endobj
122 130  
123 131 %% Original object ID: 6 0
124   -8 0 obj
  132 +9 0 obj
125 133 <<
126 134 /BaseFont /Helvetica
127 135 /Encoding /WinAnsiEncoding
... ... @@ -132,7 +140,7 @@ endobj
132 140 endobj
133 141  
134 142 %% Original object ID: 5 0
135   -9 0 obj
  143 +10 0 obj
136 144 [
137 145 /PDF
138 146 /Text
... ... @@ -140,23 +148,24 @@ endobj
140 148 endobj
141 149  
142 150 xref
143   -0 10
  151 +0 11
144 152 0000000000 65535 f
145 153 0000000052 00000 n
146 154 0000000133 00000 n
147   -0000000706 00000 n
148   -0000000805 00000 n
149   -0000000866 00000 n
150   -0000001108 00000 n
151   -0000001207 00000 n
152   -0000001253 00000 n
153   -0000001398 00000 n
  155 +0000000752 00000 n
  156 +0000000851 00000 n
  157 +0000000899 00000 n
  158 +0000000960 00000 n
  159 +0000001203 00000 n
  160 +0000001302 00000 n
  161 +0000001348 00000 n
  162 +0000001493 00000 n
154 163 trailer <<
155 164 /QTest 2 0 R
156 165 /Root 1 0 R
157   - /Size 10
  166 + /Size 11
158 167 /ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
159 168 >>
160 169 startxref
161   -1433
  170 +1529
162 171 %%EOF
... ...
qpdf/qtest/qpdf/manual-qpdf-json-out.json
1 1 {
2 2 "qpdf-v2": {
3 3 "pdfversion": "2.0",
4   - "maxobjectid": 8,
  4 + "maxobjectid": 100,
5 5 "objects": {
6 6 "obj:1 0 R": {
7 7 "value": {
... ... @@ -119,7 +119,15 @@
119 119 }
120 120 },
121 121 "obj:8 0 R": {
122   - "value": "u:hello"
  122 + "value": {
  123 + "/dangling": [
  124 + "100 0 R"
  125 + ],
  126 + "/k1": "u:hello"
  127 + }
  128 + },
  129 + "obj:100 0 R": {
  130 + "value": null
123 131 },
124 132 "trailer": {
125 133 "value": {
... ...
qpdf/qtest/qpdf/manual-qpdf-json-pdf.json
1 1 {
2 2 "qpdf-v2": {
3 3 "pdfversion": "2.0",
4   - "maxobjectid": 9,
  4 + "maxobjectid": 10,
5 5 "objects": {
6 6 "obj:1 0 R": {
7 7 "value": {
... ... @@ -79,11 +79,16 @@
79 79 }
80 80 },
81 81 "obj:4 0 R": {
82   - "value": "u:hello"
  82 + "value": {
  83 + "/dangling": [
  84 + "6 0 R"
  85 + ],
  86 + "/k1": "u:hello"
  87 + }
83 88 },
84 89 "obj:5 0 R": {
85 90 "value": {
86   - "/Contents": "6 0 R",
  91 + "/Contents": "7 0 R",
87 92 "/MediaBox": [
88 93 0,
89 94 0,
... ... @@ -93,23 +98,26 @@
93 98 "/Parent": "3 0 R",
94 99 "/Resources": {
95 100 "/Font": {
96   - "/F1": "8 0 R"
  101 + "/F1": "9 0 R"
97 102 },
98   - "/ProcSet": "9 0 R"
  103 + "/ProcSet": "10 0 R"
99 104 },
100 105 "/Type": "/Page"
101 106 }
102 107 },
103 108 "obj:6 0 R": {
  109 + "value": null
  110 + },
  111 + "obj:7 0 R": {
104 112 "stream": {
105 113 "data": "QlQKICAvRjEgMjQgVGYKICA3MiA3MjAgVGQKICAoUG90YXRvKSBUagpFVAo=",
106 114 "dict": {}
107 115 }
108 116 },
109   - "obj:7 0 R": {
  117 + "obj:8 0 R": {
110 118 "value": 44
111 119 },
112   - "obj:8 0 R": {
  120 + "obj:9 0 R": {
113 121 "value": {
114 122 "/BaseFont": "/Helvetica",
115 123 "/Encoding": "/WinAnsiEncoding",
... ... @@ -118,7 +126,7 @@
118 126 "/Type": "/Font"
119 127 }
120 128 },
121   - "obj:9 0 R": {
  129 + "obj:10 0 R": {
122 130 "value": [
123 131 "/PDF",
124 132 "/Text"
... ... @@ -132,7 +140,7 @@
132 140 ],
133 141 "/QTest": "2 0 R",
134 142 "/Root": "1 0 R",
135   - "/Size": 10
  143 + "/Size": 11
136 144 }
137 145 }
138 146 }
... ...
qpdf/qtest/qpdf/manual-qpdf-json.json
... ... @@ -134,7 +134,10 @@
134 134 }
135 135 },
136 136 "obj:8 0 R": {
137   - "value": "u:hello"
  137 + "value": {
  138 + "/k1": "u:hello",
  139 + "/dangling": ["100 0 R"]
  140 + }
138 141 }
139 142 }
140 143 }
... ...
qpdf/qtest/qpdf/manual-qpdf-json.pdf
... ... @@ -85,14 +85,19 @@ endobj
85 85  
86 86 %% Original object ID: 8 0
87 87 4 0 obj
88   -(hello)
  88 +<<
  89 + /dangling [
  90 + 6 0 R
  91 + ]
  92 + /k1 (hello)
  93 +>>
89 94 endobj
90 95  
91 96 %% Page 1
92 97 %% Original object ID: 3 0
93 98 5 0 obj
94 99 <<
95   - /Contents 6 0 R
  100 + /Contents 7 0 R
96 101 /MediaBox [
97 102 0
98 103 0
... ... @@ -102,19 +107,24 @@ endobj
102 107 /Parent 3 0 R
103 108 /Resources <<
104 109 /Font <<
105   - /F1 8 0 R
  110 + /F1 9 0 R
106 111 >>
107   - /ProcSet 9 0 R
  112 + /ProcSet 10 0 R
108 113 >>
109 114 /Type /Page
110 115 >>
111 116 endobj
112 117  
  118 +%% Original object ID: 100 0
  119 +6 0 obj
  120 +null
  121 +endobj
  122 +
113 123 %% Contents for page 1
114 124 %% Original object ID: 4 0
115   -6 0 obj
  125 +7 0 obj
116 126 <<
117   - /Length 7 0 R
  127 + /Length 8 0 R
118 128 >>
119 129 stream
120 130 BT
... ... @@ -125,12 +135,12 @@ ET
125 135 endstream
126 136 endobj
127 137  
128   -7 0 obj
  138 +8 0 obj
129 139 44
130 140 endobj
131 141  
132 142 %% Original object ID: 6 0
133   -8 0 obj
  143 +9 0 obj
134 144 <<
135 145 /BaseFont /Helvetica
136 146 /Encoding /WinAnsiEncoding
... ... @@ -141,7 +151,7 @@ endobj
141 151 endobj
142 152  
143 153 %% Original object ID: 5 0
144   -9 0 obj
  154 +10 0 obj
145 155 [
146 156 /PDF
147 157 /Text
... ... @@ -149,23 +159,24 @@ endobj
149 159 endobj
150 160  
151 161 xref
152   -0 10
  162 +0 11
153 163 0000000000 65535 f
154 164 0000000052 00000 n
155 165 0000000133 00000 n
156 166 0000000829 00000 n
157 167 0000000928 00000 n
158   -0000000989 00000 n
159   -0000001231 00000 n
160   -0000001330 00000 n
161   -0000001376 00000 n
162   -0000001521 00000 n
  168 +0000001029 00000 n
  169 +0000001251 00000 n
  170 +0000001322 00000 n
  171 +0000001421 00000 n
  172 +0000001467 00000 n
  173 +0000001612 00000 n
163 174 trailer <<
164 175 /QTest 2 0 R
165 176 /Root 1 0 R
166   - /Size 10
  177 + /Size 11
167 178 /ID [<31415926535897932384626433832795><31415926535897932384626433832795>]
168 179 >>
169 180 startxref
170   -1556
  181 +1648
171 182 %%EOF
... ...