Commit 1c944e4c89cf09d86f4e3f79ff57d937dab9b60f
1 parent
11b194a1
Have QPDFWriter detect foreign objects while writing
Throw an exception that directs the user to QPDF::copyForeignObject.
Showing
6 changed files
with
43 additions
and
1 deletions
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->runtest("remove page we don't have", | @@ -149,7 +149,7 @@ $td->runtest("remove page we don't have", | ||
| 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->runtest("reserved objects", | @@ -365,6 +365,10 @@ $td->runtest("reserved objects", | ||
| 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
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 ") + |