diff --git a/ChangeLog b/ChangeLog index 91301ae9..ed435242 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2021-11-04 Jay Berkenbilt + * Bug fix: fix crash that could occur under certain conditions + when using --pages with files that had form fields. Fixes #548. + * Add an extra check to the library to detect when foreign objects are inserted directly (instead of using QPDF::copyForeignObject) at the time of diff --git a/fuzz/build.mk b/fuzz/build.mk index d38fb909..b2e2d06a 100644 --- a/fuzz/build.mk +++ b/fuzz/build.mk @@ -41,6 +41,7 @@ CORPUS_FROM_TEST = \ outlines-with-old-root-dests.pdf \ page-labels-and-outlines.pdf \ page-labels-num-tree.pdf \ + dr-with-indirect-item.pdf \ fuzz-16214.pdf \ issue-99b.pdf \ issue-99.pdf \ diff --git a/fuzz/qtest/fuzz.test b/fuzz/qtest/fuzz.test index 8c94cb6f..73d4bd9d 100644 --- a/fuzz/qtest/fuzz.test +++ b/fuzz/qtest/fuzz.test @@ -9,7 +9,7 @@ require TestDriver; my $td = new TestDriver('fuzz'); -my $qpdf_n_test_files = 30; +my $qpdf_n_test_files = 31; my @extra = glob("../qpdf_extra/*.fuzz"); my $qpdf_n_extra_files = scalar(@extra); my $qpdf_n_orig_files = 2557; diff --git a/libqpdf/QPDFAcroFormDocumentHelper.cc b/libqpdf/QPDFAcroFormDocumentHelper.cc index 256fa694..ad6efc70 100644 --- a/libqpdf/QPDFAcroFormDocumentHelper.cc +++ b/libqpdf/QPDFAcroFormDocumentHelper.cc @@ -1002,8 +1002,10 @@ QPDFAcroFormDocumentHelper::transformAnnotations( } // Merge the other document's /DR, creating a conflict // map. mergeResources checks to make sure both objects - // are dictionaries. - from_dr.makeResourcesIndirect(*from_qpdf); + // are dictionaries. By this point, if this is foreign, + // from_dr has been copied, so we use the target qpdf as + // the owning qpdf. + from_dr.makeResourcesIndirect(this->qpdf); dr.mergeResources(from_dr, &dr_map); if (from_afdh->getNeedAppearances()) diff --git a/manual/qpdf-manual.xml b/manual/qpdf-manual.xml index 026d6039..64fe1c0e 100644 --- a/manual/qpdf-manual.xml +++ b/manual/qpdf-manual.xml @@ -5086,6 +5086,13 @@ print "\n"; (with no resource dictionary). + + + Fix crash that could occur under certain conditions when + using with files that had form + fields. + + diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test index fc8c709f..af99bb2a 100644 --- a/qpdf/qtest/qpdf.test +++ b/qpdf/qtest/qpdf.test @@ -1025,7 +1025,7 @@ my @bug_tests = ( ["335a", "ozz-fuzz-12152", 2], ["335b", "ozz-fuzz-14845", 2], ["fuzz-16214", "stream in object stream", 3, "--preserve-unreferenced"], - # When adding to this list, consider adding to SEED_CORPUS_FILES + # When adding to this list, consider adding to CORPUS_FROM_TEST # in fuzz/build.mk and updating the count in fuzz/qtest/fuzz.test. ); $n_tests += scalar(@bug_tests); @@ -3517,7 +3517,7 @@ for (my $n = 16; $n <= 19; ++$n) show_ntests(); # ---------- $td->notify("--- Specific File Tests ---"); -$n_tests += 9; +$n_tests += 11; # Special PDF files that caused problems at some point @@ -3556,6 +3556,15 @@ $td->runtest("pages points to page", $td->runtest("check output", {$td->FILE => "a.pdf"}, {$td->FILE => "pages-is-page-out.pdf"}); +$td->runtest("Acroform /DR with indirect subkey", + {$td->COMMAND => + "qpdf --static-id --empty" . + " --pages dr-with-indirect-item.pdf -- a.pdf"}, + {$td->STRING => "", $td->EXIT_STATUS => 0}, + $td->NORMALIZE_NEWLINES); +$td->runtest("check output", + {$td->FILE => "a.pdf"}, + {$td->FILE => "dr-with-indirect-item-out.pdf"}); show_ntests(); # ---------- diff --git a/qpdf/qtest/qpdf/dr-with-indirect-item-out.pdf b/qpdf/qtest/qpdf/dr-with-indirect-item-out.pdf new file mode 100644 index 00000000..c6f5c88b --- /dev/null +++ b/qpdf/qtest/qpdf/dr-with-indirect-item-out.pdf @@ -0,0 +1,37 @@ +%PDF-1.3 +%¿÷¢þ +1 0 obj +<< /AcroForm 2 0 R /Pages 3 0 R /Type /Catalog >> +endobj +2 0 obj +<< /DR 4 0 R /Fields [ 5 0 R ] >> +endobj +3 0 obj +<< /Count 1 /Kids [ 6 0 R ] /Type /Pages >> +endobj +4 0 obj +<< /Font << /F 7 0 R >> >> +endobj +5 0 obj +<< /DA (0 0 0 rg /Helv 11 Tf) /DV () /F 4 /FT /Tx /P 6 0 R /Rect [ 0 0 1 1 ] /Subtype /Widget /T () /TU () /Type /Annot /V () >> +endobj +6 0 obj +<< /Annots [ 5 0 R ] /MediaBox [ 0 0 1 1 ] /Parent 3 0 R /Resources << /Font << >> >> /Type /Page >> +endobj +7 0 obj +<< >> +endobj +xref +0 8 +0000000000 65535 f +0000000015 00000 n +0000000080 00000 n +0000000129 00000 n +0000000188 00000 n +0000000230 00000 n +0000000374 00000 n +0000000490 00000 n +trailer << /Root 1 0 R /Size 8 /ID [<31415926535897932384626433832795><31415926535897932384626433832795>] >> +startxref +511 +%%EOF diff --git a/qpdf/qtest/qpdf/dr-with-indirect-item.pdf b/qpdf/qtest/qpdf/dr-with-indirect-item.pdf new file mode 100644 index 00000000..ebd4f7ee --- /dev/null +++ b/qpdf/qtest/qpdf/dr-with-indirect-item.pdf @@ -0,0 +1,33 @@ +%PDF-1.4 +%¿÷¢þ +1 0 obj +<< /AcroForm << /DR 2 0 R /Fields [ 3 0 R ] >> /Pages 4 0 R /Type /Catalog >> +endobj +2 0 obj +<< /Font 5 0 R >> +endobj +3 0 obj +<< /DA (0 0 0 rg /Helv 11 Tf) /DV () /F 4 /FT /Tx /P 6 0 R /Rect [ 0 0 1 1 ] /Subtype /Widget /T () /TU () /Type /Annot /V () >> +endobj +4 0 obj +<< /Count 1 /Kids [ 6 0 R ] /MediaBox [ 0 0 1 1 ] /Resources 2 0 R /Type /Pages >> +endobj +5 0 obj +<< /F << >> >> +endobj +6 0 obj +<< /Annots [ 3 0 R ] /MediaBox [ 0 0 1 1 ] /Parent 4 0 R /Resources 2 0 R /Type /Page >> +endobj +xref +0 7 +0000000000 65535 f +0000000015 00000 n +0000000108 00000 n +0000000141 00000 n +0000000285 00000 n +0000000383 00000 n +0000000413 00000 n +trailer << /Root 1 0 R /Size 7 /ID [<5e0a553555622a0516e9877ca55217a6>] >> +startxref +517 +%%EOF