Commit 34f557a83f75fd82377b3b6e21f4df589b24ac02

Authored by m-holger
Committed by GitHub
2 parents 5940c53f 99f3a7b5

Merge pull request #1257 from m-holger/fuzz

In QPDFWriter::willFilterStream remember unfilterable streams
Showing 1 changed file with 17 additions and 10 deletions
libqpdf/QPDFWriter.cc
... ... @@ -1236,8 +1236,8 @@ QPDFWriter::writeTrailer(
1236 1236 bool
1237 1237 QPDFWriter::willFilterStream(
1238 1238 QPDFObjectHandle stream,
1239   - bool& compress_stream,
1240   - bool& is_metadata,
  1239 + bool& compress_stream, // out only
  1240 + bool& is_metadata, // out only
1241 1241 std::shared_ptr<Buffer>* stream_data)
1242 1242 {
1243 1243 compress_stream = false;
... ... @@ -1299,9 +1299,10 @@ QPDFWriter::willFilterStream(
1299 1299 throw std::runtime_error(
1300 1300 "error while getting stream data for " + stream.unparse() + ": " + e.what());
1301 1301 }
1302   - if (filter && (!filtered)) {
  1302 + if (filter && !filtered) {
1303 1303 // Try again
1304 1304 filter = false;
  1305 + stream.setFilterOnWrite(false);
1305 1306 } else {
1306 1307 break;
1307 1308 }
... ... @@ -2543,14 +2544,20 @@ QPDFWriter::writeLinearized()
2543 2544 {
2544 2545 // Optimize file and enqueue objects in order
2545 2546  
2546   - auto skip_stream_parameters = [this](QPDFObjectHandle& stream) {
2547   - bool compress_stream;
2548   - bool is_metadata;
2549   - if (willFilterStream(stream, compress_stream, is_metadata, nullptr)) {
2550   - return 2;
2551   - } else {
2552   - return 1;
  2547 + std::map<int, int> stream_cache;
  2548 +
  2549 + auto skip_stream_parameters = [this, &stream_cache](QPDFObjectHandle& stream) {
  2550 + auto& result = stream_cache[stream.getObjectID()];
  2551 + if (result == 0) {
  2552 + bool compress_stream;
  2553 + bool is_metadata;
  2554 + if (willFilterStream(stream, compress_stream, is_metadata, nullptr)) {
  2555 + result = 2;
  2556 + } else {
  2557 + result = 1;
  2558 + }
2553 2559 }
  2560 + return result;
2554 2561 };
2555 2562  
2556 2563 QPDF::Writer::optimize(m->pdf, m->obj, skip_stream_parameters);
... ...