2
1
mirror of https://github.com/qpdf/qpdf.git synced 2025-01-05 08:02:11 +00:00

Tune QPDFWriter::unparseObject

This commit is contained in:
m-holger 2023-01-06 14:38:08 +00:00 committed by Jay Berkenbilt
parent 942a2c3f68
commit 59191ebbc4

View File

@ -23,6 +23,7 @@
#include <qpdf/RC4.hh> #include <qpdf/RC4.hh>
#include <algorithm> #include <algorithm>
#include <stdexcept>
#include <stdlib.h> #include <stdlib.h>
QPDFWriter::ProgressReporter::~ProgressReporter() QPDFWriter::ProgressReporter::~ProgressReporter()
@ -1482,13 +1483,13 @@ QPDFWriter::unparseObject(
{ {
QPDFObjGen old_og = object.getObjGen(); QPDFObjGen old_og = object.getObjGen();
int child_flags = flags & ~f_stream; int child_flags = flags & ~f_stream;
if (level < 0) {
std::string indent; throw std::logic_error("invalid level in QPDFWriter::unparseObject");
for (int i = 0; i < level; ++i) {
indent += " ";
} }
if (object.isArray()) { std::string const indent(static_cast<size_t>(2 * level), ' ');
if (auto const tc = object.getTypeCode(); tc == ::ot_array) {
// Note: PDF spec 1.4 implementation note 121 states that // Note: PDF spec 1.4 implementation note 121 states that
// Acrobat requires a space after the [ in the /H key of the // Acrobat requires a space after the [ in the /H key of the
// linearization parameter dictionary. We'll do this // linearization parameter dictionary. We'll do this
@ -1496,18 +1497,17 @@ QPDFWriter::unparseObject(
// doesn't make the files that much bigger. // doesn't make the files that much bigger.
writeString("["); writeString("[");
writeStringQDF("\n"); writeStringQDF("\n");
int n = object.getArrayNItems(); for (auto const& item: object.getArrayAsVector()) {
for (int i = 0; i < n; ++i) {
writeStringQDF(indent); writeStringQDF(indent);
writeStringQDF(" "); writeStringQDF(" ");
writeStringNoQDF(" "); writeStringNoQDF(" ");
unparseChild(object.getArrayItem(i), level + 1, child_flags); unparseChild(item, level + 1, child_flags);
writeStringQDF("\n"); writeStringQDF("\n");
} }
writeStringQDF(indent); writeStringQDF(indent);
writeStringNoQDF(" "); writeStringNoQDF(" ");
writeString("]"); writeString("]");
} else if (object.isDictionary()) { } else if (tc == ::ot_dictionary) {
// Make a shallow copy of this object so we can modify it // Make a shallow copy of this object so we can modify it
// safely without affecting the original. This code has logic // safely without affecting the original. This code has logic
// to skip certain keys in agreement with prepareFileForWrite // to skip certain keys in agreement with prepareFileForWrite
@ -1668,23 +1668,26 @@ QPDFWriter::unparseObject(
writeString("<<"); writeString("<<");
writeStringQDF("\n"); writeStringQDF("\n");
for (auto const& key: object.getKeys()) { for (auto& item: object.getDictAsMap()) {
writeStringQDF(indent); if (!item.second.isNull()) {
writeStringQDF(" "); auto const& key = item.first;
writeStringNoQDF(" "); writeStringQDF(indent);
writeString(QPDF_Name::normalizeName(key)); writeStringQDF(" ");
writeString(" "); writeStringNoQDF(" ");
if (key == "/Contents" && object.isDictionaryOfType("/Sig") && writeString(QPDF_Name::normalizeName(key));
object.hasKey("/ByteRange")) { writeString(" ");
QTC::TC("qpdf", "QPDFWriter no encryption sig contents"); if (key == "/Contents" && object.isDictionaryOfType("/Sig") &&
unparseChild( object.hasKey("/ByteRange")) {
object.getKey(key), QTC::TC("qpdf", "QPDFWriter no encryption sig contents");
level + 1, unparseChild(
child_flags | f_hex_string | f_no_encryption); item.second,
} else { level + 1,
unparseChild(object.getKey(key), level + 1, child_flags); child_flags | f_hex_string | f_no_encryption);
} else {
unparseChild(item.second, level + 1, child_flags);
}
writeStringQDF("\n");
} }
writeStringQDF("\n");
} }
if (flags & f_stream) { if (flags & f_stream) {
@ -1710,7 +1713,7 @@ QPDFWriter::unparseObject(
writeStringQDF(indent); writeStringQDF(indent);
writeStringNoQDF(" "); writeStringNoQDF(" ");
writeString(">>"); writeString(">>");
} else if (object.isStream()) { } else if (tc == ::ot_stream) {
// Write stream data to a buffer. // Write stream data to a buffer.
int new_id = this->m->obj_renumber[old_og]; int new_id = this->m->obj_renumber[old_og];
if (!this->m->direct_stream_lengths) { if (!this->m->direct_stream_lengths) {
@ -1752,7 +1755,7 @@ QPDFWriter::unparseObject(
this->m->added_newline = false; this->m->added_newline = false;
} }
writeString("endstream"); writeString("endstream");
} else if (object.isString()) { } else if (tc == ::ot_string) {
std::string val; std::string val;
if (this->m->encrypted && (!(flags & f_in_ostream)) && if (this->m->encrypted && (!(flags & f_in_ostream)) &&
(!(flags & f_no_encryption)) && (!this->m->cur_data_key.empty())) { (!(flags & f_no_encryption)) && (!this->m->cur_data_key.empty())) {