From faa2e3ddfd7e5bfd0922deb49b9c88e8eee08fbd Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Tue, 2 Feb 2021 15:55:18 -0500 Subject: [PATCH] Handle older PDFs whose form XObjects inherit resources (fixes #494) When removing unreferenced resources, notice if a page (recursively) contains a form XObject with unreferenced resources, and count any such resources as referenced by the page. --- ChangeLog | 9 + include/qpdf/QPDFPageObjectHelper.hh | 4 +- libqpdf/QPDFPageObjectHelper.cc | 83 ++++- manual/qpdf-manual.xml | 10 + qpdf/qpdf.testcov | 2 + qpdf/qtest/qpdf.test | 36 +- .../qpdf/form-xobjects-no-resources-out.pdf | Bin 0 -> 2664 bytes .../qtest/qpdf/form-xobjects-no-resources.pdf | 325 +++++++++++++++++ .../form-xobjects-some-resources1-out.pdf | Bin 0 -> 2775 bytes .../qpdf/form-xobjects-some-resources1.out | 2 + .../qpdf/form-xobjects-some-resources1.pdf | 331 +++++++++++++++++ .../form-xobjects-some-resources2-out.pdf | Bin 0 -> 2819 bytes .../qpdf/form-xobjects-some-resources2.out | 3 + .../qpdf/form-xobjects-some-resources2.pdf | 336 ++++++++++++++++++ qpdf/qtest/qpdf/shared-images-errors-2.out | 2 +- qpdf/qtest/qpdf/split-tokens-split.out | 2 +- 16 files changed, 1128 insertions(+), 17 deletions(-) create mode 100644 qpdf/qtest/qpdf/form-xobjects-no-resources-out.pdf create mode 100644 qpdf/qtest/qpdf/form-xobjects-no-resources.pdf create mode 100644 qpdf/qtest/qpdf/form-xobjects-some-resources1-out.pdf create mode 100644 qpdf/qtest/qpdf/form-xobjects-some-resources1.out create mode 100644 qpdf/qtest/qpdf/form-xobjects-some-resources1.pdf create mode 100644 qpdf/qtest/qpdf/form-xobjects-some-resources2-out.pdf create mode 100644 qpdf/qtest/qpdf/form-xobjects-some-resources2.out create mode 100644 qpdf/qtest/qpdf/form-xobjects-some-resources2.pdf diff --git a/ChangeLog b/ChangeLog index 243e4929..2670dd07 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2021-02-02 Jay Berkenbilt + + * Bug fix: if a form XObject lacks a resources dictionary, + consider any names in that form XObject to be referenced from the + containing page. This is compliant with older PDF versions. Also + detect if any form XObjects have any unresolved names and, if so, + don't remove unreferenced resources from them or from the page + that contains them. Fixes #494. + 2021-01-31 Jay Berkenbilt * Bug fix: properly handle strings if they appear in inline image diff --git a/include/qpdf/QPDFPageObjectHelper.hh b/include/qpdf/QPDFPageObjectHelper.hh index c948c5c2..73344caf 100644 --- a/include/qpdf/QPDFPageObjectHelper.hh +++ b/include/qpdf/QPDFPageObjectHelper.hh @@ -317,9 +317,9 @@ class QPDFPageObjectHelper: public QPDFObjectHelper void flattenRotation(); private: - static void + static bool removeUnreferencedResourcesHelper( - QPDFPageObjectHelper ph); + QPDFPageObjectHelper ph, std::set& unresolved); class Members { diff --git a/libqpdf/QPDFPageObjectHelper.cc b/libqpdf/QPDFPageObjectHelper.cc index 28b76561..da8b3919 100644 --- a/libqpdf/QPDFPageObjectHelper.cc +++ b/libqpdf/QPDFPageObjectHelper.cc @@ -701,10 +701,16 @@ NameWatcher::handleToken(QPDFTokenizer::Token const& token) writeToken(token); } -void +bool QPDFPageObjectHelper::removeUnreferencedResourcesHelper( - QPDFPageObjectHelper ph) + QPDFPageObjectHelper ph, std::set& unresolved) { + bool is_page = (! ph.oh.isFormXObject()); + if (! is_page) + { + QTC::TC("qpdf", "QPDFPageObjectHelper filter form xobject"); + } + NameWatcher nw; try { @@ -714,16 +720,17 @@ QPDFPageObjectHelper::removeUnreferencedResourcesHelper( { ph.oh.warnIfPossible( std::string("Unable to parse content stream: ") + e.what() + - "; not attempting to remove unreferenced objects from this page"); - return; + "; not attempting to remove unreferenced objects" + " from this object"); + return false; } if (nw.saw_bad) { QTC::TC("qpdf", "QPDFPageObjectHelper bad token finding names"); ph.oh.warnIfPossible( "Bad token found while scanning content stream; " - "not attempting to remove unreferenced objects from this page"); - return; + "not attempting to remove unreferenced objects from this object"); + return false; } // We will walk through /Font and /XObject dictionaries, removing @@ -733,6 +740,7 @@ QPDFPageObjectHelper::removeUnreferencedResourcesHelper( // of mutating the one it was copied from. QPDFObjectHandle resources = ph.getAttribute("/Resources", true); std::vector rdicts; + std::set known_names; if (resources.isDictionary()) { std::vector to_filter = {"/Font", "/XObject"}; @@ -744,33 +752,86 @@ QPDFPageObjectHelper::removeUnreferencedResourcesHelper( dict = dict.shallowCopy(); resources.replaceKey(iter, dict); rdicts.push_back(dict); + auto keys = dict.getKeys(); + known_names.insert(keys.begin(), keys.end()); } } } + + std::set local_unresolved; + for (auto const& name: nw.names) + { + if (! known_names.count(name)) + { + unresolved.insert(name); + local_unresolved.insert(name); + } + } + // Older versions of the PDF spec allowed form XObjects to omit + // their resources dictionaries, in which case names were resolved + // from the containing page. This behavior seems to be widely + // supported by viewers. If a form XObjects has a resources + // dictionary and has some unresolved names, some viewers fail to + // resolve them, and others allow them to be inherited from the + // page or from another form XObjects that contains them. Since + // this behavior is inconsistent across viewers, we consider an + // unresolved name when a resources dictionary is present to be + // reason not to remove unreferenced resources. An unresolved name + // in the absence of a resource dictionary is not considered a + // problem. For form XObjects, we just accumulate a list of + // unresolved names, and for page objects, we avoid removing any + // such names found in nested form XObjects. + + if ((! local_unresolved.empty()) && resources.isDictionary()) + { + QTC::TC("qpdf", "QPDFPageObjectHelper unresolved names"); + ph.oh.warnIfPossible( + "Unresolved names found while scanning content stream; " + "not attempting to remove unreferenced objects from this object"); + return false; + } + for (auto& dict: rdicts) { for (auto const& key: dict.getKeys()) { - if (! nw.names.count(key)) + if (is_page && unresolved.count(key)) + { + // This name is referenced by some nested form + // xobject, so don't remove it. + QTC::TC("qpdf", "QPDFPageObjectHelper resolving unresolved"); + } + else if (! nw.names.count(key)) { dict.removeKey(key); } } } + return true; } void QPDFPageObjectHelper::removeUnreferencedResources() { + // Accumulate a list of unresolved names across all nested form + // XObjects. + std::set unresolved; + bool any_failures = false; forEachFormXObject( true, - []( + [&any_failures, &unresolved]( QPDFObjectHandle& obj, QPDFObjectHandle&, std::string const&) { - QTC::TC("qpdf", "QPDFPageObjectHelper filter form xobject"); - removeUnreferencedResourcesHelper(QPDFPageObjectHelper(obj)); + if (! removeUnreferencedResourcesHelper( + QPDFPageObjectHelper(obj), unresolved)) + { + any_failures = true; + } }); - removeUnreferencedResourcesHelper(*this); + if (this->oh.isFormXObject() || (! any_failures)) + { + removeUnreferencedResourcesHelper(*this, unresolved); + } } QPDFPageObjectHelper diff --git a/manual/qpdf-manual.xml b/manual/qpdf-manual.xml index 66819d99..fda9c1fd 100644 --- a/manual/qpdf-manual.xml +++ b/manual/qpdf-manual.xml @@ -4887,6 +4887,16 @@ print "\n"; Bug Fixes + + + If a form XObject lacks a resources dictionary, consider any + names in that form XObject to be referenced from the + containing page. This is compliant with older PDF versions. + Also detect if any form XObjects have any unresolved names + and, if so, don't remove unreferenced resources from them or + from the page that contains them. + + Properly handle strings if they appear in inline image diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov index 7aa84d8d..520cc84b 100644 --- a/qpdf/qpdf.testcov +++ b/qpdf/qpdf.testcov @@ -566,3 +566,5 @@ NNTree non-flat tree is empty after remove 0 NNTree remove walking up tree 0 NNTree erased last item in tree 0 NNTree remove limits from root 0 +QPDFPageObjectHelper unresolved names 0 +QPDFPageObjectHelper resolving unresolved 0 diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test index 62eebcd7..0ec1b834 100644 --- a/qpdf/qtest/qpdf.test +++ b/qpdf/qtest/qpdf.test @@ -1783,8 +1783,8 @@ my @sp_cases = ( [1, 'broken data', '--pages broken-lzw.pdf --', 'split-out.pdf', {$td->FILE => "broken-lzw.out", $td->EXIT_STATUS => 3}], ); -$n_tests += 36; -$n_compare_pdfs += 1; +$n_tests += 43; +$n_compare_pdfs += 2; for (@sp_cases) { $n_tests += 1 + $_->[0]; @@ -1943,6 +1943,38 @@ foreach my $i (qw(1 2)) {$td->FILE => "shared-form-xobject-split-$i.pdf"}); } +my @fo_resources = (['form-xobjects-no-resources', 0], + ['form-xobjects-some-resources1', 3], + ['form-xobjects-some-resources2', 3]); +foreach my $d (@fo_resources) +{ + my ($f, $status) = @$d; + my $expout = ($status == 0 ? + {$td->STRING => ""} : + {$td->FILE => "$f.out"}); + $expout->{$td->EXIT_STATUS} = $status; + $td->runtest("split $f", + {$td->COMMAND => + "qpdf --empty --static-id --pages $f.pdf 1 --" . + " --remove-unreferenced-resources=yes a.pdf"}, + $expout, $td->NORMALIZE_NEWLINES); + $td->runtest("check output ($f)", + {$td->FILE => "a.pdf"}, + {$td->FILE => "$f-out.pdf"}); + if ($status == 0) + { + compare_pdfs("$f.pdf", "a.pdf"); + } +} + +$td->runtest("no warn with pages warnings", + {$td->COMMAND => + "qpdf --no-warn --empty --static-id". + " --pages form-xobjects-some-resources1.pdf 1 --" . + " --remove-unreferenced-resources=yes a.pdf"}, + {$td->STRING => "", $td->EXIT_STATUS => 3}, + $td->NORMALIZE_NEWLINES); + show_ntests(); # ---------- $td->notify("--- Keep Files Open ---"); diff --git a/qpdf/qtest/qpdf/form-xobjects-no-resources-out.pdf b/qpdf/qtest/qpdf/form-xobjects-no-resources-out.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ac9f92ebc062a03f3e58aa7c580a52fce94d0ef9 GIT binary patch literal 2664 zcmd5;O>7%Q6kgX!u~spPAV_Tl(vXruDYbWIf9zF)mD;K6G$}ETQ4vWbHul8X%HB1* zo7Uyz2Do9VAQf>y5LHp79^k;G&4~&jXeE#ch{A~-7JaH!$fNbIZ#Z-d8S5~t?(TA0zwz+N<04GD7HsOuCz({r-B@$p^nS}-FAjNb2;{3{4T4?Ik zFp7ENbd8|6x16b9r20#OFhc+-n5l>evjn+o2?3_&T1MF83OWkH9tQ}`qI-#B+&i+y zG<@oF)F?S?5Jdt4dfA~C{FXI`PSb)}bggX1qFRNoy=U`xbJ?%Yi+O=OADRh%{8giV zYwGbQ25;R7W#;C;%ZG0NWQFfO{WFn-EO&f3oL}9)^|rnJ`?GfVk)_|Z_wD2lyfk(c zZyenbxxiph8a-?n1N6Ybn_E+dZ@e&dEWo|;!J(^A+GfONky$Q%xJk{XZl0qVT0Tb| zy`Z7!2?L<&MhQjF=*Drw*4u*Tv4wVQ$!iG^B(x=p7+ ziPjvJddOc2E&E-^YSseOZWB=ukPKgFlUA^_X;u7Ke(9sloU6*cr#w9JW@Bh1nXAu* zuZL2n-?;QlEha{p~j`l@7}!p%fWhm zBQV;SeRS)`4?hiEd5n9D8=L4!HEY5DU`FnNSxo*v%!b;`4s|hmeaB;U)noMydiZ7j zOT=@eG4ewX2{t?}61rn&sg*J-RnuUT8;5PgESuIsRVzSeOw)6Efu6Lq3kW(&FRj52 z0^nQqb4%Y-z%zQ0%?v2|3Qcs9fBdmx_KtWU%P9KJK5^#FHA{XQcnFbccQeU;l7 z7_QcXr*6FVAjgd<{jhiL-O0U^b-P->2-r9I^Fn}o=$(GZI}efjg&f*&_pEP@X1Ktw z)oUT{WT_wU&LeDZ0grgVgIw&3e!x2qpuGh=-~vCgpL^=bKEP`hUF8KBd|qfhNReex zMyseLgMGn$i;T8R0m|&@kYNJ#>ynAFUOicY4XsO0k>RB3mZ`nAD!V28TMuKQ#~&uW zwpfby+A0d15MBP_at{w8h#h*4rRin3SFo#5&NSH_&AquS=&w?D6P=kxi<2Uju&fdV sk{MTHsz}7Rq!2|C#kfdfs+`zeW0~D?Y)7*kw@`!-xLA&#m{0Tn08b|tv;Y7A literal 0 HcmV?d00001 diff --git a/qpdf/qtest/qpdf/form-xobjects-no-resources.pdf b/qpdf/qtest/qpdf/form-xobjects-no-resources.pdf new file mode 100644 index 00000000..64898fe4 --- /dev/null +++ b/qpdf/qtest/qpdf/form-xobjects-no-resources.pdf @@ -0,0 +1,325 @@ +%PDF-1.3 +%¿÷¢þ +%QDF-1.0 + +1 0 obj +<< + /Pages 2 0 R + /Type /Catalog +>> +endobj + +2 0 obj +<< + /Count 1 + /Kids [ + 3 0 R + ] + /Resources << + /Font << + /F1 4 0 R + >> + /ProcSet 5 0 R + /XObject << + /Fx1 6 0 R + /Fx2 8 0 R + /Im1 10 0 R + /Im2 12 0 R + /Im3 14 0 R + /Im4 16 0 R + /Im5 18 0 R + /Im6 20 0 R + /ImX 20 0 R + >> + >> + /Type /Pages +>> +endobj + +%% Page 1 +3 0 obj +<< + /Contents 22 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 2 0 R + /Type /Page +>> +endobj + +4 0 obj +<< + /BaseFont /Helvetica + /Encoding /WinAnsiEncoding + /Name /F1 + /Subtype /Type1 + /Type /Font +>> +endobj + +5 0 obj +[ + /PDF + /Text + /ImageC +] +endobj + +6 0 obj +<< + /BBox [ + 0 + 0 + 300 + 500 + ] + /Subtype /Form + /Type /XObject + /Length 7 0 R +>> +stream +BT + /F1 24 Tf + 0 320 Td + (FX1) Tj +ET +q +100 0 0 100 000 200 cm +/Im3 Do +Q +q +100 0 0 100 120 200 cm +/Im4 Do +Q +q +1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 cm +/Fx2 Do +Q +endstream +endobj + +7 0 obj +173 +endobj + +8 0 obj +<< + /BBox [ + 0 + 0 + 300 + 200 + ] + /Subtype /Form + /Type /XObject + /Length 9 0 R +>> +stream +BT + /F1 24 Tf + 0 120 Td + (FX2) Tj +ET +q +100 0 0 100 0 0 cm +/Im5 Do +Q +q +100 0 0 100 120 0 cm +/Im6 Do +Q +endstream +endobj + +9 0 obj +104 +endobj + +10 0 obj +<< + /BitsPerComponent 8 + /ColorSpace /DeviceGray + /Height 15 + /Subtype /Image + /Type /XObject + /Width 15 + /Length 11 0 R +>> +stream +`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +endstream +endobj + +%QDF: ignore_newline +11 0 obj +225 +endobj + +12 0 obj +<< + /BitsPerComponent 8 + /ColorSpace /DeviceGray + /Height 15 + /Subtype /Image + /Type /XObject + /Width 15 + /Length 13 0 R +>> +stream +@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +endstream +endobj + +%QDF: ignore_newline +13 0 obj +225 +endobj + +14 0 obj +<< + /BitsPerComponent 8 + /ColorSpace /DeviceGray + /Height 15 + /Subtype /Image + /Type /XObject + /Width 15 + /Length 15 0 R +>> +stream +@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +endstream +endobj + +%QDF: ignore_newline +15 0 obj +225 +endobj + +16 0 obj +<< + /BitsPerComponent 8 + /ColorSpace /DeviceGray + /Height 15 + /Subtype /Image + /Type /XObject + /Width 15 + /Length 17 0 R +>> +stream +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +endstream +endobj + +%QDF: ignore_newline +17 0 obj +225 +endobj + +18 0 obj +<< + /BitsPerComponent 8 + /ColorSpace /DeviceGray + /Height 15 + /Subtype /Image + /Type /XObject + /Width 15 + /Length 19 0 R +>> +stream +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +endstream +endobj + +%QDF: ignore_newline +19 0 obj +225 +endobj + +20 0 obj +<< + /BitsPerComponent 8 + /ColorSpace /DeviceGray + /Height 15 + /Subtype /Image + /Type /XObject + /Width 15 + /Length 21 0 R +>> +stream +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +endstream +endobj + +%QDF: ignore_newline +21 0 obj +225 +endobj + +%% Contents for page 1 +22 0 obj +<< + /Length 23 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Page) Tj +ET +q +100 0 0 100 72 600 cm +/Im1 Do +Q +q +100 0 0 100 192 600 cm +/Im2 Do +Q +q +1.00000 0.00000 0.00000 1.00000 72.00000 200.00000 cm +/Fx1 Do +Q +endstream +endobj + +23 0 obj +177 +endobj + +xref +0 24 +0000000000 65535 f +0000000025 00000 n +0000000079 00000 n +0000000420 00000 n +0000000537 00000 n +0000000655 00000 n +0000000700 00000 n +0000001004 00000 n +0000001024 00000 n +0000001259 00000 n +0000001279 00000 n +0000001691 00000 n +0000001712 00000 n +0000002124 00000 n +0000002145 00000 n +0000002557 00000 n +0000002578 00000 n +0000002990 00000 n +0000003011 00000 n +0000003423 00000 n +0000003444 00000 n +0000003856 00000 n +0000003900 00000 n +0000004134 00000 n +trailer << + /Root 1 0 R + /Size 24 + /ID [<55269d37282af9edc76855e4cb859987><5044e8073c04a0be007e587c761cce26>] +>> +startxref +4155 +%%EOF diff --git a/qpdf/qtest/qpdf/form-xobjects-some-resources1-out.pdf b/qpdf/qtest/qpdf/form-xobjects-some-resources1-out.pdf new file mode 100644 index 0000000000000000000000000000000000000000..7cb072a801b46df2e37d2f23743312265b44c417 GIT binary patch literal 2775 zcmd5;O>7%Q6kgX!u~spPAV_Tl(ljOIr_|orKYNv6rMBzZO-hVo)It)8jXiNTvUkny zrgb^F0d7PpNJShFL{(I&2RLw{IZ+`5?E#5UQBE9+I3SJ)3BdvJX4h-GUZWHaQEgcs zznwSld*A!~-i+tdnPWI2u;ZWqapi9oBMuo$tL)??issb{u@DcI0*V$d)Cr2FR9meY z6_iM@L@(2g^s(oVGS+k(VHBO#$`+bOg5$dAIlJd|Td5t%rj7-e*FHLY6_{*AY;j6c@!)0*NS0P3gOTi{m`DH#rcs(BHj24PpPgM=C8gHB z21aq$oN4e#ahJIohLpWEk1#DXlr>iq5OCXCiwL_l1G|K9s}{MMjBtzIT=ZLM9R1`g-1G}1DLD4gseq6V-j^PEh2GWB3qH}9YwxcszMfmL& z(>bdXisnp1%>xbT3~V9|nE9XiA^{OZVUU-FKI+u3Wjl_zG( zsMQUfHibBJD5Gkab9J=@l1h_vT8W%A)e8uus8v>=IRW~1;T_HRDt|^R)BXS(y;h;@ zp7C^++4oR9yV;zG2N-;3LiHo>Zmr3^LC(W}XxAQBXVwRX>&@V)>u)^FFk^B*?A={{ zkFewWVBM-WF9P;W_BmN)~|(_la+qJyJyye1w7&c z4>GZ@`vLEsUJn-VfCK!Q{mj!(^#R^6$ui3!EVEqug=9$*B(#j$HaZCD3+Wx347KX9 zVIG9nW8-;f-90uDt|7fPDem``6&T(^~c!FpvNM literal 0 HcmV?d00001 diff --git a/qpdf/qtest/qpdf/form-xobjects-some-resources1.out b/qpdf/qtest/qpdf/form-xobjects-some-resources1.out new file mode 100644 index 00000000..17d6c7f2 --- /dev/null +++ b/qpdf/qtest/qpdf/form-xobjects-some-resources1.out @@ -0,0 +1,2 @@ +WARNING: form-xobjects-some-resources1.pdf, stream object 8 0: Unresolved names found while scanning content stream; not attempting to remove unreferenced objects from this object +qpdf: operation succeeded with warnings; resulting file may have some problems diff --git a/qpdf/qtest/qpdf/form-xobjects-some-resources1.pdf b/qpdf/qtest/qpdf/form-xobjects-some-resources1.pdf new file mode 100644 index 00000000..0c914ad5 --- /dev/null +++ b/qpdf/qtest/qpdf/form-xobjects-some-resources1.pdf @@ -0,0 +1,331 @@ +%PDF-1.3 +%¿÷¢þ +%QDF-1.0 + +1 0 obj +<< + /Pages 2 0 R + /Type /Catalog +>> +endobj + +2 0 obj +<< + /Count 1 + /Kids [ + 3 0 R + ] + /Resources << + /Font << + /F1 4 0 R + >> + /ProcSet 5 0 R + /XObject << + /Fx1 6 0 R + /Fx2 8 0 R + /Im1 10 0 R + /Im2 12 0 R + /Im3 14 0 R + /Im4 16 0 R + /Im5 18 0 R + /Im6 20 0 R + /ImX 20 0 R + >> + >> + /Type /Pages +>> +endobj + +%% Page 1 +3 0 obj +<< + /Contents 22 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 2 0 R + /Type /Page +>> +endobj + +4 0 obj +<< + /BaseFont /Helvetica + /Encoding /WinAnsiEncoding + /Name /F1 + /Subtype /Type1 + /Type /Font +>> +endobj + +5 0 obj +[ + /PDF + /Text + /ImageC +] +endobj + +6 0 obj +<< + /BBox [ + 0 + 0 + 300 + 500 + ] + /Subtype /Form + /Type /XObject + /Length 7 0 R +>> +stream +BT + /F1 24 Tf + 0 320 Td + (FX1) Tj +ET +q +100 0 0 100 000 200 cm +/Im3 Do +Q +q +100 0 0 100 120 200 cm +/Im4 Do +Q +q +1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 cm +/Fx2 Do +Q +endstream +endobj + +7 0 obj +173 +endobj + +8 0 obj +<< + /BBox [ + 0 + 0 + 300 + 200 + ] + /Subtype /Form + /Type /XObject + /Length 9 0 R + /Resources << + /XObject << + /Im1 20 0 R + /ImY 20 0 R + >> + >> +>> +stream +BT + /F1 24 Tf + 0 120 Td + (FX2) Tj +ET +q +100 0 0 100 0 0 cm +/Im5 Do +Q +q +100 0 0 100 120 0 cm +/Im1 Do +Q +endstream +endobj + +9 0 obj +104 +endobj + +10 0 obj +<< + /BitsPerComponent 8 + /ColorSpace /DeviceGray + /Height 15 + /Subtype /Image + /Type /XObject + /Width 15 + /Length 11 0 R +>> +stream +`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +endstream +endobj + +%QDF: ignore_newline +11 0 obj +225 +endobj + +12 0 obj +<< + /BitsPerComponent 8 + /ColorSpace /DeviceGray + /Height 15 + /Subtype /Image + /Type /XObject + /Width 15 + /Length 13 0 R +>> +stream +@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +endstream +endobj + +%QDF: ignore_newline +13 0 obj +225 +endobj + +14 0 obj +<< + /BitsPerComponent 8 + /ColorSpace /DeviceGray + /Height 15 + /Subtype /Image + /Type /XObject + /Width 15 + /Length 15 0 R +>> +stream +@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +endstream +endobj + +%QDF: ignore_newline +15 0 obj +225 +endobj + +16 0 obj +<< + /BitsPerComponent 8 + /ColorSpace /DeviceGray + /Height 15 + /Subtype /Image + /Type /XObject + /Width 15 + /Length 17 0 R +>> +stream +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +endstream +endobj + +%QDF: ignore_newline +17 0 obj +225 +endobj + +18 0 obj +<< + /BitsPerComponent 8 + /ColorSpace /DeviceGray + /Height 15 + /Subtype /Image + /Type /XObject + /Width 15 + /Length 19 0 R +>> +stream +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +endstream +endobj + +%QDF: ignore_newline +19 0 obj +225 +endobj + +20 0 obj +<< + /BitsPerComponent 8 + /ColorSpace /DeviceGray + /Height 15 + /Subtype /Image + /Type /XObject + /Width 15 + /Length 21 0 R +>> +stream +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +endstream +endobj + +%QDF: ignore_newline +21 0 obj +225 +endobj + +%% Contents for page 1 +22 0 obj +<< + /Length 23 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Page) Tj +ET +q +100 0 0 100 72 600 cm +/Im1 Do +Q +q +100 0 0 100 192 600 cm +/Im2 Do +Q +q +1.00000 0.00000 0.00000 1.00000 72.00000 200.00000 cm +/Fx1 Do +Q +endstream +endobj + +23 0 obj +177 +endobj + +xref +0 24 +0000000000 65535 f +0000000025 00000 n +0000000079 00000 n +0000000420 00000 n +0000000537 00000 n +0000000655 00000 n +0000000700 00000 n +0000001004 00000 n +0000001024 00000 n +0000001339 00000 n +0000001359 00000 n +0000001771 00000 n +0000001792 00000 n +0000002204 00000 n +0000002225 00000 n +0000002637 00000 n +0000002658 00000 n +0000003070 00000 n +0000003091 00000 n +0000003503 00000 n +0000003524 00000 n +0000003936 00000 n +0000003980 00000 n +0000004214 00000 n +trailer << + /Root 1 0 R + /Size 24 + /ID [<55269d37282af9edc76855e4cb859987><5044e8073c04a0be007e587c761cce26>] +>> +startxref +4235 +%%EOF diff --git a/qpdf/qtest/qpdf/form-xobjects-some-resources2-out.pdf b/qpdf/qtest/qpdf/form-xobjects-some-resources2-out.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2b54914b8d15593821ae219913cd036c9e24fd9b GIT binary patch literal 2819 zcmd5;Pi)&%7P`+X@~=YYN{r2fCCrS6B9zP9grv!U4 zvxMStmKa6qNFVzFNpszB5JudzUbN8y65Y@xKiJ!^6-pnsLJfx)j*TSmxYMMlYYDRk zyYTRqv49j+K(JR%v%t}Zl_$2jZWRD$)C=@*(xciy(oOx7W{6R8RuSeU#HIDJLoE0% zYYs_~f?0H2kZ!d`RyzpWu8~pT}&HBx$Lr)Igyc5dI%zi%~y7iM4 zzWeOYg2d;TWQ}N-ZO-PnjBaM;lrWlU{36@!yBMwr$q|eSSuaQE- zuZB^~GpB0;QoUuif+1ypEg(z_4Q0(%L({2K4iAUsl6on6nrzICkX*+G%N)+LShO(8H?@71~ zWZJYUK1M&BYe-6!|GT2XBX4aEjU@8*neb)8=84L~%58R$A4}5uR zXYsEOcD`aGe=c5HJvFp>`O14YuKaSaUf&3eZcabG{o}`9gswipyv>YFbSa5e|6dpp z`ZEHOX-eRnzjh^XpNuHc|HH^oi;=?}jJ&byv2o2~<2&@|E9}rAmJ!xQZg(Z`>b;r0 z?$|kECCy6JG-v~fK{qqYrZrd93LwQ4IjrPPT36-I=tbH~ zz|n6jYX6Lm{P+6y!z!~eFkGz%PhEfgVTKu# zdtq;%2z!Jb-v{e+r!A^LtLX5P6&QpaHU-19?y#vUTnO&9VL|G`f~9UO zSjI4tJ7QyecdQ!g!XjX$&Cjtky$p9SI*;?FNw1IYWn@l&jR3ze> +endobj + +2 0 obj +<< + /Count 1 + /Kids [ + 3 0 R + ] + /Resources << + /Font << + /F1 4 0 R + >> + /ProcSet 5 0 R + /XObject << + /Fx1 6 0 R + /Fx2 8 0 R + /Im1 10 0 R + /Im2 12 0 R + /Im3 14 0 R + /Im4 16 0 R + /Im6 20 0 R + /ImX 20 0 R + >> + >> + /Type /Pages +>> +endobj + +%% Page 1 +3 0 obj +<< + /Contents 22 0 R + /MediaBox [ + 0 + 0 + 612 + 792 + ] + /Parent 2 0 R + /Type /Page +>> +endobj + +4 0 obj +<< + /BaseFont /Helvetica + /Encoding /WinAnsiEncoding + /Name /F1 + /Subtype /Type1 + /Type /Font +>> +endobj + +5 0 obj +[ + /PDF + /Text + /ImageC +] +endobj + +6 0 obj +<< + /BBox [ + 0 + 0 + 300 + 500 + ] + /Subtype /Form + /Type /XObject + /Length 7 0 R + /Resources << + /XObject << + /Im5 18 0 R + /ImY 20 0 R + >> + >> +>> +stream +BT + /F1 24 Tf + 0 320 Td + (FX1) Tj +ET +q +100 0 0 100 000 200 cm +/Im3 Do +Q +q +100 0 0 100 120 200 cm +/Im4 Do +Q +q +1.00000 0.00000 0.00000 1.00000 0.00000 0.00000 cm +/Fx2 Do +Q +endstream +endobj + +7 0 obj +173 +endobj + +8 0 obj +<< + /BBox [ + 0 + 0 + 300 + 200 + ] + /Subtype /Form + /Type /XObject + /Length 9 0 R + /Resources << + /XObject << + /Im1 20 0 R + /ImZ 20 0 R + >> + >> +>> +stream +BT + /F1 24 Tf + 0 120 Td + (FX2) Tj +ET +q +100 0 0 100 0 0 cm +/Im5 Do +Q +q +100 0 0 100 120 0 cm +/Im1 Do +Q +endstream +endobj + +9 0 obj +104 +endobj + +10 0 obj +<< + /BitsPerComponent 8 + /ColorSpace /DeviceGray + /Height 15 + /Subtype /Image + /Type /XObject + /Width 15 + /Length 11 0 R +>> +stream +`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +endstream +endobj + +%QDF: ignore_newline +11 0 obj +225 +endobj + +12 0 obj +<< + /BitsPerComponent 8 + /ColorSpace /DeviceGray + /Height 15 + /Subtype /Image + /Type /XObject + /Width 15 + /Length 13 0 R +>> +stream +@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +endstream +endobj + +%QDF: ignore_newline +13 0 obj +225 +endobj + +14 0 obj +<< + /BitsPerComponent 8 + /ColorSpace /DeviceGray + /Height 15 + /Subtype /Image + /Type /XObject + /Width 15 + /Length 15 0 R +>> +stream +@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +endstream +endobj + +%QDF: ignore_newline +15 0 obj +225 +endobj + +16 0 obj +<< + /BitsPerComponent 8 + /ColorSpace /DeviceGray + /Height 15 + /Subtype /Image + /Type /XObject + /Width 15 + /Length 17 0 R +>> +stream +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +endstream +endobj + +%QDF: ignore_newline +17 0 obj +225 +endobj + +18 0 obj +<< + /BitsPerComponent 8 + /ColorSpace /DeviceGray + /Height 15 + /Subtype /Image + /Type /XObject + /Width 15 + /Length 19 0 R +>> +stream +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +endstream +endobj + +%QDF: ignore_newline +19 0 obj +225 +endobj + +20 0 obj +<< + /BitsPerComponent 8 + /ColorSpace /DeviceGray + /Height 15 + /Subtype /Image + /Type /XObject + /Width 15 + /Length 21 0 R +>> +stream +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@`````@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +endstream +endobj + +%QDF: ignore_newline +21 0 obj +225 +endobj + +%% Contents for page 1 +22 0 obj +<< + /Length 23 0 R +>> +stream +BT + /F1 24 Tf + 72 720 Td + (Page) Tj +ET +q +100 0 0 100 72 600 cm +/Im1 Do +Q +q +100 0 0 100 192 600 cm +/Im2 Do +Q +q +1.00000 0.00000 0.00000 1.00000 72.00000 200.00000 cm +/Fx1 Do +Q +endstream +endobj + +23 0 obj +177 +endobj + +xref +0 24 +0000000000 65535 f +0000000025 00000 n +0000000079 00000 n +0000000402 00000 n +0000000519 00000 n +0000000637 00000 n +0000000682 00000 n +0000001066 00000 n +0000001086 00000 n +0000001401 00000 n +0000001421 00000 n +0000001833 00000 n +0000001854 00000 n +0000002266 00000 n +0000002287 00000 n +0000002699 00000 n +0000002720 00000 n +0000003132 00000 n +0000003153 00000 n +0000003565 00000 n +0000003586 00000 n +0000003998 00000 n +0000004042 00000 n +0000004276 00000 n +trailer << + /Root 1 0 R + /Size 24 + /ID [<55269d37282af9edc76855e4cb859987><5044e8073c04a0be007e587c761cce26>] +>> +startxref +4297 +%%EOF diff --git a/qpdf/qtest/qpdf/shared-images-errors-2.out b/qpdf/qtest/qpdf/shared-images-errors-2.out index eda5851a..5e00a7a7 100644 --- a/qpdf/qtest/qpdf/shared-images-errors-2.out +++ b/qpdf/qtest/qpdf/shared-images-errors-2.out @@ -1,5 +1,5 @@ WARNING: shared-images-errors.pdf (offset 4933): error decoding stream data for object 19 0: stream inflate: inflate: data: incorrect header check -WARNING: shared-images-errors.pdf, object 4 0 at offset 676: Unable to parse content stream: content stream (content stream object 19 0): errors while decoding content stream; not attempting to remove unreferenced objects from this page +WARNING: shared-images-errors.pdf, object 4 0 at offset 676: Unable to parse content stream: content stream (content stream object 19 0): errors while decoding content stream; not attempting to remove unreferenced objects from this object WARNING: shared-images-errors.pdf (offset 4933): error decoding stream data for object 19 0: stream inflate: inflate: data: incorrect header check WARNING: shared-images-errors.pdf (offset 4933): stream will be re-processed without filtering to avoid data loss qpdf: operation succeeded with warnings; resulting file may have some problems diff --git a/qpdf/qtest/qpdf/split-tokens-split.out b/qpdf/qtest/qpdf/split-tokens-split.out index 7b940622..ab9f3b7a 100644 --- a/qpdf/qtest/qpdf/split-tokens-split.out +++ b/qpdf/qtest/qpdf/split-tokens-split.out @@ -1,4 +1,4 @@ -WARNING: split-tokens.pdf, object 3 0 at offset 181: Bad token found while scanning content stream; not attempting to remove unreferenced objects from this page +WARNING: split-tokens.pdf, object 3 0 at offset 181: Bad token found while scanning content stream; not attempting to remove unreferenced objects from this object WARNING: empty PDF: content normalization encountered bad tokens WARNING: empty PDF: normalized content ended with a bad token; you may be able to resolve this by coalescing content streams in combination with normalizing content. From the command line, specify --coalesce-contents WARNING: empty PDF: Resulting stream data may be corrupted but is may still useful for manual inspection. For more information on this warning, search for content normalization in the manual.