From 96767fb104589ee1152152edc803b5f979a8390f Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Sat, 31 Oct 2020 11:43:31 -0400 Subject: [PATCH] Fix foreign stream copying bug (fixes #478) --- ChangeLog | 7 +++++++ libqpdf/QPDF.cc | 26 ++++++++++---------------- qpdf/qtest/qpdf/indirect-filter-out-0.pdf | Bin 2671 -> 0 bytes qpdf/qtest/qpdf/indirect-filter-out-1.pdf | Bin 2671 -> 0 bytes 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index de63df3..cdd64ee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2020-10-31 Jay Berkenbilt + + * My previous fix to #449 (handling foreign streams with indirect + objects in /Filter and/or /DecodeParms) was incorrect and caused + other problems. There is a now a correct fix to the original + problem. Fixes #478. + 2020-10-27 Jay Berkenbilt * 10.0.2: release diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc index c0d6ecc..ece8066 100644 --- a/libqpdf/QPDF.cc +++ b/libqpdf/QPDF.cc @@ -2317,8 +2317,7 @@ QPDF::reserveObjects(QPDFObjectHandle foreign, ObjCopier& obj_copier, if (foreign.isReserved()) { throw std::logic_error( - "QPDF: attempting to copy a foreign reserved object: " + - QUtil::int_to_string(foreign.getObjectID())); + "QPDF: attempting to copy a foreign reserved object"); } if (foreign.isPagesObject()) @@ -2491,16 +2490,6 @@ QPDF::replaceForeignIndirectObjects( } PointerHolder stream_buffer = stream->getStreamDataBuffer(); - // Note: at this stage, dictionary keys may still be reserved. - // We have to handle that explicitly if we access anything. - auto get_as_direct = [&old_dict] (std::string const& key) { - QPDFObjectHandle obj = old_dict.getKey(key); - obj.makeDirect(); - return obj; - }; - - QPDFObjectHandle filter = get_as_direct("/Filter"); - QPDFObjectHandle decode_parms = get_as_direct("/DecodeParms"); if ((foreign_stream_qpdf->m->immediate_copy_from) && (stream_buffer.getPointer() == 0)) { @@ -2510,7 +2499,8 @@ QPDF::replaceForeignIndirectObjects( // have to keep duplicating the memory. QTC::TC("qpdf", "QPDF immediate copy stream data"); foreign.replaceStreamData(foreign.getRawStreamData(), - filter, decode_parms); + old_dict.getKey("/Filter"), + old_dict.getKey("/DecodeParms")); stream_buffer = stream->getStreamDataBuffer(); } PointerHolder stream_provider = @@ -2518,7 +2508,9 @@ QPDF::replaceForeignIndirectObjects( if (stream_buffer.getPointer()) { QTC::TC("qpdf", "QPDF copy foreign stream with buffer"); - result.replaceStreamData(stream_buffer, filter, decode_parms); + result.replaceStreamData(stream_buffer, + dict.getKey("/Filter"), + dict.getKey("/DecodeParms")); } else if (stream_provider.getPointer()) { @@ -2527,7 +2519,8 @@ QPDF::replaceForeignIndirectObjects( this->m->copied_stream_data_provider->registerForeignStream( local_og, foreign); result.replaceStreamData(this->m->copied_streams, - filter, decode_parms); + dict.getKey("/Filter"), + dict.getKey("/DecodeParms")); } else { @@ -2545,7 +2538,8 @@ QPDF::replaceForeignIndirectObjects( this->m->copied_stream_data_provider->registerForeignStream( local_og, foreign_stream_data); result.replaceStreamData(this->m->copied_streams, - filter, decode_parms); + dict.getKey("/Filter"), + dict.getKey("/DecodeParms")); } } else diff --git a/qpdf/qtest/qpdf/indirect-filter-out-0.pdf b/qpdf/qtest/qpdf/indirect-filter-out-0.pdf index 79e8060..0467095 100644 Binary files a/qpdf/qtest/qpdf/indirect-filter-out-0.pdf and b/qpdf/qtest/qpdf/indirect-filter-out-0.pdf differ diff --git a/qpdf/qtest/qpdf/indirect-filter-out-1.pdf b/qpdf/qtest/qpdf/indirect-filter-out-1.pdf index 0e8aac8..b46fe92 100644 Binary files a/qpdf/qtest/qpdf/indirect-filter-out-1.pdf and b/qpdf/qtest/qpdf/indirect-filter-out-1.pdf differ -- libgit2 0.21.4