Commit 5696a507b6dacf34d066810a3f2fca3525eb02f5
Committed by
GitHub
Merge pull request #731 from m-holger/og_unparse
Tidy QPDFObjGen related code
Showing
22 changed files
with
291 additions
and
390 deletions
examples/pdf-create.cc
| ... | ... | @@ -29,8 +29,7 @@ class ImageProvider: public QPDFObjectHandle::StreamDataProvider |
| 29 | 29 | public: |
| 30 | 30 | ImageProvider(std::string const& color_space, std::string const& filter); |
| 31 | 31 | virtual ~ImageProvider() = default; |
| 32 | - virtual void | |
| 33 | - provideStreamData(int objid, int generation, Pipeline* pipeline); | |
| 32 | + virtual void provideStreamData(QPDFObjGen const&, Pipeline* pipeline); | |
| 34 | 33 | size_t getWidth() const; |
| 35 | 34 | size_t getHeight() const; |
| 36 | 35 | |
| ... | ... | @@ -93,7 +92,7 @@ ImageProvider::getHeight() const |
| 93 | 92 | } |
| 94 | 93 | |
| 95 | 94 | void |
| 96 | -ImageProvider::provideStreamData(int objid, int generation, Pipeline* pipeline) | |
| 95 | +ImageProvider::provideStreamData(QPDFObjGen const&, Pipeline* pipeline) | |
| 97 | 96 | { |
| 98 | 97 | std::vector<std::shared_ptr<Pipeline>> to_delete; |
| 99 | 98 | Pipeline* p = pipeline; |
| ... | ... | @@ -292,7 +291,7 @@ check( |
| 292 | 291 | ImageProvider* p = new ImageProvider(desired_color_space, "null"); |
| 293 | 292 | std::shared_ptr<QPDFObjectHandle::StreamDataProvider> provider(p); |
| 294 | 293 | Pl_Buffer b_p("get image data"); |
| 295 | - provider->provideStreamData(0, 0, &b_p); | |
| 294 | + provider->provideStreamData(QPDFObjGen(), &b_p); | |
| 296 | 295 | std::shared_ptr<Buffer> desired_data(b_p.getBuffer()); |
| 297 | 296 | |
| 298 | 297 | if (desired_data->getSize() != actual_data->getSize()) { | ... | ... |
examples/pdf-custom-filter.cc
| ... | ... | @@ -201,7 +201,7 @@ class StreamReplacer: public QPDFObjectHandle::StreamDataProvider |
| 201 | 201 | StreamReplacer(QPDF* pdf); |
| 202 | 202 | virtual ~StreamReplacer() = default; |
| 203 | 203 | virtual void |
| 204 | - provideStreamData(int objid, int generation, Pipeline* pipeline) override; | |
| 204 | + provideStreamData(QPDFObjGen const& og, Pipeline* pipeline) override; | |
| 205 | 205 | |
| 206 | 206 | void registerStream( |
| 207 | 207 | QPDFObjectHandle stream, |
| ... | ... | @@ -384,9 +384,8 @@ StreamReplacer::registerStream( |
| 384 | 384 | } |
| 385 | 385 | |
| 386 | 386 | void |
| 387 | -StreamReplacer::provideStreamData(int objid, int generation, Pipeline* pipeline) | |
| 387 | +StreamReplacer::provideStreamData(QPDFObjGen const& og, Pipeline* pipeline) | |
| 388 | 388 | { |
| 389 | - QPDFObjGen og(objid, generation); | |
| 390 | 389 | QPDFObjectHandle orig = this->copied_streams[og]; |
| 391 | 390 | // call maybeReplace again, this time with the pipeline and no |
| 392 | 391 | // dict_updates. In this mode, maybeReplace doesn't make any | ... | ... |
examples/pdf-invert-images.cc
| ... | ... | @@ -35,7 +35,7 @@ class ImageInverter: public QPDFObjectHandle::StreamDataProvider |
| 35 | 35 | public: |
| 36 | 36 | virtual ~ImageInverter() = default; |
| 37 | 37 | virtual void |
| 38 | - provideStreamData(int objid, int generation, Pipeline* pipeline) override; | |
| 38 | + provideStreamData(QPDFObjGen const& og, Pipeline* pipeline) override; | |
| 39 | 39 | |
| 40 | 40 | void registerImage( |
| 41 | 41 | QPDFObjectHandle image, |
| ... | ... | @@ -82,12 +82,11 @@ ImageInverter::registerImage( |
| 82 | 82 | } |
| 83 | 83 | |
| 84 | 84 | void |
| 85 | -ImageInverter::provideStreamData(int objid, int generation, Pipeline* pipeline) | |
| 85 | +ImageInverter::provideStreamData(QPDFObjGen const& og, Pipeline* pipeline) | |
| 86 | 86 | { |
| 87 | 87 | // Use the object and generation number supplied to look up the |
| 88 | 88 | // image data. Then invert the image data and write the inverted |
| 89 | 89 | // data to the pipeline. |
| 90 | - QPDFObjGen og(objid, generation); | |
| 91 | 90 | std::shared_ptr<Buffer> data = |
| 92 | 91 | this->copied_images[og].getStreamData(qpdf_dl_all); |
| 93 | 92 | size_t size = data->getSize(); | ... | ... |
include/qpdf/QPDF.hh
| ... | ... | @@ -815,9 +815,9 @@ class QPDF |
| 815 | 815 | |
| 816 | 816 | private: |
| 817 | 817 | static std::shared_ptr<QPDFObject> |
| 818 | - resolve(QPDF* qpdf, int objid, int generation) | |
| 818 | + resolve(QPDF* qpdf, QPDFObjGen const& og) | |
| 819 | 819 | { |
| 820 | - return qpdf->resolve(objid, generation); | |
| 820 | + return qpdf->resolve(og); | |
| 821 | 821 | } |
| 822 | 822 | static bool |
| 823 | 823 | objectChanged( |
| ... | ... | @@ -879,8 +879,7 @@ class QPDF |
| 879 | 879 | static bool |
| 880 | 880 | pipeStreamData( |
| 881 | 881 | QPDF* qpdf, |
| 882 | - int objid, | |
| 883 | - int generation, | |
| 882 | + QPDFObjGen const& og, | |
| 884 | 883 | qpdf_offset_t offset, |
| 885 | 884 | size_t length, |
| 886 | 885 | QPDFObjectHandle dict, |
| ... | ... | @@ -889,8 +888,7 @@ class QPDF |
| 889 | 888 | bool will_retry) |
| 890 | 889 | { |
| 891 | 890 | return qpdf->pipeStreamData( |
| 892 | - objid, | |
| 893 | - generation, | |
| 891 | + og, | |
| 894 | 892 | offset, |
| 895 | 893 | length, |
| 896 | 894 | dict, |
| ... | ... | @@ -959,8 +957,7 @@ class QPDF |
| 959 | 957 | std::string user_password; |
| 960 | 958 | std::string encryption_key; |
| 961 | 959 | std::string cached_object_encryption_key; |
| 962 | - int cached_key_objid; | |
| 963 | - int cached_key_generation; | |
| 960 | + QPDFObjGen cached_key_og; | |
| 964 | 961 | bool user_password_matched; |
| 965 | 962 | bool owner_password_matched; |
| 966 | 963 | }; |
| ... | ... | @@ -973,8 +970,7 @@ class QPDF |
| 973 | 970 | ForeignStreamData( |
| 974 | 971 | std::shared_ptr<EncryptionParameters> encp, |
| 975 | 972 | std::shared_ptr<InputSource> file, |
| 976 | - int foreign_objid, | |
| 977 | - int foreign_generation, | |
| 973 | + QPDFObjGen const& foreign_og, | |
| 978 | 974 | qpdf_offset_t offset, |
| 979 | 975 | size_t length, |
| 980 | 976 | QPDFObjectHandle local_dict); |
| ... | ... | @@ -982,8 +978,7 @@ class QPDF |
| 982 | 978 | private: |
| 983 | 979 | std::shared_ptr<EncryptionParameters> encp; |
| 984 | 980 | std::shared_ptr<InputSource> file; |
| 985 | - int foreign_objid; | |
| 986 | - int foreign_generation; | |
| 981 | + QPDFObjGen foreign_og; | |
| 987 | 982 | qpdf_offset_t offset; |
| 988 | 983 | size_t length; |
| 989 | 984 | QPDFObjectHandle local_dict; |
| ... | ... | @@ -995,8 +990,7 @@ class QPDF |
| 995 | 990 | CopiedStreamDataProvider(QPDF& destination_qpdf); |
| 996 | 991 | virtual ~CopiedStreamDataProvider() = default; |
| 997 | 992 | virtual bool provideStreamData( |
| 998 | - int objid, | |
| 999 | - int generation, | |
| 993 | + QPDFObjGen const& og, | |
| 1000 | 994 | Pipeline* pipeline, |
| 1001 | 995 | bool suppress_warnings, |
| 1002 | 996 | bool will_retry) override; |
| ... | ... | @@ -1017,14 +1011,13 @@ class QPDF |
| 1017 | 1011 | friend class QPDF; |
| 1018 | 1012 | |
| 1019 | 1013 | public: |
| 1020 | - StringDecrypter(QPDF* qpdf, int objid, int gen); | |
| 1014 | + StringDecrypter(QPDF* qpdf, QPDFObjGen const& og); | |
| 1021 | 1015 | virtual ~StringDecrypter() = default; |
| 1022 | 1016 | virtual void decryptString(std::string& val); |
| 1023 | 1017 | |
| 1024 | 1018 | private: |
| 1025 | 1019 | QPDF* qpdf; |
| 1026 | - int objid; | |
| 1027 | - int gen; | |
| 1020 | + QPDFObjGen og; | |
| 1028 | 1021 | }; |
| 1029 | 1022 | |
| 1030 | 1023 | class ResolveRecorder |
| ... | ... | @@ -1127,17 +1120,15 @@ class QPDF |
| 1127 | 1120 | void insertXrefEntry( |
| 1128 | 1121 | int obj, int f0, qpdf_offset_t f1, int f2, bool overwrite = false); |
| 1129 | 1122 | void setLastObjectDescription( |
| 1130 | - std::string const& description, int objid, int generation); | |
| 1123 | + std::string const& description, QPDFObjGen const& og); | |
| 1131 | 1124 | QPDFObjectHandle readObject( |
| 1132 | 1125 | std::shared_ptr<InputSource>, |
| 1133 | 1126 | std::string const& description, |
| 1134 | - int objid, | |
| 1135 | - int generation, | |
| 1127 | + QPDFObjGen const& og, | |
| 1136 | 1128 | bool in_object_stream); |
| 1137 | 1129 | size_t recoverStreamLength( |
| 1138 | 1130 | std::shared_ptr<InputSource> input, |
| 1139 | - int objid, | |
| 1140 | - int generation, | |
| 1131 | + QPDFObjGen const& og, | |
| 1141 | 1132 | qpdf_offset_t stream_offset); |
| 1142 | 1133 | QPDFTokenizer::Token |
| 1143 | 1134 | readToken(std::shared_ptr<InputSource>, size_t max_len = 0); |
| ... | ... | @@ -1146,21 +1137,18 @@ class QPDF |
| 1146 | 1137 | bool attempt_recovery, |
| 1147 | 1138 | qpdf_offset_t offset, |
| 1148 | 1139 | std::string const& description, |
| 1149 | - int exp_objid, | |
| 1150 | - int exp_generation, | |
| 1151 | - int& act_objid, | |
| 1152 | - int& act_generation); | |
| 1140 | + QPDFObjGen const& exp_og, | |
| 1141 | + QPDFObjGen& og); | |
| 1153 | 1142 | bool objectChanged(QPDFObjGen const& og, std::shared_ptr<QPDFObject>& oph); |
| 1154 | - std::shared_ptr<QPDFObject> resolve(int objid, int generation); | |
| 1143 | + std::shared_ptr<QPDFObject> resolve(QPDFObjGen const& og); | |
| 1155 | 1144 | void resolveObjectsInStream(int obj_stream_number); |
| 1156 | 1145 | void stopOnError(std::string const& message); |
| 1157 | - QPDFObjectHandle reserveObjectIfNotExists(int objid, int gen); | |
| 1158 | - QPDFObjectHandle reserveStream(int objid, int gen); | |
| 1146 | + QPDFObjectHandle reserveObjectIfNotExists(QPDFObjGen const& og); | |
| 1147 | + QPDFObjectHandle reserveStream(QPDFObjGen const& og); | |
| 1159 | 1148 | |
| 1160 | 1149 | // Calls finish() on the pipeline when done but does not delete it |
| 1161 | 1150 | bool pipeStreamData( |
| 1162 | - int objid, | |
| 1163 | - int generation, | |
| 1151 | + QPDFObjGen const& og, | |
| 1164 | 1152 | qpdf_offset_t offset, |
| 1165 | 1153 | size_t length, |
| 1166 | 1154 | QPDFObjectHandle dict, |
| ... | ... | @@ -1176,8 +1164,7 @@ class QPDF |
| 1176 | 1164 | std::shared_ptr<QPDF::EncryptionParameters> encp, |
| 1177 | 1165 | std::shared_ptr<InputSource> file, |
| 1178 | 1166 | QPDF& qpdf_for_warning, |
| 1179 | - int objid, | |
| 1180 | - int generation, | |
| 1167 | + QPDFObjGen const& og, | |
| 1181 | 1168 | qpdf_offset_t offset, |
| 1182 | 1169 | size_t length, |
| 1183 | 1170 | QPDFObjectHandle dict, |
| ... | ... | @@ -1230,10 +1217,9 @@ class QPDF |
| 1230 | 1217 | void initializeEncryption(); |
| 1231 | 1218 | static std::string getKeyForObject( |
| 1232 | 1219 | std::shared_ptr<EncryptionParameters> encp, |
| 1233 | - int objid, | |
| 1234 | - int generation, | |
| 1220 | + QPDFObjGen const& og, | |
| 1235 | 1221 | bool use_aes); |
| 1236 | - void decryptString(std::string&, int objid, int generation); | |
| 1222 | + void decryptString(std::string&, QPDFObjGen const& og); | |
| 1237 | 1223 | static std::string compute_encryption_key_from_password( |
| 1238 | 1224 | std::string const& password, EncryptionData const& data); |
| 1239 | 1225 | static std::string recover_encryption_key_with_password( |
| ... | ... | @@ -1247,8 +1233,7 @@ class QPDF |
| 1247 | 1233 | std::shared_ptr<InputSource> file, |
| 1248 | 1234 | QPDF& qpdf_for_warning, |
| 1249 | 1235 | Pipeline*& pipeline, |
| 1250 | - int objid, | |
| 1251 | - int generation, | |
| 1236 | + QPDFObjGen const& og, | |
| 1252 | 1237 | QPDFObjectHandle& stream_dict, |
| 1253 | 1238 | std::vector<std::shared_ptr<Pipeline>>& heap); |
| 1254 | 1239 | |
| ... | ... | @@ -1571,7 +1556,6 @@ class QPDF |
| 1571 | 1556 | void dumpHSharedObject(); |
| 1572 | 1557 | void dumpHGeneric(HGeneric&); |
| 1573 | 1558 | qpdf_offset_t adjusted_offset(qpdf_offset_t offset); |
| 1574 | - QPDFObjectHandle objGenToIndirect(QPDFObjGen const&); | |
| 1575 | 1559 | void |
| 1576 | 1560 | calculateLinearizationData(std::map<int, int> const& object_stream_data); |
| 1577 | 1561 | void pushOutlinesToPart( | ... | ... |
include/qpdf/QPDFObjGen.hh
| ... | ... | @@ -23,7 +23,6 @@ |
| 23 | 23 | #define QPDFOBJGEN_HH |
| 24 | 24 | |
| 25 | 25 | #include <qpdf/DLL.h> |
| 26 | -#include <qpdf/QUtil.hh> | |
| 27 | 26 | #include <iostream> |
| 28 | 27 | |
| 29 | 28 | // This class represents an object ID and generation pair. It is |
| ... | ... | @@ -39,7 +38,7 @@ class QPDFObjGen |
| 39 | 38 | { |
| 40 | 39 | } |
| 41 | 40 | QPDF_DLL |
| 42 | - QPDFObjGen(int obj, int gen) : | |
| 41 | + explicit QPDFObjGen(int obj, int gen) : | |
| 43 | 42 | obj(obj), |
| 44 | 43 | gen(gen) |
| 45 | 44 | { |
| ... | ... | @@ -48,13 +47,19 @@ class QPDFObjGen |
| 48 | 47 | bool |
| 49 | 48 | operator<(QPDFObjGen const& rhs) const |
| 50 | 49 | { |
| 51 | - return ((obj < rhs.obj) || ((obj == rhs.obj) && (gen < rhs.gen))); | |
| 50 | + return (obj < rhs.obj) || ((obj == rhs.obj) && (gen < rhs.gen)); | |
| 52 | 51 | } |
| 53 | 52 | QPDF_DLL |
| 54 | 53 | bool |
| 55 | 54 | operator==(QPDFObjGen const& rhs) const |
| 56 | 55 | { |
| 57 | - return ((obj == rhs.obj) && (gen == rhs.gen)); | |
| 56 | + return (obj == rhs.obj) && (gen == rhs.gen); | |
| 57 | + } | |
| 58 | + QPDF_DLL | |
| 59 | + bool | |
| 60 | + operator!=(QPDFObjGen const& rhs) const | |
| 61 | + { | |
| 62 | + return (obj != rhs.obj) || (gen != rhs.gen); | |
| 58 | 63 | } |
| 59 | 64 | QPDF_DLL |
| 60 | 65 | int |
| ... | ... | @@ -69,18 +74,15 @@ class QPDFObjGen |
| 69 | 74 | return gen; |
| 70 | 75 | } |
| 71 | 76 | QPDF_DLL |
| 72 | - std::string | |
| 73 | - unparse() const | |
| 77 | + bool | |
| 78 | + isIndirect() const | |
| 74 | 79 | { |
| 75 | - return QUtil::int_to_string(obj) + "," + QUtil::int_to_string(gen); | |
| 80 | + return obj != 0; | |
| 76 | 81 | } |
| 77 | 82 | QPDF_DLL |
| 78 | - friend std::ostream& | |
| 79 | - operator<<(std::ostream& os, const QPDFObjGen& og) | |
| 80 | - { | |
| 81 | - os << og.obj << "," << og.gen; | |
| 82 | - return os; | |
| 83 | - } | |
| 83 | + std::string unparse(char separator = ',') const; | |
| 84 | + QPDF_DLL | |
| 85 | + friend std::ostream& operator<<(std::ostream& os, const QPDFObjGen& og); | |
| 84 | 86 | |
| 85 | 87 | private: |
| 86 | 88 | // This class does not use the Members pattern to avoid a memory | ... | ... |
include/qpdf/QPDFObjectHandle.hh
| ... | ... | @@ -116,9 +116,16 @@ class QPDFObjectHandle |
| 116 | 116 | // indicating whether it ran without errors. |
| 117 | 117 | QPDF_DLL |
| 118 | 118 | virtual void |
| 119 | - provideStreamData(int objid, int generation, Pipeline* pipeline); | |
| 119 | + provideStreamData(QPDFObjGen const& og, Pipeline* pipeline); | |
| 120 | 120 | QPDF_DLL |
| 121 | 121 | virtual bool provideStreamData( |
| 122 | + QPDFObjGen const& og, | |
| 123 | + Pipeline* pipeline, | |
| 124 | + bool suppress_warnings, | |
| 125 | + bool will_retry); | |
| 126 | + QPDF_DLL virtual void | |
| 127 | + provideStreamData(int objid, int generation, Pipeline* pipeline); | |
| 128 | + QPDF_DLL virtual bool provideStreamData( | |
| 122 | 129 | int objid, |
| 123 | 130 | int generation, |
| 124 | 131 | Pipeline* pipeline, |
| ... | ... | @@ -1429,21 +1436,20 @@ class QPDFObjectHandle |
| 1429 | 1436 | |
| 1430 | 1437 | private: |
| 1431 | 1438 | static QPDFObjectHandle |
| 1432 | - newIndirect(QPDF* qpdf, int objid, int generation) | |
| 1439 | + newIndirect(QPDF* qpdf, QPDFObjGen const& og) | |
| 1433 | 1440 | { |
| 1434 | - return QPDFObjectHandle::newIndirect(qpdf, objid, generation); | |
| 1441 | + return QPDFObjectHandle::newIndirect(qpdf, og); | |
| 1435 | 1442 | } |
| 1436 | 1443 | static QPDFObjectHandle |
| 1437 | 1444 | newStream( |
| 1438 | 1445 | QPDF* qpdf, |
| 1439 | - int objid, | |
| 1440 | - int generation, | |
| 1446 | + QPDFObjGen const& og, | |
| 1441 | 1447 | QPDFObjectHandle stream_dict, |
| 1442 | 1448 | qpdf_offset_t offset, |
| 1443 | 1449 | size_t length) |
| 1444 | 1450 | { |
| 1445 | 1451 | return QPDFObjectHandle::newStream( |
| 1446 | - qpdf, objid, generation, stream_dict, offset, length); | |
| 1452 | + qpdf, og, stream_dict, offset, length); | |
| 1447 | 1453 | } |
| 1448 | 1454 | // Reserve an object with a specific ID |
| 1449 | 1455 | static QPDFObjectHandle |
| ... | ... | @@ -1550,7 +1556,7 @@ class QPDFObjectHandle |
| 1550 | 1556 | bool isImage(bool exclude_imagemask = true); |
| 1551 | 1557 | |
| 1552 | 1558 | private: |
| 1553 | - QPDFObjectHandle(QPDF*, int objid, int generation); | |
| 1559 | + QPDFObjectHandle(QPDF*, QPDFObjGen const& og); | |
| 1554 | 1560 | QPDFObjectHandle(std::shared_ptr<QPDFObject> const&); |
| 1555 | 1561 | |
| 1556 | 1562 | enum parser_state_e { |
| ... | ... | @@ -1563,11 +1569,10 @@ class QPDFObjectHandle |
| 1563 | 1569 | }; |
| 1564 | 1570 | |
| 1565 | 1571 | // Private object factory methods |
| 1566 | - static QPDFObjectHandle newIndirect(QPDF*, int objid, int generation); | |
| 1572 | + static QPDFObjectHandle newIndirect(QPDF*, QPDFObjGen const& og); | |
| 1567 | 1573 | static QPDFObjectHandle newStream( |
| 1568 | 1574 | QPDF* qpdf, |
| 1569 | - int objid, | |
| 1570 | - int generation, | |
| 1575 | + QPDFObjGen const& og, | |
| 1571 | 1576 | QPDFObjectHandle stream_dict, |
| 1572 | 1577 | qpdf_offset_t offset, |
| 1573 | 1578 | size_t length); |
| ... | ... | @@ -1584,7 +1589,6 @@ class QPDFObjectHandle |
| 1584 | 1589 | bool stop_at_streams); |
| 1585 | 1590 | void shallowCopyInternal(QPDFObjectHandle& oh, bool first_level_only); |
| 1586 | 1591 | void releaseResolved(); |
| 1587 | - std::string getObjGenAsStr() const; | |
| 1588 | 1592 | static void setObjectDescriptionFromInput( |
| 1589 | 1593 | QPDFObjectHandle, |
| 1590 | 1594 | QPDF*, |
| ... | ... | @@ -1618,8 +1622,7 @@ class QPDFObjectHandle |
| 1618 | 1622 | // a substantial performance penalty since QPDFObjectHandle |
| 1619 | 1623 | // objects are copied around so frequently. |
| 1620 | 1624 | QPDF* qpdf; |
| 1621 | - int objid; // 0 for direct object | |
| 1622 | - int generation; | |
| 1625 | + QPDFObjGen og; | |
| 1623 | 1626 | std::shared_ptr<QPDFObject> obj; |
| 1624 | 1627 | bool reserved; |
| 1625 | 1628 | }; | ... | ... |
libqpdf/CMakeLists.txt
libqpdf/QPDF.cc
| ... | ... | @@ -113,15 +113,13 @@ namespace |
| 113 | 113 | QPDF::ForeignStreamData::ForeignStreamData( |
| 114 | 114 | std::shared_ptr<EncryptionParameters> encp, |
| 115 | 115 | std::shared_ptr<InputSource> file, |
| 116 | - int foreign_objid, | |
| 117 | - int foreign_generation, | |
| 116 | + QPDFObjGen const& foreign_og, | |
| 118 | 117 | qpdf_offset_t offset, |
| 119 | 118 | size_t length, |
| 120 | 119 | QPDFObjectHandle local_dict) : |
| 121 | 120 | encp(encp), |
| 122 | 121 | file(file), |
| 123 | - foreign_objid(foreign_objid), | |
| 124 | - foreign_generation(foreign_generation), | |
| 122 | + foreign_og(foreign_og), | |
| 125 | 123 | offset(offset), |
| 126 | 124 | length(length), |
| 127 | 125 | local_dict(local_dict) |
| ... | ... | @@ -137,22 +135,19 @@ QPDF::CopiedStreamDataProvider::CopiedStreamDataProvider( |
| 137 | 135 | |
| 138 | 136 | bool |
| 139 | 137 | QPDF::CopiedStreamDataProvider::provideStreamData( |
| 140 | - int objid, | |
| 141 | - int generation, | |
| 138 | + QPDFObjGen const& og, | |
| 142 | 139 | Pipeline* pipeline, |
| 143 | 140 | bool suppress_warnings, |
| 144 | 141 | bool will_retry) |
| 145 | 142 | { |
| 146 | - std::shared_ptr<ForeignStreamData> foreign_data = | |
| 147 | - this->foreign_stream_data[QPDFObjGen(objid, generation)]; | |
| 143 | + std::shared_ptr<ForeignStreamData> foreign_data = foreign_stream_data[og]; | |
| 148 | 144 | bool result = false; |
| 149 | 145 | if (foreign_data.get()) { |
| 150 | 146 | result = destination_qpdf.pipeForeignStreamData( |
| 151 | 147 | foreign_data, pipeline, suppress_warnings, will_retry); |
| 152 | 148 | QTC::TC("qpdf", "QPDF copy foreign with data", result ? 0 : 1); |
| 153 | 149 | } else { |
| 154 | - QPDFObjectHandle foreign_stream = | |
| 155 | - this->foreign_streams[QPDFObjGen(objid, generation)]; | |
| 150 | + auto foreign_stream = foreign_streams[og]; | |
| 156 | 151 | result = foreign_stream.pipeStreamData( |
| 157 | 152 | pipeline, nullptr, 0, qpdf_dl_none, suppress_warnings, will_retry); |
| 158 | 153 | QTC::TC( |
| ... | ... | @@ -176,17 +171,16 @@ QPDF::CopiedStreamDataProvider::registerForeignStream( |
| 176 | 171 | this->foreign_stream_data[local_og] = foreign_stream; |
| 177 | 172 | } |
| 178 | 173 | |
| 179 | -QPDF::StringDecrypter::StringDecrypter(QPDF* qpdf, int objid, int gen) : | |
| 174 | +QPDF::StringDecrypter::StringDecrypter(QPDF* qpdf, QPDFObjGen const& og) : | |
| 180 | 175 | qpdf(qpdf), |
| 181 | - objid(objid), | |
| 182 | - gen(gen) | |
| 176 | + og(og) | |
| 183 | 177 | { |
| 184 | 178 | } |
| 185 | 179 | |
| 186 | 180 | void |
| 187 | 181 | QPDF::StringDecrypter::decryptString(std::string& val) |
| 188 | 182 | { |
| 189 | - qpdf->decryptString(val, objid, gen); | |
| 183 | + qpdf->decryptString(val, og); | |
| 190 | 184 | } |
| 191 | 185 | |
| 192 | 186 | std::string const& |
| ... | ... | @@ -205,8 +199,6 @@ QPDF::EncryptionParameters::EncryptionParameters() : |
| 205 | 199 | cf_stream(e_none), |
| 206 | 200 | cf_string(e_none), |
| 207 | 201 | cf_file(e_none), |
| 208 | - cached_key_objid(0), | |
| 209 | - cached_key_generation(0), | |
| 210 | 202 | user_password_matched(false), |
| 211 | 203 | owner_password_matched(false) |
| 212 | 204 | { |
| ... | ... | @@ -631,7 +623,7 @@ QPDF::reconstruct_xref(QPDFExc& e) |
| 631 | 623 | (!this->m->trailer.isInitialized()) && |
| 632 | 624 | (t1 == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "trailer"))) { |
| 633 | 625 | QPDFObjectHandle t = |
| 634 | - readObject(this->m->file, "trailer", 0, 0, false); | |
| 626 | + readObject(this->m->file, "trailer", QPDFObjGen(), false); | |
| 635 | 627 | if (!t.isDictionary()) { |
| 636 | 628 | // Oh well. It was worth a try. |
| 637 | 629 | } else { |
| ... | ... | @@ -969,7 +961,7 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset) |
| 969 | 961 | |
| 970 | 962 | // Set offset to previous xref table if any |
| 971 | 963 | QPDFObjectHandle cur_trailer = |
| 972 | - readObject(this->m->file, "trailer", 0, 0, false); | |
| 964 | + readObject(this->m->file, "trailer", QPDFObjGen(), false); | |
| 973 | 965 | if (!cur_trailer.isDictionary()) { |
| 974 | 966 | QTC::TC("qpdf", "QPDF missing trailer"); |
| 975 | 967 | throw QPDFExc( |
| ... | ... | @@ -1055,12 +1047,11 @@ QPDF::read_xrefStream(qpdf_offset_t xref_offset) |
| 1055 | 1047 | { |
| 1056 | 1048 | bool found = false; |
| 1057 | 1049 | if (!this->m->ignore_xref_streams) { |
| 1058 | - int xobj; | |
| 1059 | - int xgen; | |
| 1050 | + QPDFObjGen x_og; | |
| 1060 | 1051 | QPDFObjectHandle xref_obj; |
| 1061 | 1052 | try { |
| 1062 | 1053 | xref_obj = readObjectAtOffset( |
| 1063 | - false, xref_offset, "xref stream", 0, 0, xobj, xgen); | |
| 1054 | + false, xref_offset, "xref stream", QPDFObjGen(0, 0), x_og); | |
| 1064 | 1055 | } catch (QPDFExc&) { |
| 1065 | 1056 | // ignore -- report error below |
| 1066 | 1057 | } |
| ... | ... | @@ -1363,7 +1354,7 @@ QPDF::showXRefTable() |
| 1363 | 1354 | for (auto const& iter: this->m->xref_table) { |
| 1364 | 1355 | QPDFObjGen const& og = iter.first; |
| 1365 | 1356 | QPDFXRefEntry const& entry = iter.second; |
| 1366 | - cout << og.getObj() << "/" << og.getGen() << ": "; | |
| 1357 | + cout << og.unparse('/') << ": "; | |
| 1367 | 1358 | switch (entry.getType()) { |
| 1368 | 1359 | case 1: |
| 1369 | 1360 | cout << "uncompressed; offset = " << entry.getOffset(); |
| ... | ... | @@ -1405,9 +1396,8 @@ QPDF::fixDanglingReferences(bool force) |
| 1405 | 1396 | // For each non-scalar item to process, put it in the queue. |
| 1406 | 1397 | std::list<QPDFObjectHandle> queue; |
| 1407 | 1398 | queue.push_back(this->m->trailer); |
| 1408 | - for (auto const& iter: to_process) { | |
| 1409 | - QPDFObjectHandle obj = QPDFObjectHandle::Factory::newIndirect( | |
| 1410 | - this, iter.getObj(), iter.getGen()); | |
| 1399 | + for (auto const& og: to_process) { | |
| 1400 | + QPDFObjectHandle obj = QPDFObjectHandle::Factory::newIndirect(this, og); | |
| 1411 | 1401 | if (obj.isDictionary() || obj.isArray()) { |
| 1412 | 1402 | queue.push_back(obj); |
| 1413 | 1403 | } else if (obj.isStream()) { |
| ... | ... | @@ -1473,29 +1463,24 @@ QPDF::getAllObjects() |
| 1473 | 1463 | std::vector<QPDFObjectHandle> result; |
| 1474 | 1464 | for (auto const& iter: this->m->obj_cache) { |
| 1475 | 1465 | QPDFObjGen const& og = iter.first; |
| 1476 | - result.push_back( | |
| 1477 | - // line-break | |
| 1478 | - QPDFObjectHandle::Factory::newIndirect( | |
| 1479 | - this, og.getObj(), og.getGen())); | |
| 1466 | + result.push_back(QPDFObjectHandle::Factory::newIndirect(this, og)); | |
| 1480 | 1467 | } |
| 1481 | 1468 | return result; |
| 1482 | 1469 | } |
| 1483 | 1470 | |
| 1484 | 1471 | void |
| 1485 | 1472 | QPDF::setLastObjectDescription( |
| 1486 | - std::string const& description, int objid, int generation) | |
| 1473 | + std::string const& description, QPDFObjGen const& og) | |
| 1487 | 1474 | { |
| 1488 | 1475 | this->m->last_object_description.clear(); |
| 1489 | 1476 | if (!description.empty()) { |
| 1490 | 1477 | this->m->last_object_description += description; |
| 1491 | - if (objid > 0) { | |
| 1478 | + if (og.isIndirect()) { | |
| 1492 | 1479 | this->m->last_object_description += ": "; |
| 1493 | 1480 | } |
| 1494 | 1481 | } |
| 1495 | - if (objid > 0) { | |
| 1496 | - this->m->last_object_description += "object " + | |
| 1497 | - QUtil::int_to_string(objid) + " " + | |
| 1498 | - QUtil::int_to_string(generation); | |
| 1482 | + if (og.isIndirect()) { | |
| 1483 | + this->m->last_object_description += "object " + og.unparse(' '); | |
| 1499 | 1484 | } |
| 1500 | 1485 | } |
| 1501 | 1486 | |
| ... | ... | @@ -1503,19 +1488,17 @@ QPDFObjectHandle |
| 1503 | 1488 | QPDF::readObject( |
| 1504 | 1489 | std::shared_ptr<InputSource> input, |
| 1505 | 1490 | std::string const& description, |
| 1506 | - int objid, | |
| 1507 | - int generation, | |
| 1491 | + QPDFObjGen const& og, | |
| 1508 | 1492 | bool in_object_stream) |
| 1509 | 1493 | { |
| 1510 | - setLastObjectDescription(description, objid, generation); | |
| 1494 | + setLastObjectDescription(description, og); | |
| 1511 | 1495 | qpdf_offset_t offset = input->tell(); |
| 1512 | 1496 | |
| 1513 | 1497 | bool empty = false; |
| 1514 | 1498 | std::shared_ptr<StringDecrypter> decrypter_ph; |
| 1515 | 1499 | StringDecrypter* decrypter = 0; |
| 1516 | 1500 | if (this->m->encp->encrypted && (!in_object_stream)) { |
| 1517 | - decrypter_ph = | |
| 1518 | - std::make_shared<StringDecrypter>(this, objid, generation); | |
| 1501 | + decrypter_ph = std::make_shared<StringDecrypter>(this, og); | |
| 1519 | 1502 | decrypter = decrypter_ph.get(); |
| 1520 | 1503 | } |
| 1521 | 1504 | QPDFObjectHandle object = QPDFObjectHandle::parse( |
| ... | ... | @@ -1657,14 +1640,13 @@ QPDF::readObject( |
| 1657 | 1640 | } catch (QPDFExc& e) { |
| 1658 | 1641 | if (this->m->attempt_recovery) { |
| 1659 | 1642 | warn(e); |
| 1660 | - length = recoverStreamLength( | |
| 1661 | - input, objid, generation, stream_offset); | |
| 1643 | + length = recoverStreamLength(input, og, stream_offset); | |
| 1662 | 1644 | } else { |
| 1663 | 1645 | throw e; |
| 1664 | 1646 | } |
| 1665 | 1647 | } |
| 1666 | 1648 | object = QPDFObjectHandle::Factory::newStream( |
| 1667 | - this, objid, generation, object, stream_offset, length); | |
| 1649 | + this, og, object, stream_offset, length); | |
| 1668 | 1650 | } else { |
| 1669 | 1651 | input->seek(cur_offset, SEEK_SET); |
| 1670 | 1652 | } |
| ... | ... | @@ -1692,8 +1674,7 @@ QPDF::findEndstream() |
| 1692 | 1674 | size_t |
| 1693 | 1675 | QPDF::recoverStreamLength( |
| 1694 | 1676 | std::shared_ptr<InputSource> input, |
| 1695 | - int objid, | |
| 1696 | - int generation, | |
| 1677 | + QPDFObjGen const& og, | |
| 1697 | 1678 | qpdf_offset_t stream_offset) |
| 1698 | 1679 | { |
| 1699 | 1680 | // Try to reconstruct stream length by looking for |
| ... | ... | @@ -1718,11 +1699,10 @@ QPDF::recoverStreamLength( |
| 1718 | 1699 | |
| 1719 | 1700 | if (length) { |
| 1720 | 1701 | qpdf_offset_t this_obj_offset = 0; |
| 1721 | - QPDFObjGen this_obj(0, 0); | |
| 1702 | + QPDFObjGen this_og; | |
| 1722 | 1703 | |
| 1723 | 1704 | // Make sure this is inside this object |
| 1724 | 1705 | for (auto const& iter: this->m->xref_table) { |
| 1725 | - QPDFObjGen const& og = iter.first; | |
| 1726 | 1706 | QPDFXRefEntry const& entry = iter.second; |
| 1727 | 1707 | if (entry.getType() == 1) { |
| 1728 | 1708 | qpdf_offset_t obj_offset = entry.getOffset(); |
| ... | ... | @@ -1730,12 +1710,11 @@ QPDF::recoverStreamLength( |
| 1730 | 1710 | ((this_obj_offset == 0) || |
| 1731 | 1711 | (this_obj_offset > obj_offset))) { |
| 1732 | 1712 | this_obj_offset = obj_offset; |
| 1733 | - this_obj = og; | |
| 1713 | + this_og = iter.first; | |
| 1734 | 1714 | } |
| 1735 | 1715 | } |
| 1736 | 1716 | } |
| 1737 | - if (this_obj_offset && (this_obj.getObj() == objid) && | |
| 1738 | - (this_obj.getGen() == generation)) { | |
| 1717 | + if (this_obj_offset && (this_og == og)) { | |
| 1739 | 1718 | // Well, we found endstream\nendobj within the space |
| 1740 | 1719 | // allowed for this object, so we're probably in good |
| 1741 | 1720 | // shape. |
| ... | ... | @@ -1777,13 +1756,11 @@ QPDF::readObjectAtOffset( |
| 1777 | 1756 | bool try_recovery, |
| 1778 | 1757 | qpdf_offset_t offset, |
| 1779 | 1758 | std::string const& description, |
| 1780 | - int exp_objid, | |
| 1781 | - int exp_generation, | |
| 1782 | - int& objid, | |
| 1783 | - int& generation) | |
| 1759 | + QPDFObjGen const& exp_og, | |
| 1760 | + QPDFObjGen& og) | |
| 1784 | 1761 | { |
| 1785 | 1762 | bool check_og = true; |
| 1786 | - if (exp_objid == 0) { | |
| 1763 | + if (exp_og.getObj() == 0) { | |
| 1787 | 1764 | // This method uses an expect object ID of 0 to indicate that |
| 1788 | 1765 | // we don't know or don't care what the actual object ID is at |
| 1789 | 1766 | // this offset. This is true when we read the xref stream and |
| ... | ... | @@ -1795,7 +1772,7 @@ QPDF::readObjectAtOffset( |
| 1795 | 1772 | check_og = false; |
| 1796 | 1773 | try_recovery = false; |
| 1797 | 1774 | } else { |
| 1798 | - setLastObjectDescription(description, exp_objid, exp_generation); | |
| 1775 | + setLastObjectDescription(description, exp_og); | |
| 1799 | 1776 | } |
| 1800 | 1777 | |
| 1801 | 1778 | if (!this->m->attempt_recovery) { |
| ... | ... | @@ -1841,9 +1818,9 @@ QPDF::readObjectAtOffset( |
| 1841 | 1818 | offset, |
| 1842 | 1819 | "expected n n obj"); |
| 1843 | 1820 | } |
| 1844 | - objid = QUtil::string_to_int(tobjid.getValue().c_str()); | |
| 1845 | - generation = QUtil::string_to_int(tgen.getValue().c_str()); | |
| 1846 | - | |
| 1821 | + int objid = QUtil::string_to_int(tobjid.getValue().c_str()); | |
| 1822 | + int generation = QUtil::string_to_int(tgen.getValue().c_str()); | |
| 1823 | + og = QPDFObjGen(objid, generation); | |
| 1847 | 1824 | if (objid == 0) { |
| 1848 | 1825 | QTC::TC("qpdf", "QPDF object id 0"); |
| 1849 | 1826 | throw QPDFExc( |
| ... | ... | @@ -1853,17 +1830,14 @@ QPDF::readObjectAtOffset( |
| 1853 | 1830 | offset, |
| 1854 | 1831 | "object with ID 0"); |
| 1855 | 1832 | } |
| 1856 | - | |
| 1857 | - if (check_og && | |
| 1858 | - (!((objid == exp_objid) && (generation == exp_generation)))) { | |
| 1833 | + if (check_og && (exp_og != og)) { | |
| 1859 | 1834 | QTC::TC("qpdf", "QPDF err wrong objid/generation"); |
| 1860 | 1835 | QPDFExc e( |
| 1861 | 1836 | qpdf_e_damaged_pdf, |
| 1862 | 1837 | this->m->file->getName(), |
| 1863 | 1838 | this->m->last_object_description, |
| 1864 | 1839 | offset, |
| 1865 | - (std::string("expected ") + QUtil::int_to_string(exp_objid) + | |
| 1866 | - " " + QUtil::int_to_string(exp_generation) + " obj")); | |
| 1840 | + (std::string("expected ") + exp_og.unparse(' ') + " obj")); | |
| 1867 | 1841 | if (try_recovery) { |
| 1868 | 1842 | // Will be retried below |
| 1869 | 1843 | throw e; |
| ... | ... | @@ -1877,18 +1851,12 @@ QPDF::readObjectAtOffset( |
| 1877 | 1851 | if (try_recovery) { |
| 1878 | 1852 | // Try again after reconstructing xref table |
| 1879 | 1853 | reconstruct_xref(e); |
| 1880 | - QPDFObjGen og(exp_objid, exp_generation); | |
| 1881 | - if (this->m->xref_table.count(og) && | |
| 1882 | - (this->m->xref_table[og].getType() == 1)) { | |
| 1883 | - qpdf_offset_t new_offset = this->m->xref_table[og].getOffset(); | |
| 1854 | + if (this->m->xref_table.count(exp_og) && | |
| 1855 | + (this->m->xref_table[exp_og].getType() == 1)) { | |
| 1856 | + qpdf_offset_t new_offset = | |
| 1857 | + this->m->xref_table[exp_og].getOffset(); | |
| 1884 | 1858 | QPDFObjectHandle result = readObjectAtOffset( |
| 1885 | - false, | |
| 1886 | - new_offset, | |
| 1887 | - description, | |
| 1888 | - exp_objid, | |
| 1889 | - exp_generation, | |
| 1890 | - objid, | |
| 1891 | - generation); | |
| 1859 | + false, new_offset, description, exp_og, og); | |
| 1892 | 1860 | QTC::TC("qpdf", "QPDF recovered in readObjectAtOffset"); |
| 1893 | 1861 | return result; |
| 1894 | 1862 | } else { |
| ... | ... | @@ -1898,8 +1866,7 @@ QPDF::readObjectAtOffset( |
| 1898 | 1866 | "", |
| 1899 | 1867 | 0, |
| 1900 | 1868 | std::string( |
| 1901 | - "object " + QUtil::int_to_string(exp_objid) + " " + | |
| 1902 | - QUtil::int_to_string(exp_generation) + | |
| 1869 | + "object " + exp_og.unparse(' ') + | |
| 1903 | 1870 | " not found in file after regenerating" |
| 1904 | 1871 | " cross reference table")); |
| 1905 | 1872 | return QPDFObjectHandle::newNull(); |
| ... | ... | @@ -1909,8 +1876,7 @@ QPDF::readObjectAtOffset( |
| 1909 | 1876 | } |
| 1910 | 1877 | } |
| 1911 | 1878 | |
| 1912 | - QPDFObjectHandle oh = | |
| 1913 | - readObject(this->m->file, description, objid, generation, false); | |
| 1879 | + QPDFObjectHandle oh = readObject(this->m->file, description, og, false); | |
| 1914 | 1880 | |
| 1915 | 1881 | if (!(readToken(this->m->file) == |
| 1916 | 1882 | QPDFTokenizer::Token(QPDFTokenizer::tt_word, "endobj"))) { |
| ... | ... | @@ -1922,7 +1888,6 @@ QPDF::readObjectAtOffset( |
| 1922 | 1888 | "expected endobj"); |
| 1923 | 1889 | } |
| 1924 | 1890 | |
| 1925 | - QPDFObjGen og(objid, generation); | |
| 1926 | 1891 | if (!this->m->obj_cache.count(og)) { |
| 1927 | 1892 | // Store the object in the cache here so it gets cached |
| 1928 | 1893 | // whether we first know the offset or whether we first know |
| ... | ... | @@ -1987,12 +1952,11 @@ QPDF::objectChanged(QPDFObjGen const& og, std::shared_ptr<QPDFObject>& oph) |
| 1987 | 1952 | } |
| 1988 | 1953 | |
| 1989 | 1954 | std::shared_ptr<QPDFObject> |
| 1990 | -QPDF::resolve(int objid, int generation) | |
| 1955 | +QPDF::resolve(QPDFObjGen const& og) | |
| 1991 | 1956 | { |
| 1992 | 1957 | // Check object cache before checking xref table. This allows us |
| 1993 | 1958 | // to insert things into the object cache that don't actually |
| 1994 | 1959 | // exist in the file. |
| 1995 | - QPDFObjGen og(objid, generation); | |
| 1996 | 1960 | if (this->m->resolving.count(og)) { |
| 1997 | 1961 | // This can happen if an object references itself directly or |
| 1998 | 1962 | // indirectly in some key that has to be resolved during |
| ... | ... | @@ -2002,8 +1966,7 @@ QPDF::resolve(int objid, int generation) |
| 2002 | 1966 | qpdf_e_damaged_pdf, |
| 2003 | 1967 | "", |
| 2004 | 1968 | this->m->file->getLastOffset(), |
| 2005 | - ("loop detected resolving object " + QUtil::int_to_string(objid) + | |
| 2006 | - " " + QUtil::int_to_string(generation))); | |
| 1969 | + ("loop detected resolving object " + og.unparse(' '))); | |
| 2007 | 1970 | return QPDF_Null::create(); |
| 2008 | 1971 | } |
| 2009 | 1972 | ResolveRecorder rr(this, og); |
| ... | ... | @@ -2016,16 +1979,9 @@ QPDF::resolve(int objid, int generation) |
| 2016 | 1979 | { |
| 2017 | 1980 | qpdf_offset_t offset = entry.getOffset(); |
| 2018 | 1981 | // Object stored in cache by readObjectAtOffset |
| 2019 | - int aobjid; | |
| 2020 | - int ageneration; | |
| 2021 | - QPDFObjectHandle oh = readObjectAtOffset( | |
| 2022 | - true, | |
| 2023 | - offset, | |
| 2024 | - "", | |
| 2025 | - objid, | |
| 2026 | - generation, | |
| 2027 | - aobjid, | |
| 2028 | - ageneration); | |
| 1982 | + QPDFObjGen a_og; | |
| 1983 | + QPDFObjectHandle oh = | |
| 1984 | + readObjectAtOffset(true, offset, "", og, a_og); | |
| 2029 | 1985 | } |
| 2030 | 1986 | break; |
| 2031 | 1987 | |
| ... | ... | @@ -2039,8 +1995,7 @@ QPDF::resolve(int objid, int generation) |
| 2039 | 1995 | this->m->file->getName(), |
| 2040 | 1996 | "", |
| 2041 | 1997 | 0, |
| 2042 | - ("object " + QUtil::int_to_string(objid) + "/" + | |
| 2043 | - QUtil::int_to_string(generation) + | |
| 1998 | + ("object " + og.unparse('/') + | |
| 2044 | 1999 | " has unexpected xref entry type")); |
| 2045 | 2000 | } |
| 2046 | 2001 | } catch (QPDFExc& e) { |
| ... | ... | @@ -2050,8 +2005,7 @@ QPDF::resolve(int objid, int generation) |
| 2050 | 2005 | qpdf_e_damaged_pdf, |
| 2051 | 2006 | "", |
| 2052 | 2007 | 0, |
| 2053 | - ("object " + QUtil::int_to_string(objid) + "/" + | |
| 2054 | - QUtil::int_to_string(generation) + | |
| 2008 | + ("object " + og.unparse('/') + | |
| 2055 | 2009 | ": error reading object: " + e.what())); |
| 2056 | 2010 | } |
| 2057 | 2011 | } |
| ... | ... | @@ -2065,10 +2019,7 @@ QPDF::resolve(int objid, int generation) |
| 2065 | 2019 | |
| 2066 | 2020 | std::shared_ptr<QPDFObject> result(this->m->obj_cache[og].object); |
| 2067 | 2021 | if (!result->hasDescription()) { |
| 2068 | - result->setDescription( | |
| 2069 | - this, | |
| 2070 | - ("object " + QUtil::int_to_string(objid) + " " + | |
| 2071 | - QUtil::int_to_string(generation))); | |
| 2022 | + result->setDescription(this, ("object " + og.unparse(' '))); | |
| 2072 | 2023 | } |
| 2073 | 2024 | return result; |
| 2074 | 2025 | } |
| ... | ... | @@ -2165,7 +2116,7 @@ QPDF::resolveObjectsInStream(int obj_stream_number) |
| 2165 | 2116 | (entry.getObjStreamNumber() == obj_stream_number)) { |
| 2166 | 2117 | int offset = iter.second; |
| 2167 | 2118 | input->seek(offset, SEEK_SET); |
| 2168 | - QPDFObjectHandle oh = readObject(input, "", obj, 0, true); | |
| 2119 | + QPDFObjectHandle oh = readObject(input, "", og, true); | |
| 2169 | 2120 | this->m->obj_cache[og] = ObjCache( |
| 2170 | 2121 | QPDFObjectHandle::ObjAccessor::getObject(oh), |
| 2171 | 2122 | end_before_space, |
| ... | ... | @@ -2187,48 +2138,46 @@ QPDF::makeIndirectObject(QPDFObjectHandle oh) |
| 2187 | 2138 | QPDFObjGen next(max_objid + 1, 0); |
| 2188 | 2139 | this->m->obj_cache[next] = |
| 2189 | 2140 | ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh), -1, -1); |
| 2190 | - return QPDFObjectHandle::Factory::newIndirect( | |
| 2191 | - this, next.getObj(), next.getGen()); | |
| 2141 | + return QPDFObjectHandle::Factory::newIndirect(this, next); | |
| 2192 | 2142 | } |
| 2193 | 2143 | |
| 2194 | 2144 | QPDFObjectHandle |
| 2195 | -QPDF::reserveObjectIfNotExists(int objid, int gen) | |
| 2145 | +QPDF::reserveObjectIfNotExists(QPDFObjGen const& og) | |
| 2196 | 2146 | { |
| 2197 | - QPDFObjGen og(objid, gen); | |
| 2198 | 2147 | if ((!this->m->obj_cache.count(og)) && (!this->m->xref_table.count(og))) { |
| 2199 | - resolve(objid, gen); | |
| 2200 | - replaceObject(objid, gen, QPDFObjectHandle::Factory::makeReserved()); | |
| 2148 | + resolve(og); | |
| 2149 | + replaceObject(og, QPDFObjectHandle::Factory::makeReserved()); | |
| 2201 | 2150 | } |
| 2202 | - return getObjectByID(objid, gen); | |
| 2151 | + return getObjectByObjGen(og); | |
| 2203 | 2152 | } |
| 2204 | 2153 | |
| 2205 | 2154 | QPDFObjectHandle |
| 2206 | -QPDF::reserveStream(int objid, int gen) | |
| 2155 | +QPDF::reserveStream(QPDFObjGen const& og) | |
| 2207 | 2156 | { |
| 2208 | 2157 | return QPDFObjectHandle::Factory::newStream( |
| 2209 | - this, objid, gen, QPDFObjectHandle::newDictionary(), 0, 0); | |
| 2158 | + this, og, QPDFObjectHandle::newDictionary(), 0, 0); | |
| 2210 | 2159 | } |
| 2211 | 2160 | |
| 2212 | 2161 | QPDFObjectHandle |
| 2213 | 2162 | QPDF::getObjectByObjGen(QPDFObjGen const& og) |
| 2214 | 2163 | { |
| 2215 | - return getObjectByID(og.getObj(), og.getGen()); | |
| 2164 | + return QPDFObjectHandle::Factory::newIndirect(this, og); | |
| 2216 | 2165 | } |
| 2217 | 2166 | |
| 2218 | 2167 | QPDFObjectHandle |
| 2219 | 2168 | QPDF::getObjectByID(int objid, int generation) |
| 2220 | 2169 | { |
| 2221 | - return QPDFObjectHandle::Factory::newIndirect(this, objid, generation); | |
| 2170 | + return getObjectByObjGen(QPDFObjGen(objid, generation)); | |
| 2222 | 2171 | } |
| 2223 | 2172 | |
| 2224 | 2173 | void |
| 2225 | -QPDF::replaceObject(QPDFObjGen const& og, QPDFObjectHandle oh) | |
| 2174 | +QPDF::replaceObject(int objid, int generation, QPDFObjectHandle oh) | |
| 2226 | 2175 | { |
| 2227 | - replaceObject(og.getObj(), og.getGen(), oh); | |
| 2176 | + replaceObject(QPDFObjGen(objid, generation), oh); | |
| 2228 | 2177 | } |
| 2229 | 2178 | |
| 2230 | 2179 | void |
| 2231 | -QPDF::replaceObject(int objid, int generation, QPDFObjectHandle oh) | |
| 2180 | +QPDF::replaceObject(QPDFObjGen const& og, QPDFObjectHandle oh) | |
| 2232 | 2181 | { |
| 2233 | 2182 | if (oh.isIndirect()) { |
| 2234 | 2183 | QTC::TC("qpdf", "QPDF replaceObject called with indirect object"); |
| ... | ... | @@ -2237,10 +2186,9 @@ QPDF::replaceObject(int objid, int generation, QPDFObjectHandle oh) |
| 2237 | 2186 | } |
| 2238 | 2187 | |
| 2239 | 2188 | // Force new object to appear in the cache |
| 2240 | - resolve(objid, generation); | |
| 2189 | + resolve(og); | |
| 2241 | 2190 | |
| 2242 | 2191 | // Replace the object in the object cache |
| 2243 | - QPDFObjGen og(objid, generation); | |
| 2244 | 2192 | this->m->ever_replaced_objects = true; |
| 2245 | 2193 | this->m->obj_cache[og] = |
| 2246 | 2194 | ObjCache(QPDFObjectHandle::ObjAccessor::getObject(oh), -1, -1); |
| ... | ... | @@ -2540,8 +2488,7 @@ QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign) |
| 2540 | 2488 | auto foreign_stream_data = std::make_shared<ForeignStreamData>( |
| 2541 | 2489 | foreign_stream_qpdf->m->encp, |
| 2542 | 2490 | foreign_stream_qpdf->m->file, |
| 2543 | - foreign.getObjectID(), | |
| 2544 | - foreign.getGeneration(), | |
| 2491 | + foreign.getObjGen(), | |
| 2545 | 2492 | stream->getOffset(), |
| 2546 | 2493 | stream->getLength(), |
| 2547 | 2494 | dict); |
| ... | ... | @@ -2555,20 +2502,19 @@ QPDF::copyStreamData(QPDFObjectHandle result, QPDFObjectHandle foreign) |
| 2555 | 2502 | } |
| 2556 | 2503 | |
| 2557 | 2504 | void |
| 2558 | -QPDF::swapObjects(QPDFObjGen const& og1, QPDFObjGen const& og2) | |
| 2505 | +QPDF::swapObjects(int objid1, int generation1, int objid2, int generation2) | |
| 2559 | 2506 | { |
| 2560 | - swapObjects(og1.getObj(), og1.getGen(), og2.getObj(), og2.getGen()); | |
| 2507 | + swapObjects( | |
| 2508 | + QPDFObjGen(objid1, generation1), QPDFObjGen(objid2, generation2)); | |
| 2561 | 2509 | } |
| 2562 | 2510 | |
| 2563 | 2511 | void |
| 2564 | -QPDF::swapObjects(int objid1, int generation1, int objid2, int generation2) | |
| 2512 | +QPDF::swapObjects(QPDFObjGen const& og1, QPDFObjGen const& og2) | |
| 2565 | 2513 | { |
| 2566 | 2514 | // Force objects to be loaded into cache; then swap them in the |
| 2567 | 2515 | // cache. |
| 2568 | - resolve(objid1, generation1); | |
| 2569 | - resolve(objid2, generation2); | |
| 2570 | - QPDFObjGen og1(objid1, generation1); | |
| 2571 | - QPDFObjGen og2(objid2, generation2); | |
| 2516 | + resolve(og1); | |
| 2517 | + resolve(og2); | |
| 2572 | 2518 | ObjCache t = this->m->obj_cache[og1]; |
| 2573 | 2519 | this->m->ever_replaced_objects = true; |
| 2574 | 2520 | this->m->obj_cache[og1] = this->m->obj_cache[og2]; |
| ... | ... | @@ -2752,8 +2698,7 @@ QPDF::pipeStreamData( |
| 2752 | 2698 | std::shared_ptr<EncryptionParameters> encp, |
| 2753 | 2699 | std::shared_ptr<InputSource> file, |
| 2754 | 2700 | QPDF& qpdf_for_warning, |
| 2755 | - int objid, | |
| 2756 | - int generation, | |
| 2701 | + QPDFObjGen const& og, | |
| 2757 | 2702 | qpdf_offset_t offset, |
| 2758 | 2703 | size_t length, |
| 2759 | 2704 | QPDFObjectHandle stream_dict, |
| ... | ... | @@ -2764,14 +2709,7 @@ QPDF::pipeStreamData( |
| 2764 | 2709 | std::vector<std::shared_ptr<Pipeline>> to_delete; |
| 2765 | 2710 | if (encp->encrypted) { |
| 2766 | 2711 | decryptStream( |
| 2767 | - encp, | |
| 2768 | - file, | |
| 2769 | - qpdf_for_warning, | |
| 2770 | - pipeline, | |
| 2771 | - objid, | |
| 2772 | - generation, | |
| 2773 | - stream_dict, | |
| 2774 | - to_delete); | |
| 2712 | + encp, file, qpdf_for_warning, pipeline, og, stream_dict, to_delete); | |
| 2775 | 2713 | } |
| 2776 | 2714 | |
| 2777 | 2715 | bool success = false; |
| ... | ... | @@ -2809,8 +2747,7 @@ QPDF::pipeStreamData( |
| 2809 | 2747 | "", |
| 2810 | 2748 | file->getLastOffset(), |
| 2811 | 2749 | ("error decoding stream data for object " + |
| 2812 | - QUtil::int_to_string(objid) + " " + | |
| 2813 | - QUtil::int_to_string(generation) + ": " + e.what()))); | |
| 2750 | + og.unparse(' ') + ": " + e.what()))); | |
| 2814 | 2751 | if (will_retry) { |
| 2815 | 2752 | qpdf_for_warning.warn( |
| 2816 | 2753 | // line-break |
| ... | ... | @@ -2836,8 +2773,7 @@ QPDF::pipeStreamData( |
| 2836 | 2773 | |
| 2837 | 2774 | bool |
| 2838 | 2775 | QPDF::pipeStreamData( |
| 2839 | - int objid, | |
| 2840 | - int generation, | |
| 2776 | + QPDFObjGen const& og, | |
| 2841 | 2777 | qpdf_offset_t offset, |
| 2842 | 2778 | size_t length, |
| 2843 | 2779 | QPDFObjectHandle stream_dict, |
| ... | ... | @@ -2849,8 +2785,7 @@ QPDF::pipeStreamData( |
| 2849 | 2785 | this->m->encp, |
| 2850 | 2786 | this->m->file, |
| 2851 | 2787 | *this, |
| 2852 | - objid, | |
| 2853 | - generation, | |
| 2788 | + og, | |
| 2854 | 2789 | offset, |
| 2855 | 2790 | length, |
| 2856 | 2791 | stream_dict, |
| ... | ... | @@ -2873,8 +2808,7 @@ QPDF::pipeForeignStreamData( |
| 2873 | 2808 | foreign->encp, |
| 2874 | 2809 | foreign->file, |
| 2875 | 2810 | *this, |
| 2876 | - foreign->foreign_objid, | |
| 2877 | - foreign->foreign_generation, | |
| 2811 | + foreign->foreign_og, | |
| 2878 | 2812 | foreign->offset, |
| 2879 | 2813 | foreign->length, |
| 2880 | 2814 | foreign->local_dict, | ... | ... |
libqpdf/QPDFAcroFormDocumentHelper.cc
| ... | ... | @@ -991,8 +991,8 @@ QPDFAcroFormDocumentHelper::transformAnnotations( |
| 991 | 991 | } else { |
| 992 | 992 | parent.warnIfPossible( |
| 993 | 993 | "while traversing field " + |
| 994 | - obj.getObjGen().unparse() + ", found parent (" + | |
| 995 | - parent_og.unparse() + | |
| 994 | + obj.getObjGen().unparse(',') + ", found parent (" + | |
| 995 | + parent_og.unparse(',') + | |
| 996 | 996 | ") that had not been seen, indicating likely" |
| 997 | 997 | " invalid field structure"); |
| 998 | 998 | } | ... | ... |
libqpdf/QPDFJob.cc
| ... | ... | @@ -49,8 +49,7 @@ namespace |
| 49 | 49 | size_t oi_min_area, |
| 50 | 50 | QPDFObjectHandle& image); |
| 51 | 51 | virtual ~ImageOptimizer() = default; |
| 52 | - virtual void | |
| 53 | - provideStreamData(int objid, int generation, Pipeline* pipeline); | |
| 52 | + virtual void provideStreamData(QPDFObjGen const&, Pipeline* pipeline); | |
| 54 | 53 | std::shared_ptr<Pipeline> |
| 55 | 54 | makePipeline(std::string const& description, Pipeline* next); |
| 56 | 55 | bool evaluate(std::string const& description); |
| ... | ... | @@ -250,7 +249,7 @@ ImageOptimizer::evaluate(std::string const& description) |
| 250 | 249 | } |
| 251 | 250 | |
| 252 | 251 | void |
| 253 | -ImageOptimizer::provideStreamData(int, int, Pipeline* pipeline) | |
| 252 | +ImageOptimizer::provideStreamData(QPDFObjGen const&, Pipeline* pipeline) | |
| 254 | 253 | { |
| 255 | 254 | std::shared_ptr<Pipeline> p = makePipeline("", pipeline); |
| 256 | 255 | if (p.get() == nullptr) { |
| ... | ... | @@ -947,7 +946,7 @@ QPDFJob::doShowObj(QPDF& pdf) |
| 947 | 946 | } |
| 948 | 947 | if (error) { |
| 949 | 948 | throw std::runtime_error( |
| 950 | - "unable to get object " + obj.getObjGen().unparse()); | |
| 949 | + "unable to get object " + obj.getObjGen().unparse(',')); | |
| 951 | 950 | } |
| 952 | 951 | } |
| 953 | 952 | |
| ... | ... | @@ -995,7 +994,8 @@ QPDFJob::doListAttachments(QPDF& pdf) |
| 995 | 994 | auto efoh = i.second; |
| 996 | 995 | *this->m->log->getInfo() |
| 997 | 996 | << key << " -> " |
| 998 | - << efoh->getEmbeddedFileStream().getObjGen().unparse() << "\n"; | |
| 997 | + << efoh->getEmbeddedFileStream().getObjGen().unparse(',') | |
| 998 | + << "\n"; | |
| 999 | 999 | doIfVerbose([&](Pipeline& v, std::string const& prefix) { |
| 1000 | 1000 | auto desc = efoh->getDescription(); |
| 1001 | 1001 | if (!desc.empty()) { |
| ... | ... | @@ -1010,7 +1010,7 @@ QPDFJob::doListAttachments(QPDF& pdf) |
| 1010 | 1010 | for (auto i2: efoh->getEmbeddedFileStreams().ditems()) { |
| 1011 | 1011 | auto efs = QPDFEFStreamObjectHelper(i2.second); |
| 1012 | 1012 | v << " " << i2.first << " -> " |
| 1013 | - << efs.getObjectHandle().getObjGen().unparse() << "\n"; | |
| 1013 | + << efs.getObjectHandle().getObjGen().unparse(',') << "\n"; | |
| 1014 | 1014 | v << " creation date: " << efs.getCreationDate() |
| 1015 | 1015 | << "\n" |
| 1016 | 1016 | << " modification date: " << efs.getModDate() << "\n" |
| ... | ... | @@ -2463,7 +2463,7 @@ QPDFJob::shouldRemoveUnreferencedResources(QPDF& pdf) |
| 2463 | 2463 | QTC::TC("qpdf", "QPDFJob found resources in non-leaf"); |
| 2464 | 2464 | doIfVerbose([&](Pipeline& v, std::string const& prefix) { |
| 2465 | 2465 | v << " found resources in non-leaf page node " |
| 2466 | - << og.getObj() << " " << og.getGen() << "\n"; | |
| 2466 | + << og.unparse(' ') << "\n"; | |
| 2467 | 2467 | }); |
| 2468 | 2468 | return true; |
| 2469 | 2469 | } |
| ... | ... | @@ -2480,9 +2480,8 @@ QPDFJob::shouldRemoveUnreferencedResources(QPDF& pdf) |
| 2480 | 2480 | QTC::TC("qpdf", "QPDFJob found shared resources in leaf"); |
| 2481 | 2481 | doIfVerbose([&](Pipeline& v, std::string const& prefix) { |
| 2482 | 2482 | v << " found shared resources in leaf node " |
| 2483 | - << og.getObj() << " " << og.getGen() << ": " | |
| 2484 | - << resources_og.getObj() << " " | |
| 2485 | - << resources_og.getGen() << "\n"; | |
| 2483 | + << og.unparse(' ') << ": " | |
| 2484 | + << resources_og.unparse(' ') << "\n"; | |
| 2486 | 2485 | }); |
| 2487 | 2486 | return true; |
| 2488 | 2487 | } |
| ... | ... | @@ -2497,8 +2496,7 @@ QPDFJob::shouldRemoveUnreferencedResources(QPDF& pdf) |
| 2497 | 2496 | QTC::TC("qpdf", "QPDFJob found shared xobject in leaf"); |
| 2498 | 2497 | doIfVerbose([&](Pipeline& v, std::string const& prefix) { |
| 2499 | 2498 | v << " found shared xobject in leaf node " |
| 2500 | - << og.getObj() << " " << og.getGen() << ": " | |
| 2501 | - << xobject_og.getObj() << " " << xobject_og.getGen() | |
| 2499 | + << og.unparse(' ') << ": " << xobject_og.unparse(' ') | |
| 2502 | 2500 | << "\n"; |
| 2503 | 2501 | }); |
| 2504 | 2502 | return true; |
| ... | ... | @@ -3375,7 +3373,7 @@ QPDFJob::writeJSON(QPDF& pdf) |
| 3375 | 3373 | auto wanted = getWantedJSONObjects(); |
| 3376 | 3374 | for (auto const& og: wanted) { |
| 3377 | 3375 | std::ostringstream s; |
| 3378 | - s << "obj:" << og.getObj() << " " << og.getGen() << " R"; | |
| 3376 | + s << "obj:" << og.unparse(' ') << " R"; | |
| 3379 | 3377 | json_objects.insert(s.str()); |
| 3380 | 3378 | } |
| 3381 | 3379 | pdf.writeJSON( | ... | ... |
libqpdf/QPDFObjGen.cc
0 โ 100644
| 1 | +#include <qpdf/QPDFObjGen.hh> | |
| 2 | + | |
| 3 | +#include <qpdf/QUtil.hh> | |
| 4 | + | |
| 5 | +std::ostream& | |
| 6 | +operator<<(std::ostream& os, const QPDFObjGen& og) | |
| 7 | +{ | |
| 8 | + os << og.obj << "," << og.gen; | |
| 9 | + return os; | |
| 10 | +} | |
| 11 | + | |
| 12 | +std::string | |
| 13 | +QPDFObjGen::unparse(char separator) const | |
| 14 | +{ | |
| 15 | + return QUtil::int_to_string(this->obj) + separator + | |
| 16 | + QUtil::int_to_string(this->gen); | |
| 17 | +} | ... | ... |
libqpdf/QPDFObjectHandle.cc
| ... | ... | @@ -53,6 +53,24 @@ QPDFObjectHandle::StreamDataProvider::~StreamDataProvider() |
| 53 | 53 | |
| 54 | 54 | void |
| 55 | 55 | QPDFObjectHandle::StreamDataProvider::provideStreamData( |
| 56 | + QPDFObjGen const& og, Pipeline* pipeline) | |
| 57 | +{ | |
| 58 | + return provideStreamData(og.getObj(), og.getGen(), pipeline); | |
| 59 | +} | |
| 60 | + | |
| 61 | +bool | |
| 62 | +QPDFObjectHandle::StreamDataProvider::provideStreamData( | |
| 63 | + QPDFObjGen const& og, | |
| 64 | + Pipeline* pipeline, | |
| 65 | + bool suppress_warnings, | |
| 66 | + bool will_retry) | |
| 67 | +{ | |
| 68 | + return provideStreamData( | |
| 69 | + og.getObj(), og.getGen(), pipeline, suppress_warnings, will_retry); | |
| 70 | +} | |
| 71 | + | |
| 72 | +void | |
| 73 | +QPDFObjectHandle::StreamDataProvider::provideStreamData( | |
| 56 | 74 | int objid, int generation, Pipeline* pipeline) |
| 57 | 75 | { |
| 58 | 76 | throw std::logic_error( |
| ... | ... | @@ -90,8 +108,7 @@ namespace |
| 90 | 108 | { |
| 91 | 109 | } |
| 92 | 110 | virtual ~CoalesceProvider() = default; |
| 93 | - virtual void | |
| 94 | - provideStreamData(int objid, int generation, Pipeline* pipeline); | |
| 111 | + virtual void provideStreamData(QPDFObjGen const&, Pipeline* pipeline); | |
| 95 | 112 | |
| 96 | 113 | private: |
| 97 | 114 | QPDFObjectHandle containing_page; |
| ... | ... | @@ -100,12 +117,11 @@ namespace |
| 100 | 117 | } // namespace |
| 101 | 118 | |
| 102 | 119 | void |
| 103 | -CoalesceProvider::provideStreamData(int, int, Pipeline* p) | |
| 120 | +CoalesceProvider::provideStreamData(QPDFObjGen const&, Pipeline* p) | |
| 104 | 121 | { |
| 105 | 122 | QTC::TC("qpdf", "QPDFObjectHandle coalesce provide stream data"); |
| 106 | - std::string description = "page object " + | |
| 107 | - QUtil::int_to_string(containing_page.getObjectID()) + " " + | |
| 108 | - QUtil::int_to_string(containing_page.getGeneration()); | |
| 123 | + std::string description = | |
| 124 | + "page object " + containing_page.getObjGen().unparse(' '); | |
| 109 | 125 | std::string all_description; |
| 110 | 126 | old_contents.pipeContentStreams(p, description, all_description); |
| 111 | 127 | } |
| ... | ... | @@ -219,27 +235,22 @@ LastChar::getLastChar() |
| 219 | 235 | |
| 220 | 236 | QPDFObjectHandle::QPDFObjectHandle() : |
| 221 | 237 | initialized(false), |
| 222 | - qpdf(0), | |
| 223 | - objid(0), | |
| 224 | - generation(0), | |
| 238 | + qpdf(nullptr), | |
| 225 | 239 | reserved(false) |
| 226 | 240 | { |
| 227 | 241 | } |
| 228 | 242 | |
| 229 | -QPDFObjectHandle::QPDFObjectHandle(QPDF* qpdf, int objid, int generation) : | |
| 243 | +QPDFObjectHandle::QPDFObjectHandle(QPDF* qpdf, QPDFObjGen const& og) : | |
| 230 | 244 | initialized(true), |
| 231 | 245 | qpdf(qpdf), |
| 232 | - objid(objid), | |
| 233 | - generation(generation), | |
| 246 | + og(og), | |
| 234 | 247 | reserved(false) |
| 235 | 248 | { |
| 236 | 249 | } |
| 237 | 250 | |
| 238 | 251 | QPDFObjectHandle::QPDFObjectHandle(std::shared_ptr<QPDFObject> const& data) : |
| 239 | 252 | initialized(true), |
| 240 | - qpdf(0), | |
| 241 | - objid(0), | |
| 242 | - generation(0), | |
| 253 | + qpdf(nullptr), | |
| 243 | 254 | obj(data), |
| 244 | 255 | reserved(false) |
| 245 | 256 | { |
| ... | ... | @@ -1431,15 +1442,14 @@ namespace |
| 1431 | 1442 | } |
| 1432 | 1443 | |
| 1433 | 1444 | virtual void |
| 1434 | - provideStreamData(int, int, Pipeline* pipeline) override | |
| 1445 | + provideStreamData(QPDFObjGen const&, Pipeline* pipeline) override | |
| 1435 | 1446 | { |
| 1436 | 1447 | p1(pipeline); |
| 1437 | 1448 | } |
| 1438 | 1449 | |
| 1439 | 1450 | virtual bool |
| 1440 | 1451 | provideStreamData( |
| 1441 | - int, | |
| 1442 | - int, | |
| 1452 | + QPDFObjGen const&, | |
| 1443 | 1453 | Pipeline* pipeline, |
| 1444 | 1454 | bool suppress_warnings, |
| 1445 | 1455 | bool will_retry) override |
| ... | ... | @@ -1482,26 +1492,19 @@ QPDFObjectHandle::replaceStreamData( |
| 1482 | 1492 | QPDFObjGen |
| 1483 | 1493 | QPDFObjectHandle::getObjGen() const |
| 1484 | 1494 | { |
| 1485 | - return QPDFObjGen(this->objid, this->generation); | |
| 1486 | -} | |
| 1487 | - | |
| 1488 | -std::string | |
| 1489 | -QPDFObjectHandle::getObjGenAsStr() const | |
| 1490 | -{ | |
| 1491 | - return QUtil::int_to_string(this->objid) + " " + | |
| 1492 | - QUtil::int_to_string(this->generation); | |
| 1495 | + return og; | |
| 1493 | 1496 | } |
| 1494 | 1497 | |
| 1495 | 1498 | int |
| 1496 | 1499 | QPDFObjectHandle::getObjectID() const |
| 1497 | 1500 | { |
| 1498 | - return this->objid; | |
| 1501 | + return og.getObj(); | |
| 1499 | 1502 | } |
| 1500 | 1503 | |
| 1501 | 1504 | int |
| 1502 | 1505 | QPDFObjectHandle::getGeneration() const |
| 1503 | 1506 | { |
| 1504 | - return this->generation; | |
| 1507 | + return og.getGen(); | |
| 1505 | 1508 | } |
| 1506 | 1509 | |
| 1507 | 1510 | std::map<std::string, QPDFObjectHandle> |
| ... | ... | @@ -1556,7 +1559,7 @@ QPDFObjectHandle::arrayOrStreamToStreamArray( |
| 1556 | 1559 | } else { |
| 1557 | 1560 | all_description += ","; |
| 1558 | 1561 | } |
| 1559 | - all_description += " stream " + item.getObjGenAsStr(); | |
| 1562 | + all_description += " stream " + item.getObjGen().unparse(' '); | |
| 1560 | 1563 | } |
| 1561 | 1564 | |
| 1562 | 1565 | return result; |
| ... | ... | @@ -1565,7 +1568,7 @@ QPDFObjectHandle::arrayOrStreamToStreamArray( |
| 1565 | 1568 | std::vector<QPDFObjectHandle> |
| 1566 | 1569 | QPDFObjectHandle::getPageContents() |
| 1567 | 1570 | { |
| 1568 | - std::string description = "page object " + getObjGenAsStr(); | |
| 1571 | + std::string description = "page object " + getObjGen().unparse(' '); | |
| 1569 | 1572 | std::string all_description; |
| 1570 | 1573 | return this->getKey("/Contents") |
| 1571 | 1574 | .arrayOrStreamToStreamArray(description, all_description); |
| ... | ... | @@ -1674,7 +1677,7 @@ QPDFObjectHandle::unparse() |
| 1674 | 1677 | { |
| 1675 | 1678 | std::string result; |
| 1676 | 1679 | if (this->isIndirect()) { |
| 1677 | - result = getObjGenAsStr() + " R"; | |
| 1680 | + result = getObjGen().unparse(' ') + " R"; | |
| 1678 | 1681 | } else { |
| 1679 | 1682 | result = unparseResolved(); |
| 1680 | 1683 | } |
| ... | ... | @@ -1789,7 +1792,7 @@ QPDFObjectHandle::parse( |
| 1789 | 1792 | void |
| 1790 | 1793 | QPDFObjectHandle::pipePageContents(Pipeline* p) |
| 1791 | 1794 | { |
| 1792 | - std::string description = "page object " + getObjGenAsStr(); | |
| 1795 | + std::string description = "page object " + getObjGen().unparse(' '); | |
| 1793 | 1796 | std::string all_description; |
| 1794 | 1797 | this->getKey("/Contents") |
| 1795 | 1798 | .pipeContentStreams(p, description, all_description); |
| ... | ... | @@ -1813,7 +1816,7 @@ QPDFObjectHandle::pipeContentStreams( |
| 1813 | 1816 | throw QPDFExc( |
| 1814 | 1817 | qpdf_e_damaged_pdf, |
| 1815 | 1818 | "content stream", |
| 1816 | - "content stream object " + stream.getObjGenAsStr(), | |
| 1819 | + "content stream object " + stream.getObjGen().unparse(' '), | |
| 1817 | 1820 | 0, |
| 1818 | 1821 | "errors while decoding content stream"); |
| 1819 | 1822 | } |
| ... | ... | @@ -1829,7 +1832,7 @@ QPDFObjectHandle::pipeContentStreams( |
| 1829 | 1832 | void |
| 1830 | 1833 | QPDFObjectHandle::parsePageContents(ParserCallbacks* callbacks) |
| 1831 | 1834 | { |
| 1832 | - std::string description = "page object " + getObjGenAsStr(); | |
| 1835 | + std::string description = "page object " + getObjGen().unparse(' '); | |
| 1833 | 1836 | this->getKey("/Contents") |
| 1834 | 1837 | .parseContentStream_internal(description, callbacks); |
| 1835 | 1838 | } |
| ... | ... | @@ -1837,14 +1840,15 @@ QPDFObjectHandle::parsePageContents(ParserCallbacks* callbacks) |
| 1837 | 1840 | void |
| 1838 | 1841 | QPDFObjectHandle::parseAsContents(ParserCallbacks* callbacks) |
| 1839 | 1842 | { |
| 1840 | - std::string description = "object " + getObjGenAsStr(); | |
| 1843 | + std::string description = "object " + getObjGen().unparse(' '); | |
| 1841 | 1844 | this->parseContentStream_internal(description, callbacks); |
| 1842 | 1845 | } |
| 1843 | 1846 | |
| 1844 | 1847 | void |
| 1845 | 1848 | QPDFObjectHandle::filterPageContents(TokenFilter* filter, Pipeline* next) |
| 1846 | 1849 | { |
| 1847 | - auto description = "token filter for page object " + getObjGenAsStr(); | |
| 1850 | + auto description = | |
| 1851 | + "token filter for page object " + getObjGen().unparse(' '); | |
| 1848 | 1852 | Pl_QPDFTokenizer token_pipeline(description.c_str(), filter, next); |
| 1849 | 1853 | this->pipePageContents(&token_pipeline); |
| 1850 | 1854 | } |
| ... | ... | @@ -1852,7 +1856,7 @@ QPDFObjectHandle::filterPageContents(TokenFilter* filter, Pipeline* next) |
| 1852 | 1856 | void |
| 1853 | 1857 | QPDFObjectHandle::filterAsContents(TokenFilter* filter, Pipeline* next) |
| 1854 | 1858 | { |
| 1855 | - auto description = "token filter for object " + getObjGenAsStr(); | |
| 1859 | + auto description = "token filter for object " + getObjGen().unparse(' '); | |
| 1856 | 1860 | Pl_QPDFTokenizer token_pipeline(description.c_str(), filter, next); |
| 1857 | 1861 | this->pipeStreamData(&token_pipeline, 0, qpdf_dl_specialized); |
| 1858 | 1862 | } |
| ... | ... | @@ -2192,8 +2196,9 @@ QPDFObjectHandle::parseInternal( |
| 2192 | 2196 | // Try to resolve indirect objects |
| 2193 | 2197 | object = newIndirect( |
| 2194 | 2198 | context, |
| 2195 | - olist.at(olist.size() - 2).getIntValueAsInt(), | |
| 2196 | - olist.at(olist.size() - 1).getIntValueAsInt()); | |
| 2199 | + QPDFObjGen( | |
| 2200 | + olist.at(olist.size() - 2).getIntValueAsInt(), | |
| 2201 | + olist.at(olist.size() - 1).getIntValueAsInt())); | |
| 2197 | 2202 | olist.remove_last(); |
| 2198 | 2203 | olist.remove_last(); |
| 2199 | 2204 | } else if ((value == "endobj") && (state == st_top)) { |
| ... | ... | @@ -2481,9 +2486,9 @@ QPDFObjectHandle::setParsedOffset(qpdf_offset_t offset) |
| 2481 | 2486 | } |
| 2482 | 2487 | |
| 2483 | 2488 | QPDFObjectHandle |
| 2484 | -QPDFObjectHandle::newIndirect(QPDF* qpdf, int objid, int generation) | |
| 2489 | +QPDFObjectHandle::newIndirect(QPDF* qpdf, QPDFObjGen const& og) | |
| 2485 | 2490 | { |
| 2486 | - if (objid == 0) { | |
| 2491 | + if (!og.isIndirect()) { | |
| 2487 | 2492 | // Special case: QPDF uses objid 0 as a sentinel for direct |
| 2488 | 2493 | // objects, and the PDF specification doesn't allow for object |
| 2489 | 2494 | // 0. Treat indirect references to object 0 as null so that we |
| ... | ... | @@ -2492,7 +2497,7 @@ QPDFObjectHandle::newIndirect(QPDF* qpdf, int objid, int generation) |
| 2492 | 2497 | return newNull(); |
| 2493 | 2498 | } |
| 2494 | 2499 | |
| 2495 | - return QPDFObjectHandle(qpdf, objid, generation); | |
| 2500 | + return QPDFObjectHandle(qpdf, og); | |
| 2496 | 2501 | } |
| 2497 | 2502 | |
| 2498 | 2503 | QPDFObjectHandle |
| ... | ... | @@ -2640,14 +2645,13 @@ QPDFObjectHandle::newDictionary( |
| 2640 | 2645 | QPDFObjectHandle |
| 2641 | 2646 | QPDFObjectHandle::newStream( |
| 2642 | 2647 | QPDF* qpdf, |
| 2643 | - int objid, | |
| 2644 | - int generation, | |
| 2648 | + QPDFObjGen const& og, | |
| 2645 | 2649 | QPDFObjectHandle stream_dict, |
| 2646 | 2650 | qpdf_offset_t offset, |
| 2647 | 2651 | size_t length) |
| 2648 | 2652 | { |
| 2649 | - QPDFObjectHandle result = QPDFObjectHandle(QPDF_Stream::create( | |
| 2650 | - qpdf, objid, generation, stream_dict, offset, length)); | |
| 2653 | + QPDFObjectHandle result = QPDFObjectHandle( | |
| 2654 | + QPDF_Stream::create(qpdf, og, stream_dict, offset, length)); | |
| 2651 | 2655 | if (offset) { |
| 2652 | 2656 | result.setParsedOffset(offset); |
| 2653 | 2657 | } |
| ... | ... | @@ -2663,11 +2667,11 @@ QPDFObjectHandle::newStream(QPDF* qpdf) |
| 2663 | 2667 | } |
| 2664 | 2668 | QTC::TC("qpdf", "QPDFObjectHandle newStream"); |
| 2665 | 2669 | QPDFObjectHandle stream_dict = newDictionary(); |
| 2666 | - QPDFObjectHandle result = qpdf->makeIndirectObject( | |
| 2667 | - QPDFObjectHandle(QPDF_Stream::create(qpdf, 0, 0, stream_dict, 0, 0))); | |
| 2670 | + QPDFObjectHandle result = qpdf->makeIndirectObject(QPDFObjectHandle( | |
| 2671 | + QPDF_Stream::create(qpdf, QPDFObjGen(), stream_dict, 0, 0))); | |
| 2668 | 2672 | result.dereference(); |
| 2669 | 2673 | QPDF_Stream* stream = dynamic_cast<QPDF_Stream*>(result.obj.get()); |
| 2670 | - stream->setObjGen(result.getObjectID(), result.getGeneration()); | |
| 2674 | + stream->setObjGen(result.getObjGen()); | |
| 2671 | 2675 | return result; |
| 2672 | 2676 | } |
| 2673 | 2677 | |
| ... | ... | @@ -2695,8 +2699,7 @@ QPDFObjectHandle::newReserved(QPDF* qpdf) |
| 2695 | 2699 | // Reserve a spot for this object by assigning it an object |
| 2696 | 2700 | // number, but then return an unresolved handle to the object. |
| 2697 | 2701 | QPDFObjectHandle reserved = qpdf->makeIndirectObject(makeReserved()); |
| 2698 | - QPDFObjectHandle result = | |
| 2699 | - newIndirect(qpdf, reserved.objid, reserved.generation); | |
| 2702 | + QPDFObjectHandle result = newIndirect(qpdf, reserved.getObjGen()); | |
| 2700 | 2703 | result.reserved = true; |
| 2701 | 2704 | return result; |
| 2702 | 2705 | } |
| ... | ... | @@ -2796,9 +2799,8 @@ QPDFObjectHandle::copyObject( |
| 2796 | 2799 | " reserved object handle direct"); |
| 2797 | 2800 | } |
| 2798 | 2801 | |
| 2799 | - this->qpdf = 0; | |
| 2800 | - this->objid = 0; | |
| 2801 | - this->generation = 0; | |
| 2802 | + qpdf = nullptr; | |
| 2803 | + og = QPDFObjGen(); | |
| 2802 | 2804 | |
| 2803 | 2805 | std::shared_ptr<QPDFObject> new_obj; |
| 2804 | 2806 | |
| ... | ... | @@ -3112,7 +3114,7 @@ QPDFObjectHandle::dereference() |
| 3112 | 3114 | } |
| 3113 | 3115 | if (this->obj.get() == 0) { |
| 3114 | 3116 | std::shared_ptr<QPDFObject> obj = |
| 3115 | - QPDF::Resolver::resolve(this->qpdf, getObjectID(), getGeneration()); | |
| 3117 | + QPDF::Resolver::resolve(this->qpdf, getObjGen()); | |
| 3116 | 3118 | if (obj.get() == 0) { |
| 3117 | 3119 | // QPDF::resolve never returns an uninitialized object, but |
| 3118 | 3120 | // check just in case. | ... | ... |
libqpdf/QPDFPageObjectHelper.cc
| ... | ... | @@ -21,8 +21,7 @@ namespace |
| 21 | 21 | { |
| 22 | 22 | } |
| 23 | 23 | virtual ~ContentProvider() = default; |
| 24 | - virtual void | |
| 25 | - provideStreamData(int objid, int generation, Pipeline* pipeline); | |
| 24 | + virtual void provideStreamData(QPDFObjGen const&, Pipeline* pipeline); | |
| 26 | 25 | |
| 27 | 26 | private: |
| 28 | 27 | QPDFObjectHandle from_page; |
| ... | ... | @@ -30,12 +29,11 @@ namespace |
| 30 | 29 | } // namespace |
| 31 | 30 | |
| 32 | 31 | void |
| 33 | -ContentProvider::provideStreamData(int, int, Pipeline* p) | |
| 32 | +ContentProvider::provideStreamData(QPDFObjGen const&, Pipeline* p) | |
| 34 | 33 | { |
| 35 | 34 | Pl_Concatenate concat("concatenate", p); |
| 36 | - std::string description = "contents from page object " + | |
| 37 | - QUtil::int_to_string(from_page.getObjectID()) + " " + | |
| 38 | - QUtil::int_to_string(from_page.getGeneration()); | |
| 35 | + std::string description = | |
| 36 | + "contents from page object " + from_page.getObjGen().unparse(' '); | |
| 39 | 37 | std::string all_description; |
| 40 | 38 | from_page.getKey("/Contents") |
| 41 | 39 | .pipeContentStreams(&concat, description, all_description); | ... | ... |
libqpdf/QPDFWriter.cc
| ... | ... | @@ -1990,9 +1990,8 @@ QPDFWriter::writeObject(QPDFObjectHandle object, int object_stream_index) |
| 1990 | 1990 | if (object_stream_index == -1) { |
| 1991 | 1991 | if (this->m->qdf_mode && (!this->m->suppress_original_object_ids)) { |
| 1992 | 1992 | writeString( |
| 1993 | - "%% Original object ID: " + | |
| 1994 | - QUtil::int_to_string(object.getObjectID()) + " " + | |
| 1995 | - QUtil::int_to_string(object.getGeneration()) + "\n"); | |
| 1993 | + "%% Original object ID: " + object.getObjGen().unparse(' ') + | |
| 1994 | + "\n"); | |
| 1996 | 1995 | } |
| 1997 | 1996 | openObject(new_id); |
| 1998 | 1997 | setDataKey(new_id); | ... | ... |
libqpdf/QPDF_Stream.cc
| ... | ... | @@ -110,14 +110,12 @@ StreamBlobProvider::operator()(Pipeline* p) |
| 110 | 110 | |
| 111 | 111 | QPDF_Stream::QPDF_Stream( |
| 112 | 112 | QPDF* qpdf, |
| 113 | - int objid, | |
| 114 | - int generation, | |
| 113 | + QPDFObjGen const& og, | |
| 115 | 114 | QPDFObjectHandle stream_dict, |
| 116 | 115 | qpdf_offset_t offset, |
| 117 | 116 | size_t length) : |
| 118 | 117 | qpdf(qpdf), |
| 119 | - objid(objid), | |
| 120 | - generation(generation), | |
| 118 | + og(og), | |
| 121 | 119 | filter_on_write(true), |
| 122 | 120 | stream_dict(stream_dict), |
| 123 | 121 | offset(offset), |
| ... | ... | @@ -128,23 +126,18 @@ QPDF_Stream::QPDF_Stream( |
| 128 | 126 | "object for dictionary"); |
| 129 | 127 | } |
| 130 | 128 | setDescription( |
| 131 | - this->qpdf, | |
| 132 | - this->qpdf->getFilename() + ", stream object " + | |
| 133 | - QUtil::int_to_string(this->objid) + " " + | |
| 134 | - QUtil::int_to_string(this->generation)); | |
| 129 | + qpdf, qpdf->getFilename() + ", stream object " + og.unparse(' ')); | |
| 135 | 130 | } |
| 136 | 131 | |
| 137 | 132 | std::shared_ptr<QPDFObject> |
| 138 | 133 | QPDF_Stream::create( |
| 139 | 134 | QPDF* qpdf, |
| 140 | - int objid, | |
| 141 | - int generation, | |
| 135 | + QPDFObjGen const& og, | |
| 142 | 136 | QPDFObjectHandle stream_dict, |
| 143 | 137 | qpdf_offset_t offset, |
| 144 | 138 | size_t length) |
| 145 | 139 | { |
| 146 | - return do_create( | |
| 147 | - new QPDF_Stream(qpdf, objid, generation, stream_dict, offset, length)); | |
| 140 | + return do_create(new QPDF_Stream(qpdf, og, stream_dict, offset, length)); | |
| 148 | 141 | } |
| 149 | 142 | |
| 150 | 143 | std::shared_ptr<QPDFObject> |
| ... | ... | @@ -181,23 +174,21 @@ QPDF_Stream::releaseResolved() |
| 181 | 174 | } |
| 182 | 175 | |
| 183 | 176 | void |
| 184 | -QPDF_Stream::setObjGen(int objid, int generation) | |
| 177 | +QPDF_Stream::setObjGen(QPDFObjGen const& og) | |
| 185 | 178 | { |
| 186 | - if (!((this->objid == 0) && (this->generation == 0))) { | |
| 179 | + if (this->og.isIndirect()) { | |
| 187 | 180 | throw std::logic_error( |
| 188 | 181 | "attempt to set object ID and generation of a stream" |
| 189 | 182 | " that already has them"); |
| 190 | 183 | } |
| 191 | - this->objid = objid; | |
| 192 | - this->generation = generation; | |
| 184 | + this->og = og; | |
| 193 | 185 | } |
| 194 | 186 | |
| 195 | 187 | std::string |
| 196 | 188 | QPDF_Stream::unparse() |
| 197 | 189 | { |
| 198 | 190 | // Unparse stream objects as indirect references |
| 199 | - return QUtil::int_to_string(this->objid) + " " + | |
| 200 | - QUtil::int_to_string(this->generation) + " R"; | |
| 191 | + return og.unparse(' ') + " R"; | |
| 201 | 192 | } |
| 202 | 193 | |
| 203 | 194 | JSON |
| ... | ... | @@ -619,17 +610,12 @@ QPDF_Stream::pipeStreamData( |
| 619 | 610 | Pl_Count count("stream provider count", pipeline); |
| 620 | 611 | if (this->stream_provider->supportsRetry()) { |
| 621 | 612 | if (!this->stream_provider->provideStreamData( |
| 622 | - this->objid, | |
| 623 | - this->generation, | |
| 624 | - &count, | |
| 625 | - suppress_warnings, | |
| 626 | - will_retry)) { | |
| 613 | + og, &count, suppress_warnings, will_retry)) { | |
| 627 | 614 | filter = false; |
| 628 | 615 | success = false; |
| 629 | 616 | } |
| 630 | 617 | } else { |
| 631 | - this->stream_provider->provideStreamData( | |
| 632 | - this->objid, this->generation, &count); | |
| 618 | + this->stream_provider->provideStreamData(og, &count); | |
| 633 | 619 | } |
| 634 | 620 | qpdf_offset_t actual_length = count.getCount(); |
| 635 | 621 | qpdf_offset_t desired_length = 0; |
| ... | ... | @@ -642,10 +628,8 @@ QPDF_Stream::pipeStreamData( |
| 642 | 628 | // This would be caused by programmer error on the |
| 643 | 629 | // part of a library user, not by invalid input data. |
| 644 | 630 | throw std::runtime_error( |
| 645 | - "stream data provider for " + | |
| 646 | - QUtil::int_to_string(this->objid) + " " + | |
| 647 | - QUtil::int_to_string(this->generation) + " provided " + | |
| 648 | - QUtil::int_to_string(actual_length) + | |
| 631 | + "stream data provider for " + og.unparse(' ') + | |
| 632 | + " provided " + QUtil::int_to_string(actual_length) + | |
| 649 | 633 | " bytes instead of expected " + |
| 650 | 634 | QUtil::int_to_string(desired_length) + " bytes"); |
| 651 | 635 | } |
| ... | ... | @@ -661,8 +645,7 @@ QPDF_Stream::pipeStreamData( |
| 661 | 645 | QTC::TC("qpdf", "QPDF_Stream pipe original stream data"); |
| 662 | 646 | if (!QPDF::Pipe::pipeStreamData( |
| 663 | 647 | this->qpdf, |
| 664 | - this->objid, | |
| 665 | - this->generation, | |
| 648 | + og, | |
| 666 | 649 | this->offset, |
| 667 | 650 | this->length, |
| 668 | 651 | this->stream_dict, | ... | ... |
libqpdf/QPDF_encryption.cc
| ... | ... | @@ -1075,8 +1075,7 @@ QPDF::initializeEncryption() |
| 1075 | 1075 | std::string |
| 1076 | 1076 | QPDF::getKeyForObject( |
| 1077 | 1077 | std::shared_ptr<EncryptionParameters> encp, |
| 1078 | - int objid, | |
| 1079 | - int generation, | |
| 1078 | + QPDFObjGen const& og, | |
| 1080 | 1079 | bool use_aes) |
| 1081 | 1080 | { |
| 1082 | 1081 | if (!encp->encrypted) { |
| ... | ... | @@ -1084,26 +1083,24 @@ QPDF::getKeyForObject( |
| 1084 | 1083 | "request for encryption key in non-encrypted PDF"); |
| 1085 | 1084 | } |
| 1086 | 1085 | |
| 1087 | - if (!((objid == encp->cached_key_objid) && | |
| 1088 | - (generation == encp->cached_key_generation))) { | |
| 1086 | + if (og != encp->cached_key_og) { | |
| 1089 | 1087 | encp->cached_object_encryption_key = compute_data_key( |
| 1090 | 1088 | encp->encryption_key, |
| 1091 | - objid, | |
| 1092 | - generation, | |
| 1089 | + og.getObj(), | |
| 1090 | + og.getGen(), | |
| 1093 | 1091 | use_aes, |
| 1094 | 1092 | encp->encryption_V, |
| 1095 | 1093 | encp->encryption_R); |
| 1096 | - encp->cached_key_objid = objid; | |
| 1097 | - encp->cached_key_generation = generation; | |
| 1094 | + encp->cached_key_og = og; | |
| 1098 | 1095 | } |
| 1099 | 1096 | |
| 1100 | 1097 | return encp->cached_object_encryption_key; |
| 1101 | 1098 | } |
| 1102 | 1099 | |
| 1103 | 1100 | void |
| 1104 | -QPDF::decryptString(std::string& str, int objid, int generation) | |
| 1101 | +QPDF::decryptString(std::string& str, QPDFObjGen const& og) | |
| 1105 | 1102 | { |
| 1106 | - if (objid == 0) { | |
| 1103 | + if (!og.isIndirect()) { | |
| 1107 | 1104 | return; |
| 1108 | 1105 | } |
| 1109 | 1106 | bool use_aes = false; |
| ... | ... | @@ -1139,8 +1136,7 @@ QPDF::decryptString(std::string& str, int objid, int generation) |
| 1139 | 1136 | } |
| 1140 | 1137 | } |
| 1141 | 1138 | |
| 1142 | - std::string key = | |
| 1143 | - getKeyForObject(this->m->encp, objid, generation, use_aes); | |
| 1139 | + std::string key = getKeyForObject(this->m->encp, og, use_aes); | |
| 1144 | 1140 | try { |
| 1145 | 1141 | if (use_aes) { |
| 1146 | 1142 | QTC::TC("qpdf", "QPDF_encryption aes decode string"); |
| ... | ... | @@ -1175,9 +1171,8 @@ QPDF::decryptString(std::string& str, int objid, int generation) |
| 1175 | 1171 | this->m->file->getName(), |
| 1176 | 1172 | this->m->last_object_description, |
| 1177 | 1173 | this->m->file->getLastOffset(), |
| 1178 | - "error decrypting string for object " + | |
| 1179 | - QUtil::int_to_string(objid) + " " + | |
| 1180 | - QUtil::int_to_string(generation) + ": " + e.what()); | |
| 1174 | + "error decrypting string for object " + og.unparse() + ": " + | |
| 1175 | + e.what()); | |
| 1181 | 1176 | } |
| 1182 | 1177 | } |
| 1183 | 1178 | |
| ... | ... | @@ -1187,8 +1182,7 @@ QPDF::decryptStream( |
| 1187 | 1182 | std::shared_ptr<InputSource> file, |
| 1188 | 1183 | QPDF& qpdf_for_warning, |
| 1189 | 1184 | Pipeline*& pipeline, |
| 1190 | - int objid, | |
| 1191 | - int generation, | |
| 1185 | + QPDFObjGen const& og, | |
| 1192 | 1186 | QPDFObjectHandle& stream_dict, |
| 1193 | 1187 | std::vector<std::shared_ptr<Pipeline>>& heap) |
| 1194 | 1188 | { |
| ... | ... | @@ -1283,7 +1277,7 @@ QPDF::decryptStream( |
| 1283 | 1277 | break; |
| 1284 | 1278 | } |
| 1285 | 1279 | } |
| 1286 | - std::string key = getKeyForObject(encp, objid, generation, use_aes); | |
| 1280 | + std::string key = getKeyForObject(encp, og, use_aes); | |
| 1287 | 1281 | std::shared_ptr<Pipeline> new_pipeline; |
| 1288 | 1282 | if (use_aes) { |
| 1289 | 1283 | QTC::TC("qpdf", "QPDF_encryption aes decode stream"); | ... | ... |
libqpdf/QPDF_json.cc
| ... | ... | @@ -371,9 +371,10 @@ QPDF::JSONReactor::containerEnd(JSON const& value) |
| 371 | 371 | QPDFObjectHandle |
| 372 | 372 | QPDF::JSONReactor::reserveObject(int obj, int gen) |
| 373 | 373 | { |
| 374 | - auto oh = pdf.reserveObjectIfNotExists(obj, gen); | |
| 374 | + QPDFObjGen og(obj, gen); | |
| 375 | + auto oh = pdf.reserveObjectIfNotExists(og); | |
| 375 | 376 | if (oh.isReserved()) { |
| 376 | - this->reserved.insert(QPDFObjGen(obj, gen)); | |
| 377 | + this->reserved.insert(og); | |
| 377 | 378 | } |
| 378 | 379 | return oh; |
| 379 | 380 | } |
| ... | ... | @@ -495,8 +496,7 @@ QPDF::JSONReactor::dictionaryItem(std::string const& key, JSON const& value) |
| 495 | 496 | QTC::TC("qpdf", "QPDF_json updating existing stream"); |
| 496 | 497 | } else { |
| 497 | 498 | this->this_stream_needs_data = true; |
| 498 | - replacement = | |
| 499 | - pdf.reserveStream(tos.getObjectID(), tos.getGeneration()); | |
| 499 | + replacement = pdf.reserveStream(tos.getObjGen()); | |
| 500 | 500 | replaceObject(tos, replacement, value); |
| 501 | 501 | } |
| 502 | 502 | } else { | ... | ... |
libqpdf/QPDF_linearization.cc
| ... | ... | @@ -137,8 +137,8 @@ QPDF::isLinearized() |
| 137 | 137 | return false; |
| 138 | 138 | } |
| 139 | 139 | |
| 140 | - QPDFObjectHandle candidate = | |
| 141 | - QPDFObjectHandle::Factory::newIndirect(this, lindict_obj, 0); | |
| 140 | + QPDFObjectHandle candidate = QPDFObjectHandle::Factory::newIndirect( | |
| 141 | + this, QPDFObjGen(lindict_obj, 0)); | |
| 142 | 142 | if (!candidate.isDictionary()) { |
| 143 | 143 | return false; |
| 144 | 144 | } |
| ... | ... | @@ -325,11 +325,10 @@ QPDF::readLinearizationData() |
| 325 | 325 | QPDFObjectHandle |
| 326 | 326 | QPDF::readHintStream(Pipeline& pl, qpdf_offset_t offset, size_t length) |
| 327 | 327 | { |
| 328 | - int obj; | |
| 329 | - int gen; | |
| 328 | + QPDFObjGen og; | |
| 330 | 329 | QPDFObjectHandle H = readObjectAtOffset( |
| 331 | - false, offset, "linearization hint stream", 0, 0, obj, gen); | |
| 332 | - ObjCache& oc = this->m->obj_cache[QPDFObjGen(obj, gen)]; | |
| 330 | + false, offset, "linearization hint stream", QPDFObjGen(0, 0), og); | |
| 331 | + ObjCache& oc = this->m->obj_cache[og]; | |
| 333 | 332 | qpdf_offset_t min_end_offset = oc.end_before_space; |
| 334 | 333 | qpdf_offset_t max_end_offset = oc.end_after_space; |
| 335 | 334 | if (!H.isStream()) { |
| ... | ... | @@ -707,7 +706,7 @@ QPDF::getUncompressedObject( |
| 707 | 706 | return obj; |
| 708 | 707 | } else { |
| 709 | 708 | int repl = (*(object_stream_data.find(obj.getObjectID()))).second; |
| 710 | - return objGenToIndirect(QPDFObjGen(repl, 0)); | |
| 709 | + return getObjectByObjGen(QPDFObjGen(repl, 0)); | |
| 711 | 710 | } |
| 712 | 711 | } |
| 713 | 712 | |
| ... | ... | @@ -1144,12 +1143,6 @@ QPDF::dumpHGeneric(HGeneric& t) |
| 1144 | 1143 | << "group_length: " << t.group_length << "\n"; |
| 1145 | 1144 | } |
| 1146 | 1145 | |
| 1147 | -QPDFObjectHandle | |
| 1148 | -QPDF::objGenToIndirect(QPDFObjGen const& og) | |
| 1149 | -{ | |
| 1150 | - return getObjectByID(og.getObj(), og.getGen()); | |
| 1151 | -} | |
| 1152 | - | |
| 1153 | 1146 | void |
| 1154 | 1147 | QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) |
| 1155 | 1148 | { |
| ... | ... | @@ -1388,9 +1381,9 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) |
| 1388 | 1381 | stopOnError("found other than one root while" |
| 1389 | 1382 | " calculating linearization data"); |
| 1390 | 1383 | } |
| 1391 | - this->m->part4.push_back(objGenToIndirect(*(lc_root.begin()))); | |
| 1384 | + this->m->part4.push_back(getObjectByObjGen(*(lc_root.begin()))); | |
| 1392 | 1385 | for (auto const& og: lc_open_document) { |
| 1393 | - this->m->part4.push_back(objGenToIndirect(og)); | |
| 1386 | + this->m->part4.push_back(getObjectByObjGen(og)); | |
| 1394 | 1387 | } |
| 1395 | 1388 | |
| 1396 | 1389 | // Part 6: first page objects. Note: implementation note 124 |
| ... | ... | @@ -1419,11 +1412,11 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) |
| 1419 | 1412 | // hint tables. |
| 1420 | 1413 | |
| 1421 | 1414 | for (auto const& og: lc_first_page_private) { |
| 1422 | - this->m->part6.push_back(objGenToIndirect(og)); | |
| 1415 | + this->m->part6.push_back(getObjectByObjGen(og)); | |
| 1423 | 1416 | } |
| 1424 | 1417 | |
| 1425 | 1418 | for (auto const& og: lc_first_page_shared) { |
| 1426 | - this->m->part6.push_back(objGenToIndirect(og)); | |
| 1419 | + this->m->part6.push_back(getObjectByObjGen(og)); | |
| 1427 | 1420 | } |
| 1428 | 1421 | |
| 1429 | 1422 | // Place the outline dictionary if it goes in the first page section. |
| ... | ... | @@ -1469,7 +1462,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) |
| 1469 | 1462 | for (auto const& og: this->m->obj_user_to_objects[ou]) { |
| 1470 | 1463 | if (lc_other_page_private.count(og)) { |
| 1471 | 1464 | lc_other_page_private.erase(og); |
| 1472 | - this->m->part7.push_back(objGenToIndirect(og)); | |
| 1465 | + this->m->part7.push_back(getObjectByObjGen(og)); | |
| 1473 | 1466 | ++this->m->c_page_offset_data.entries.at(i).nobjects; |
| 1474 | 1467 | } |
| 1475 | 1468 | } |
| ... | ... | @@ -1486,7 +1479,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) |
| 1486 | 1479 | |
| 1487 | 1480 | // Order is unimportant. |
| 1488 | 1481 | for (auto const& og: lc_other_page_shared) { |
| 1489 | - this->m->part8.push_back(objGenToIndirect(og)); | |
| 1482 | + this->m->part8.push_back(getObjectByObjGen(og)); | |
| 1490 | 1483 | } |
| 1491 | 1484 | |
| 1492 | 1485 | // Part 9: other objects |
| ... | ... | @@ -1508,7 +1501,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) |
| 1508 | 1501 | for (auto const& og: pages_ogs) { |
| 1509 | 1502 | if (lc_other.count(og)) { |
| 1510 | 1503 | lc_other.erase(og); |
| 1511 | - this->m->part9.push_back(objGenToIndirect(og)); | |
| 1504 | + this->m->part9.push_back(getObjectByObjGen(og)); | |
| 1512 | 1505 | } |
| 1513 | 1506 | } |
| 1514 | 1507 | |
| ... | ... | @@ -1538,7 +1531,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) |
| 1538 | 1531 | for (auto const& og: ogs) { |
| 1539 | 1532 | if (lc_thumbnail_private.count(og)) { |
| 1540 | 1533 | lc_thumbnail_private.erase(og); |
| 1541 | - this->m->part9.push_back(objGenToIndirect(og)); | |
| 1534 | + this->m->part9.push_back(getObjectByObjGen(og)); | |
| 1542 | 1535 | } |
| 1543 | 1536 | } |
| 1544 | 1537 | } |
| ... | ... | @@ -1551,7 +1544,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) |
| 1551 | 1544 | |
| 1552 | 1545 | // Place shared thumbnail objects |
| 1553 | 1546 | for (auto const& og: lc_thumbnail_shared) { |
| 1554 | - this->m->part9.push_back(objGenToIndirect(og)); | |
| 1547 | + this->m->part9.push_back(getObjectByObjGen(og)); | |
| 1555 | 1548 | } |
| 1556 | 1549 | |
| 1557 | 1550 | // Place outlines unless in first page |
| ... | ... | @@ -1561,7 +1554,7 @@ QPDF::calculateLinearizationData(std::map<int, int> const& object_stream_data) |
| 1561 | 1554 | |
| 1562 | 1555 | // Place all remaining objects |
| 1563 | 1556 | for (auto const& og: lc_other) { |
| 1564 | - this->m->part9.push_back(objGenToIndirect(og)); | |
| 1557 | + this->m->part9.push_back(getObjectByObjGen(og)); | |
| 1565 | 1558 | } |
| 1566 | 1559 | |
| 1567 | 1560 | // Make sure we got everything exactly once. |
| ... | ... | @@ -1663,7 +1656,7 @@ QPDF::pushOutlinesToPart( |
| 1663 | 1656 | lc_outlines.erase(outlines_og); |
| 1664 | 1657 | part.push_back(outlines); |
| 1665 | 1658 | for (auto const& og: lc_outlines) { |
| 1666 | - part.push_back(objGenToIndirect(og)); | |
| 1659 | + part.push_back(getObjectByObjGen(og)); | |
| 1667 | 1660 | ++this->m->c_outline_data.nobjects; |
| 1668 | 1661 | } |
| 1669 | 1662 | } | ... | ... |
libqpdf/QPDF_optimization.cc
| ... | ... | @@ -252,9 +252,7 @@ QPDF::pushInheritedAttributesToPageInternal( |
| 252 | 252 | if ((warn_skipped_keys) && (cur_pages.hasKey("/Parent"))) { |
| 253 | 253 | QTC::TC("qpdf", "QPDF unknown key not inherited"); |
| 254 | 254 | setLastObjectDescription( |
| 255 | - "Pages object", | |
| 256 | - cur_pages.getObjectID(), | |
| 257 | - cur_pages.getGeneration()); | |
| 255 | + "Pages object", cur_pages.getObjGen()); | |
| 258 | 256 | warn( |
| 259 | 257 | qpdf_e_pages, |
| 260 | 258 | this->m->last_object_description, | ... | ... |
libqpdf/QPDF_pages.cc
| ... | ... | @@ -207,8 +207,7 @@ QPDF::insertPageobjToPage( |
| 207 | 207 | // that causes this to happen. |
| 208 | 208 | setLastObjectDescription( |
| 209 | 209 | "page " + QUtil::int_to_string(pos) + " (numbered from zero)", |
| 210 | - og.getObj(), | |
| 211 | - og.getGen()); | |
| 210 | + og); | |
| 212 | 211 | throw QPDFExc( |
| 213 | 212 | qpdf_e_pages, |
| 214 | 213 | this->m->file->getName(), |
| ... | ... | @@ -334,7 +333,7 @@ QPDF::findPage(QPDFObjGen const& og) |
| 334 | 333 | auto it = this->m->pageobj_to_pages_pos.find(og); |
| 335 | 334 | if (it == this->m->pageobj_to_pages_pos.end()) { |
| 336 | 335 | QTC::TC("qpdf", "QPDF_pages findPage not found"); |
| 337 | - setLastObjectDescription("page object", og.getObj(), og.getGen()); | |
| 336 | + setLastObjectDescription("page object", og); | |
| 338 | 337 | throw QPDFExc( |
| 339 | 338 | qpdf_e_pages, |
| 340 | 339 | this->m->file->getName(), | ... | ... |
libqpdf/qpdf/QPDF_Stream.hh
| ... | ... | @@ -19,8 +19,7 @@ class QPDF_Stream: public QPDFObject |
| 19 | 19 | virtual ~QPDF_Stream() = default; |
| 20 | 20 | static std::shared_ptr<QPDFObject> create( |
| 21 | 21 | QPDF*, |
| 22 | - int objid, | |
| 23 | - int generation, | |
| 22 | + QPDFObjGen const& og, | |
| 24 | 23 | QPDFObjectHandle stream_dict, |
| 25 | 24 | qpdf_offset_t offset, |
| 26 | 25 | size_t length); |
| ... | ... | @@ -78,7 +77,7 @@ class QPDF_Stream: public QPDFObject |
| 78 | 77 | // Replace object ID and generation. This may only be called if |
| 79 | 78 | // object ID and generation are 0. It is used by QPDFObjectHandle |
| 80 | 79 | // when adding streams to files. |
| 81 | - void setObjGen(int objid, int generation); | |
| 80 | + void setObjGen(QPDFObjGen const& og); | |
| 82 | 81 | |
| 83 | 82 | protected: |
| 84 | 83 | virtual void releaseResolved(); |
| ... | ... | @@ -86,8 +85,7 @@ class QPDF_Stream: public QPDFObject |
| 86 | 85 | private: |
| 87 | 86 | QPDF_Stream( |
| 88 | 87 | QPDF*, |
| 89 | - int objid, | |
| 90 | - int generation, | |
| 88 | + QPDFObjGen const& og, | |
| 91 | 89 | QPDFObjectHandle stream_dict, |
| 92 | 90 | qpdf_offset_t offset, |
| 93 | 91 | size_t length); |
| ... | ... | @@ -111,8 +109,7 @@ class QPDF_Stream: public QPDFObject |
| 111 | 109 | void setDictDescription(); |
| 112 | 110 | |
| 113 | 111 | QPDF* qpdf; |
| 114 | - int objid; | |
| 115 | - int generation; | |
| 112 | + QPDFObjGen og; | |
| 116 | 113 | bool filter_on_write; |
| 117 | 114 | QPDFObjectHandle stream_dict; |
| 118 | 115 | qpdf_offset_t offset; | ... | ... |
qpdf/test_driver.cc
| ... | ... | @@ -56,6 +56,8 @@ class Provider: public QPDFObjectHandle::StreamDataProvider |
| 56 | 56 | virtual void |
| 57 | 57 | provideStreamData(int objid, int generation, Pipeline* p) |
| 58 | 58 | { |
| 59 | + // Don't change signature to use QPDFObjGen const& to detect | |
| 60 | + // problems forwarding to legacy implementations. | |
| 59 | 61 | p->write(b->getBuffer(), b->getSize()); |
| 60 | 62 | if (this->bad_length) { |
| 61 | 63 | unsigned char ch = ' '; | ... | ... |