From 96767fb104589ee1152152edc803b5f979a8390f Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Sat, 31 Oct 2020 11:43:31 -0400 Subject: Fix foreign stream copying bug (fixes #478) This reverts an incorrect fix to #449 and codes it properly. The real problem was that we were looking at the local dictionaries rather than the foreign dictionaries when saving the foreign stream data. In the case of direct objects, these happened to be the same, but in the case of indirect objects, the object references could be pointing anywhere since object numbers don't match up between the old and new files. --- ChangeLog | 7 +++++++ libqpdf/QPDF.cc | 26 ++++++++++---------------- qpdf/qtest/qpdf/indirect-filter-out-0.pdf | Bin 2671 -> 2948 bytes qpdf/qtest/qpdf/indirect-filter-out-1.pdf | Bin 2671 -> 2948 bytes 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index de63df34..cdd64ee3 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 c0d6ecc6..ece80668 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 79e80601..04670951 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 0e8aac8e..b46fe920 100644 Binary files a/qpdf/qtest/qpdf/indirect-filter-out-1.pdf and b/qpdf/qtest/qpdf/indirect-filter-out-1.pdf differ -- cgit v1.2.3-54-g00ecf