Commit 59191ebbc4c017385c6dbf69cb7d7823336f4509
Committed by
Jay Berkenbilt
1 parent
942a2c3f
Tune QPDFWriter::unparseObject
Showing
1 changed file
with
30 additions
and
27 deletions
libqpdf/QPDFWriter.cc
| @@ -23,6 +23,7 @@ | @@ -23,6 +23,7 @@ | ||
| 23 | #include <qpdf/RC4.hh> | 23 | #include <qpdf/RC4.hh> |
| 24 | 24 | ||
| 25 | #include <algorithm> | 25 | #include <algorithm> |
| 26 | +#include <stdexcept> | ||
| 26 | #include <stdlib.h> | 27 | #include <stdlib.h> |
| 27 | 28 | ||
| 28 | QPDFWriter::ProgressReporter::~ProgressReporter() | 29 | QPDFWriter::ProgressReporter::~ProgressReporter() |
| @@ -1482,13 +1483,13 @@ QPDFWriter::unparseObject( | @@ -1482,13 +1483,13 @@ QPDFWriter::unparseObject( | ||
| 1482 | { | 1483 | { |
| 1483 | QPDFObjGen old_og = object.getObjGen(); | 1484 | QPDFObjGen old_og = object.getObjGen(); |
| 1484 | int child_flags = flags & ~f_stream; | 1485 | int child_flags = flags & ~f_stream; |
| 1485 | - | ||
| 1486 | - std::string indent; | ||
| 1487 | - for (int i = 0; i < level; ++i) { | ||
| 1488 | - indent += " "; | 1486 | + if (level < 0) { |
| 1487 | + throw std::logic_error("invalid level in QPDFWriter::unparseObject"); | ||
| 1489 | } | 1488 | } |
| 1490 | 1489 | ||
| 1491 | - if (object.isArray()) { | 1490 | + std::string const indent(static_cast<size_t>(2 * level), ' '); |
| 1491 | + | ||
| 1492 | + if (auto const tc = object.getTypeCode(); tc == ::ot_array) { | ||
| 1492 | // Note: PDF spec 1.4 implementation note 121 states that | 1493 | // Note: PDF spec 1.4 implementation note 121 states that |
| 1493 | // Acrobat requires a space after the [ in the /H key of the | 1494 | // Acrobat requires a space after the [ in the /H key of the |
| 1494 | // linearization parameter dictionary. We'll do this | 1495 | // linearization parameter dictionary. We'll do this |
| @@ -1496,18 +1497,17 @@ QPDFWriter::unparseObject( | @@ -1496,18 +1497,17 @@ QPDFWriter::unparseObject( | ||
| 1496 | // doesn't make the files that much bigger. | 1497 | // doesn't make the files that much bigger. |
| 1497 | writeString("["); | 1498 | writeString("["); |
| 1498 | writeStringQDF("\n"); | 1499 | writeStringQDF("\n"); |
| 1499 | - int n = object.getArrayNItems(); | ||
| 1500 | - for (int i = 0; i < n; ++i) { | 1500 | + for (auto const& item: object.getArrayAsVector()) { |
| 1501 | writeStringQDF(indent); | 1501 | writeStringQDF(indent); |
| 1502 | writeStringQDF(" "); | 1502 | writeStringQDF(" "); |
| 1503 | writeStringNoQDF(" "); | 1503 | writeStringNoQDF(" "); |
| 1504 | - unparseChild(object.getArrayItem(i), level + 1, child_flags); | 1504 | + unparseChild(item, level + 1, child_flags); |
| 1505 | writeStringQDF("\n"); | 1505 | writeStringQDF("\n"); |
| 1506 | } | 1506 | } |
| 1507 | writeStringQDF(indent); | 1507 | writeStringQDF(indent); |
| 1508 | writeStringNoQDF(" "); | 1508 | writeStringNoQDF(" "); |
| 1509 | writeString("]"); | 1509 | writeString("]"); |
| 1510 | - } else if (object.isDictionary()) { | 1510 | + } else if (tc == ::ot_dictionary) { |
| 1511 | // Make a shallow copy of this object so we can modify it | 1511 | // Make a shallow copy of this object so we can modify it |
| 1512 | // safely without affecting the original. This code has logic | 1512 | // safely without affecting the original. This code has logic |
| 1513 | // to skip certain keys in agreement with prepareFileForWrite | 1513 | // to skip certain keys in agreement with prepareFileForWrite |
| @@ -1668,23 +1668,26 @@ QPDFWriter::unparseObject( | @@ -1668,23 +1668,26 @@ QPDFWriter::unparseObject( | ||
| 1668 | writeString("<<"); | 1668 | writeString("<<"); |
| 1669 | writeStringQDF("\n"); | 1669 | writeStringQDF("\n"); |
| 1670 | 1670 | ||
| 1671 | - for (auto const& key: object.getKeys()) { | ||
| 1672 | - writeStringQDF(indent); | ||
| 1673 | - writeStringQDF(" "); | ||
| 1674 | - writeStringNoQDF(" "); | ||
| 1675 | - writeString(QPDF_Name::normalizeName(key)); | ||
| 1676 | - writeString(" "); | ||
| 1677 | - if (key == "/Contents" && object.isDictionaryOfType("/Sig") && | ||
| 1678 | - object.hasKey("/ByteRange")) { | ||
| 1679 | - QTC::TC("qpdf", "QPDFWriter no encryption sig contents"); | ||
| 1680 | - unparseChild( | ||
| 1681 | - object.getKey(key), | ||
| 1682 | - level + 1, | ||
| 1683 | - child_flags | f_hex_string | f_no_encryption); | ||
| 1684 | - } else { | ||
| 1685 | - unparseChild(object.getKey(key), level + 1, child_flags); | 1671 | + for (auto& item: object.getDictAsMap()) { |
| 1672 | + if (!item.second.isNull()) { | ||
| 1673 | + auto const& key = item.first; | ||
| 1674 | + writeStringQDF(indent); | ||
| 1675 | + writeStringQDF(" "); | ||
| 1676 | + writeStringNoQDF(" "); | ||
| 1677 | + writeString(QPDF_Name::normalizeName(key)); | ||
| 1678 | + writeString(" "); | ||
| 1679 | + if (key == "/Contents" && object.isDictionaryOfType("/Sig") && | ||
| 1680 | + object.hasKey("/ByteRange")) { | ||
| 1681 | + QTC::TC("qpdf", "QPDFWriter no encryption sig contents"); | ||
| 1682 | + unparseChild( | ||
| 1683 | + item.second, | ||
| 1684 | + level + 1, | ||
| 1685 | + child_flags | f_hex_string | f_no_encryption); | ||
| 1686 | + } else { | ||
| 1687 | + unparseChild(item.second, level + 1, child_flags); | ||
| 1688 | + } | ||
| 1689 | + writeStringQDF("\n"); | ||
| 1686 | } | 1690 | } |
| 1687 | - writeStringQDF("\n"); | ||
| 1688 | } | 1691 | } |
| 1689 | 1692 | ||
| 1690 | if (flags & f_stream) { | 1693 | if (flags & f_stream) { |
| @@ -1710,7 +1713,7 @@ QPDFWriter::unparseObject( | @@ -1710,7 +1713,7 @@ QPDFWriter::unparseObject( | ||
| 1710 | writeStringQDF(indent); | 1713 | writeStringQDF(indent); |
| 1711 | writeStringNoQDF(" "); | 1714 | writeStringNoQDF(" "); |
| 1712 | writeString(">>"); | 1715 | writeString(">>"); |
| 1713 | - } else if (object.isStream()) { | 1716 | + } else if (tc == ::ot_stream) { |
| 1714 | // Write stream data to a buffer. | 1717 | // Write stream data to a buffer. |
| 1715 | int new_id = this->m->obj_renumber[old_og]; | 1718 | int new_id = this->m->obj_renumber[old_og]; |
| 1716 | if (!this->m->direct_stream_lengths) { | 1719 | if (!this->m->direct_stream_lengths) { |
| @@ -1752,7 +1755,7 @@ QPDFWriter::unparseObject( | @@ -1752,7 +1755,7 @@ QPDFWriter::unparseObject( | ||
| 1752 | this->m->added_newline = false; | 1755 | this->m->added_newline = false; |
| 1753 | } | 1756 | } |
| 1754 | writeString("endstream"); | 1757 | writeString("endstream"); |
| 1755 | - } else if (object.isString()) { | 1758 | + } else if (tc == ::ot_string) { |
| 1756 | std::string val; | 1759 | std::string val; |
| 1757 | if (this->m->encrypted && (!(flags & f_in_ostream)) && | 1760 | if (this->m->encrypted && (!(flags & f_in_ostream)) && |
| 1758 | (!(flags & f_no_encryption)) && (!this->m->cur_data_key.empty())) { | 1761 | (!(flags & f_no_encryption)) && (!this->m->cur_data_key.empty())) { |