Commit 1c944e4c89cf09d86f4e3f79ff57d937dab9b60f

Authored by Jay Berkenbilt
1 parent 11b194a1

Have QPDFWriter detect foreign objects while writing

Throw an exception that directs the user to QPDF::copyForeignObject.
ChangeLog
  1 +2012-07-14 Jay Berkenbilt <ejb@ql.org>
  2 +
  3 + * QPDFWriter: detect if the user has inserted an indirect object
  4 + from another QPDF object and throw an exception directing the user
  5 + to copyForeignObject.
  6 +
1 2012-07-11 Jay Berkenbilt <ejb@ql.org> 7 2012-07-11 Jay Berkenbilt <ejb@ql.org>
2 8
3 * Added new APIs to copy objects from one QPDF to another. This 9 * Added new APIs to copy objects from one QPDF to another. This
libqpdf/QPDFWriter.cc
@@ -761,6 +761,15 @@ QPDFWriter::enqueueObject(QPDFObjectHandle object) @@ -761,6 +761,15 @@ QPDFWriter::enqueueObject(QPDFObjectHandle object)
761 { 761 {
762 if (object.isIndirect()) 762 if (object.isIndirect())
763 { 763 {
  764 + if (object.getOwningQPDF() != &(this->pdf))
  765 + {
  766 + QTC::TC("qpdf", "QPDFWriter foreign object");
  767 + throw std::logic_error(
  768 + "QPDFObjectHandle from different QPDF found while writing."
  769 + " Use QPDF::copyForeignObject to add objects from"
  770 + " another file.");
  771 + }
  772 +
764 if (object.isNull()) 773 if (object.isNull())
765 { 774 {
766 // This is a place-holder object for an object stream 775 // This is a place-holder object for an object stream
qpdf/qpdf.testcov
@@ -233,3 +233,4 @@ QPDF not crossing page boundary 0 @@ -233,3 +233,4 @@ QPDF not crossing page boundary 0
233 QPDF replace foreign indirect with null 0 233 QPDF replace foreign indirect with null 0
234 QPDF not copying pages object 0 234 QPDF not copying pages object 0
235 QPDF insert foreign page 0 235 QPDF insert foreign page 0
  236 +QPDFWriter foreign object 0
qpdf/qtest/qpdf.test
@@ -149,7 +149,7 @@ $td-&gt;runtest(&quot;remove page we don&#39;t have&quot;, @@ -149,7 +149,7 @@ $td-&gt;runtest(&quot;remove page we don&#39;t have&quot;,
149 $td->NORMALIZE_NEWLINES); 149 $td->NORMALIZE_NEWLINES);
150 # ---------- 150 # ----------
151 $td->notify("--- Miscellaneous Tests ---"); 151 $td->notify("--- Miscellaneous Tests ---");
152 -$n_tests += 43; 152 +$n_tests += 44;
153 153
154 $td->runtest("qpdf version", 154 $td->runtest("qpdf version",
155 {$td->COMMAND => "qpdf --version"}, 155 {$td->COMMAND => "qpdf --version"},
@@ -365,6 +365,10 @@ $td-&gt;runtest(&quot;reserved objects&quot;, @@ -365,6 +365,10 @@ $td-&gt;runtest(&quot;reserved objects&quot;,
365 $td->runtest("check output", 365 $td->runtest("check output",
366 {$td->FILE => "a.pdf"}, 366 {$td->FILE => "a.pdf"},
367 {$td->FILE => "reserved-objects.pdf"}); 367 {$td->FILE => "reserved-objects.pdf"});
  368 +$td->runtest("detect foreign object in write",
  369 + {$td->COMMAND => "test_driver 29 copy-foreign-objects-in.pdf"},
  370 + {$td->FILE => "foreign-in-write.out", $td->EXIT_STATUS => 0},
  371 + $td->NORMALIZE_NEWLINES);
368 372
369 show_ntests(); 373 show_ntests();
370 # ---------- 374 # ----------
qpdf/qtest/qpdf/foreign-in-write.out 0 → 100644
  1 +logic error: QPDFObjectHandle from different QPDF found while writing. Use QPDF::copyForeignObject to add objects from another file.
  2 +test 29 done
qpdf/test_driver.cc
@@ -999,6 +999,26 @@ void runtest(int n, char const* filename) @@ -999,6 +999,26 @@ void runtest(int n, char const* filename)
999 std::cout << "logic error: " << e.what() << std::endl; 999 std::cout << "logic error: " << e.what() << std::endl;
1000 } 1000 }
1001 } 1001 }
  1002 + else if (n == 29)
  1003 + {
  1004 + // Detect mixed objects in QPDFWriter
  1005 + QPDF other;
  1006 + other.processFile("minimal.pdf");
  1007 + // Should use copyForeignObject instead
  1008 + other.getTrailer().replaceKey(
  1009 + "/QTest", pdf.getTrailer().getKey("/QTest"));
  1010 +
  1011 + try
  1012 + {
  1013 + QPDFWriter w(other, "a.pdf");
  1014 + w.write();
  1015 + std::cout << "oops -- didn't throw" << std::endl;
  1016 + }
  1017 + catch (std::logic_error e)
  1018 + {
  1019 + std::cout << "logic error: " << e.what() << std::endl;
  1020 + }
  1021 + }
1002 else 1022 else
1003 { 1023 {
1004 throw std::runtime_error(std::string("invalid test ") + 1024 throw std::runtime_error(std::string("invalid test ") +