From 8d2b29ef988aa86489e36be50fa881335b81363e Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Thu, 6 Sep 2012 14:39:06 -0400 Subject: Fix segmentation fault with use of QPDFWriter::setOutputMemory --- ChangeLog | 7 +++++++ TODO | 8 -------- libqpdf/QPDFWriter.cc | 3 ++- qpdf/qtest/qpdf.test | 7 ++++++- qpdf/test_driver.cc | 27 ++++++++++++++++----------- 5 files changed, 31 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5afb6871..ec165929 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2012-09-06 Jay Berkenbilt + + * Bug fix: Writing after calling QPDFWriter::setOutputMemory() + would cause a segmentation fault because of an internal field not + being initialized, rendering that method useless. This has been + corrected. + 2012-08-11 Jay Berkenbilt * 3.0.1: release diff --git a/TODO b/TODO index 90efdae7..ff3ecc83 100644 --- a/TODO +++ b/TODO @@ -1,11 +1,3 @@ -3.0.2 -===== - - * QPDFWriter::setOutputMemory segfaults without setStaticID because - it doesn't set this->filename. Be sure to have a test case that - exercises this. Check the function that sets the ID carefully to - make sure other cases aren't missed. - General ======= diff --git a/libqpdf/QPDFWriter.cc b/libqpdf/QPDFWriter.cc index c244cf30..19ab1359 100644 --- a/libqpdf/QPDFWriter.cc +++ b/libqpdf/QPDFWriter.cc @@ -120,6 +120,7 @@ QPDFWriter::setOutputFile(char const* description, FILE* file, bool close_file) void QPDFWriter::setOutputMemory() { + this->filename = "memory buffer"; this->buffer_pipeline = new Pl_Buffer("qpdf output"); to_delete.push_back(this->buffer_pipeline); initializePipelineStack(this->buffer_pipeline); @@ -1492,7 +1493,7 @@ QPDFWriter::generateID() std::string seed; seed += QUtil::int_to_string((int)QUtil::get_current_time()); seed += " QPDF "; - seed += filename; + seed += this->filename; seed += " "; if (trailer.hasKey("/Info")) { diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test index fda92b30..b2ee28eb 100644 --- a/qpdf/qtest/qpdf.test +++ b/qpdf/qtest/qpdf.test @@ -149,7 +149,7 @@ $td->runtest("remove page we don't have", $td->NORMALIZE_NEWLINES); # ---------- $td->notify("--- Miscellaneous Tests ---"); -$n_tests += 47; +$n_tests += 48; $td->runtest("qpdf version", {$td->COMMAND => "qpdf --version"}, @@ -322,6 +322,11 @@ $td->runtest("swap and replace", $td->runtest("check output", {$td->FILE => "a.pdf"}, {$td->FILE => "test14-out.pdf"}); +# Test 14 also exercises writing to memory without static ID. +$td->runtest("check non-static ID version", + {$td->COMMAND => "./diff-ignore-ID-version a.pdf b.pdf"}, + {$td->STRING => "okay\n", $td->EXIT_STATUS => 0}, + $td->NORMALIZE_NEWLINES); $td->runtest("C API info key functions", {$td->COMMAND => "qpdf-ctest 16 minimal.pdf '' a.pdf"}, diff --git a/qpdf/test_driver.cc b/qpdf/test_driver.cc index 3861c403..b277cdf1 100644 --- a/qpdf/test_driver.cc +++ b/qpdf/test_driver.cc @@ -646,17 +646,22 @@ void runtest(int n, char const* filename1, char const* filename2) } // Exercise writing to memory buffer - QPDFWriter w(pdf); - w.setOutputMemory(); - w.setStaticID(true); - w.setStreamDataMode(qpdf_s_preserve); - w.write(); - Buffer* b = w.getBuffer(); - FILE* f = QUtil::fopen_wrapper(std::string("open a.pdf"), - fopen("a.pdf", "wb")); - fwrite(b->getBuffer(), b->getSize(), 1, f); - fclose(f); - delete b; + for (int i = 0; i < 2; ++i) + { + QPDFWriter w(pdf); + w.setOutputMemory(); + // Exercise setOutputMemory with and without static ID + w.setStaticID(i == 0); + w.setStreamDataMode(qpdf_s_preserve); + w.write(); + Buffer* b = w.getBuffer(); + std::string const filename = (i == 0 ? "a.pdf" : "b.pdf"); + FILE* f = QUtil::fopen_wrapper("open " + filename, + fopen(filename.c_str(), "wb")); + fwrite(b->getBuffer(), b->getSize(), 1, f); + fclose(f); + delete b; + } } else if (n == 15) { -- cgit v1.2.3-54-g00ecf