diff --git a/ChangeLog b/ChangeLog index f1291515..f2e4551e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2017-07-29 Jay Berkenbilt + * Handle zlib data errors when decoding streams. Fixes #106. + * Improve handling of files where the "stream" keyword is not followed by proper line terminators. Fixes #104. diff --git a/libqpdf/Pl_Flate.cc b/libqpdf/Pl_Flate.cc index 297cdac7..535383c9 100644 --- a/libqpdf/Pl_Flate.cc +++ b/libqpdf/Pl_Flate.cc @@ -157,28 +157,36 @@ Pl_Flate::handleData(unsigned char* data, int len, int flush) void Pl_Flate::finish() { - if (this->outbuf) + try { - if (this->initialized) - { - z_stream& zstream = *(static_cast(this->zdata)); - unsigned char buf[1]; - buf[0] = '\0'; - handleData(buf, 0, Z_FINISH); - int err = Z_OK; - if (action == a_deflate) - { - err = deflateEnd(&zstream); - } - else - { - err = inflateEnd(&zstream); - } - checkError("End", err); - } + if (this->outbuf) + { + if (this->initialized) + { + z_stream& zstream = *(static_cast(this->zdata)); + unsigned char buf[1]; + buf[0] = '\0'; + handleData(buf, 0, Z_FINISH); + int err = Z_OK; + if (action == a_deflate) + { + err = deflateEnd(&zstream); + } + else + { + err = inflateEnd(&zstream); + } + checkError("End", err); + } - delete [] this->outbuf; - this->outbuf = 0; + delete [] this->outbuf; + this->outbuf = 0; + } + } + catch (std::exception& e) + { + this->getNext()->finish(); + throw e; } this->getNext()->finish(); } diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc index 56555261..bda87f01 100644 --- a/libqpdf/QPDF.cc +++ b/libqpdf/QPDF.cc @@ -2206,7 +2206,7 @@ QPDF::pipeStreamData(int objid, int generation, warn(e); } } - catch (std::runtime_error& e) + catch (std::exception& e) { if (! suppress_warnings) { @@ -2218,7 +2218,14 @@ QPDF::pipeStreamData(int objid, int generation, QUtil::int_to_string(generation) + ": " + e.what())); } } - pipeline->finish(); + try + { + pipeline->finish(); + } + catch (std::exception&) + { + // ignore + } return success; } diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test index 14abda34..3530035c 100644 --- a/qpdf/qtest/qpdf.test +++ b/qpdf/qtest/qpdf.test @@ -206,7 +206,7 @@ $td->runtest("remove page we don't have", show_ntests(); # ---------- $td->notify("--- Miscellaneous Tests ---"); -$n_tests += 88; +$n_tests += 89; $td->runtest("qpdf version", {$td->COMMAND => "qpdf --version"}, @@ -229,6 +229,7 @@ foreach my $d ( ["118", "other infinite loop", 2], ["119", "other infinite loop", 3], ["120", "other infinite loop", 3], + ["106", "zlib data error", 3], ) { my ($n, $description, $exit_status) = @$d; diff --git a/qpdf/qtest/qpdf/issue-106.out b/qpdf/qtest/qpdf/issue-106.out new file mode 100644 index 00000000..80ccdf74 --- /dev/null +++ b/qpdf/qtest/qpdf/issue-106.out @@ -0,0 +1,4 @@ +WARNING: issue-106.pdf (file position 56627): error decoding stream data for object 29 0: stream inflate: inflate: data: incorrect data check +WARNING: issue-106.pdf (file position 64303): error decoding stream data for object 30 0: stream inflate: inflate: data: incorrect data check +WARNING: issue-106.pdf (file position 67427): error decoding stream data for object 31 0: stream inflate: inflate: data: incorrect data check +qpdf: operation succeeded with warnings; resulting file may have some problems diff --git a/qpdf/qtest/qpdf/issue-106.pdf b/qpdf/qtest/qpdf/issue-106.pdf new file mode 100644 index 00000000..c11ebc2b Binary files /dev/null and b/qpdf/qtest/qpdf/issue-106.pdf differ