From f699aacb83a2c5ba906771178f619664b6bc18b3 Mon Sep 17 00:00:00 2001 From: m-holger Date: Sat, 9 Aug 2025 11:56:45 +0100 Subject: [PATCH] Refactor `QPDFWriter`: simplify array handling, replace `getArrayNItems` with `size`, and centralize `empty` checks. --- libqpdf/QPDFWriter.cc | 29 ++++++++++++----------------- qpdf/qpdf.testcov | 2 -- 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/libqpdf/QPDFWriter.cc b/libqpdf/QPDFWriter.cc index 90ba72f..81d894f 100644 --- a/libqpdf/QPDFWriter.cc +++ b/libqpdf/QPDFWriter.cc @@ -1538,9 +1538,7 @@ QPDFWriter::unparseObject( object.removeKey("/Length"); // If /DecodeParms is an empty list, remove it. - if (object.getKey("/DecodeParms").isArray() && - (0 == object.getKey("/DecodeParms").getArrayNItems())) { - QTC::TC("qpdf", "QPDFWriter remove empty DecodeParms"); + if (object.getKey("/DecodeParms").empty()) { object.removeKey("/DecodeParms"); } @@ -1558,22 +1556,19 @@ QPDFWriter::unparseObject( object.removeKey("/Filter"); object.removeKey("/DecodeParms"); } else { - int idx = -1; - for (int i = 0; i < filter.getArrayNItems(); ++i) { - QPDFObjectHandle item = filter.getArrayItem(i); + int idx = 0; + for (auto const& item: filter.as_array()) { if (item.isNameAndEquals("/Crypt")) { - idx = i; + // If filter is an array, then the code in QPDF_Stream has already + // verified that DecodeParms and Filters are arrays of the same + // length, but if they weren't for some reason, eraseItem does type + // and bounds checking. Fuzzing tells us that this can actually + // happen. + filter.eraseItem(idx); + decode_parms.eraseItem(idx); break; } - } - if (idx >= 0) { - // If filter is an array, then the code in QPDF_Stream has already - // verified that DecodeParms and Filters are arrays of the same length, - // but if they weren't for some reason, eraseItem does type and bounds - // checking. - QTC::TC("qpdf", "QPDFWriter remove Crypt"); - filter.eraseItem(idx); - decode_parms.eraseItem(idx); + ++idx; } } } @@ -1965,7 +1960,7 @@ QPDFWriter::initializeSpecialStreams() QPDFObjectHandle contents = page.getKey("/Contents"); std::vector contents_objects; if (contents.isArray()) { - int n = contents.getArrayNItems(); + int n = static_cast(contents.size()); for (int i = 0; i < n; ++i) { contents_objects.push_back(contents.getArrayItem(i).getObjGen()); } diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov index 1c99ad5..dd6dabf 100644 --- a/qpdf/qpdf.testcov +++ b/qpdf/qpdf.testcov @@ -239,7 +239,6 @@ QPDFWriter preserve ADBE 0 QPDF_encryption skip 0x28 0 QPDF_encrypt crypt array 0 QPDF_encryption CFM AESV3 0 -QPDFWriter remove Crypt 0 qpdf-c called qpdf_get_pdf_extension_level 0 qpdf-c called qpdf_set_r5_encryption_parameters 0 qpdf-c called qpdf_set_r6_encryption_parameters 0 @@ -423,7 +422,6 @@ QPDFPageObjectHelper externalize inline image 0 QPDFPageObjectHelper keep inline image 0 QPDFJob image optimize colorspace 0 QPDFJob image optimize bits per component 0 -QPDFWriter remove empty DecodeParms 0 QPDF xref skipped space 0 QPDF eof skipping spaces before xref 1 QPDF_encryption user matches owner V < 5 0 -- libgit2 0.21.4