Commit 8d2b29ef988aa86489e36be50fa881335b81363e
1 parent
b51a5b2c
Fix segmentation fault with use of QPDFWriter::setOutputMemory
Showing
5 changed files
with
31 additions
and
21 deletions
ChangeLog
| 1 | +2012-09-06 Jay Berkenbilt <ejb@ql.org> | |
| 2 | + | |
| 3 | + * Bug fix: Writing after calling QPDFWriter::setOutputMemory() | |
| 4 | + would cause a segmentation fault because of an internal field not | |
| 5 | + being initialized, rendering that method useless. This has been | |
| 6 | + corrected. | |
| 7 | + | |
| 1 | 8 | 2012-08-11 Jay Berkenbilt <ejb@ql.org> |
| 2 | 9 | |
| 3 | 10 | * 3.0.1: release | ... | ... |
TODO
| 1 | -3.0.2 | |
| 2 | -===== | |
| 3 | - | |
| 4 | - * QPDFWriter::setOutputMemory segfaults without setStaticID because | |
| 5 | - it doesn't set this->filename. Be sure to have a test case that | |
| 6 | - exercises this. Check the function that sets the ID carefully to | |
| 7 | - make sure other cases aren't missed. | |
| 8 | - | |
| 9 | 1 | General |
| 10 | 2 | ======= |
| 11 | 3 | ... | ... |
libqpdf/QPDFWriter.cc
| ... | ... | @@ -120,6 +120,7 @@ QPDFWriter::setOutputFile(char const* description, FILE* file, bool close_file) |
| 120 | 120 | void |
| 121 | 121 | QPDFWriter::setOutputMemory() |
| 122 | 122 | { |
| 123 | + this->filename = "memory buffer"; | |
| 123 | 124 | this->buffer_pipeline = new Pl_Buffer("qpdf output"); |
| 124 | 125 | to_delete.push_back(this->buffer_pipeline); |
| 125 | 126 | initializePipelineStack(this->buffer_pipeline); |
| ... | ... | @@ -1492,7 +1493,7 @@ QPDFWriter::generateID() |
| 1492 | 1493 | std::string seed; |
| 1493 | 1494 | seed += QUtil::int_to_string((int)QUtil::get_current_time()); |
| 1494 | 1495 | seed += " QPDF "; |
| 1495 | - seed += filename; | |
| 1496 | + seed += this->filename; | |
| 1496 | 1497 | seed += " "; |
| 1497 | 1498 | if (trailer.hasKey("/Info")) |
| 1498 | 1499 | { | ... | ... |
qpdf/qtest/qpdf.test
| ... | ... | @@ -149,7 +149,7 @@ $td->runtest("remove page we don't have", |
| 149 | 149 | $td->NORMALIZE_NEWLINES); |
| 150 | 150 | # ---------- |
| 151 | 151 | $td->notify("--- Miscellaneous Tests ---"); |
| 152 | -$n_tests += 47; | |
| 152 | +$n_tests += 48; | |
| 153 | 153 | |
| 154 | 154 | $td->runtest("qpdf version", |
| 155 | 155 | {$td->COMMAND => "qpdf --version"}, |
| ... | ... | @@ -322,6 +322,11 @@ $td->runtest("swap and replace", |
| 322 | 322 | $td->runtest("check output", |
| 323 | 323 | {$td->FILE => "a.pdf"}, |
| 324 | 324 | {$td->FILE => "test14-out.pdf"}); |
| 325 | +# Test 14 also exercises writing to memory without static ID. | |
| 326 | +$td->runtest("check non-static ID version", | |
| 327 | + {$td->COMMAND => "./diff-ignore-ID-version a.pdf b.pdf"}, | |
| 328 | + {$td->STRING => "okay\n", $td->EXIT_STATUS => 0}, | |
| 329 | + $td->NORMALIZE_NEWLINES); | |
| 325 | 330 | |
| 326 | 331 | $td->runtest("C API info key functions", |
| 327 | 332 | {$td->COMMAND => "qpdf-ctest 16 minimal.pdf '' a.pdf"}, | ... | ... |
qpdf/test_driver.cc
| ... | ... | @@ -646,17 +646,22 @@ void runtest(int n, char const* filename1, char const* filename2) |
| 646 | 646 | } |
| 647 | 647 | |
| 648 | 648 | // Exercise writing to memory buffer |
| 649 | - QPDFWriter w(pdf); | |
| 650 | - w.setOutputMemory(); | |
| 651 | - w.setStaticID(true); | |
| 652 | - w.setStreamDataMode(qpdf_s_preserve); | |
| 653 | - w.write(); | |
| 654 | - Buffer* b = w.getBuffer(); | |
| 655 | - FILE* f = QUtil::fopen_wrapper(std::string("open a.pdf"), | |
| 656 | - fopen("a.pdf", "wb")); | |
| 657 | - fwrite(b->getBuffer(), b->getSize(), 1, f); | |
| 658 | - fclose(f); | |
| 659 | - delete b; | |
| 649 | + for (int i = 0; i < 2; ++i) | |
| 650 | + { | |
| 651 | + QPDFWriter w(pdf); | |
| 652 | + w.setOutputMemory(); | |
| 653 | + // Exercise setOutputMemory with and without static ID | |
| 654 | + w.setStaticID(i == 0); | |
| 655 | + w.setStreamDataMode(qpdf_s_preserve); | |
| 656 | + w.write(); | |
| 657 | + Buffer* b = w.getBuffer(); | |
| 658 | + std::string const filename = (i == 0 ? "a.pdf" : "b.pdf"); | |
| 659 | + FILE* f = QUtil::fopen_wrapper("open " + filename, | |
| 660 | + fopen(filename.c_str(), "wb")); | |
| 661 | + fwrite(b->getBuffer(), b->getSize(), 1, f); | |
| 662 | + fclose(f); | |
| 663 | + delete b; | |
| 664 | + } | |
| 660 | 665 | } |
| 661 | 666 | else if (n == 15) |
| 662 | 667 | { | ... | ... |