Commit 5473c0956cdfbe2a72c048b19d9d5334e23007bf
1 parent
aeb66311
Use QPDFObjGen::set in QPDF::replaceForeignIndirectObjects
Showing
2 changed files
with
24 additions
and
32 deletions
include/qpdf/QPDF.hh
| @@ -1017,7 +1017,7 @@ class QPDF | @@ -1017,7 +1017,7 @@ class QPDF | ||
| 1017 | public: | 1017 | public: |
| 1018 | std::map<QPDFObjGen, QPDFObjectHandle> object_map; | 1018 | std::map<QPDFObjGen, QPDFObjectHandle> object_map; |
| 1019 | std::vector<QPDFObjectHandle> to_copy; | 1019 | std::vector<QPDFObjectHandle> to_copy; |
| 1020 | - std::set<QPDFObjGen> visiting; | 1020 | + QPDFObjGen::set visiting; |
| 1021 | }; | 1021 | }; |
| 1022 | 1022 | ||
| 1023 | class EncryptionParameters | 1023 | class EncryptionParameters |
libqpdf/QPDF.cc
| @@ -2176,7 +2176,8 @@ QPDF::copyForeignObject(QPDFObjectHandle foreign) | @@ -2176,7 +2176,8 @@ QPDF::copyForeignObject(QPDFObjectHandle foreign) | ||
| 2176 | void | 2176 | void |
| 2177 | QPDF::reserveObjects(QPDFObjectHandle foreign, ObjCopier& obj_copier, bool top) | 2177 | QPDF::reserveObjects(QPDFObjectHandle foreign, ObjCopier& obj_copier, bool top) |
| 2178 | { | 2178 | { |
| 2179 | - if (foreign.isReserved()) { | 2179 | + auto foreign_tc = foreign.getTypeCode(); |
| 2180 | + if (foreign_tc == ::ot_reserved) { | ||
| 2180 | throw std::logic_error( | 2181 | throw std::logic_error( |
| 2181 | "QPDF: attempting to copy a foreign reserved object"); | 2182 | "QPDF: attempting to copy a foreign reserved object"); |
| 2182 | } | 2183 | } |
| @@ -2193,70 +2194,62 @@ QPDF::reserveObjects(QPDFObjectHandle foreign, ObjCopier& obj_copier, bool top) | @@ -2193,70 +2194,62 @@ QPDF::reserveObjects(QPDFObjectHandle foreign, ObjCopier& obj_copier, bool top) | ||
| 2193 | 2194 | ||
| 2194 | if (foreign.isIndirect()) { | 2195 | if (foreign.isIndirect()) { |
| 2195 | QPDFObjGen foreign_og(foreign.getObjGen()); | 2196 | QPDFObjGen foreign_og(foreign.getObjGen()); |
| 2196 | - if (obj_copier.visiting.find(foreign_og) != obj_copier.visiting.end()) { | ||
| 2197 | - QTC::TC("qpdf", "QPDF loop reserving objects"); | 2197 | + if (obj_copier.object_map.count(foreign_og) > 0) { |
| 2198 | + QTC::TC("qpdf", "QPDF already reserved object"); | ||
| 2199 | + if (obj_copier.visiting.count(foreign_og)) { | ||
| 2200 | + QTC::TC("qpdf", "QPDF loop reserving objects"); | ||
| 2201 | + } | ||
| 2198 | return; | 2202 | return; |
| 2199 | } | 2203 | } |
| 2200 | - if (obj_copier.object_map.find(foreign_og) != | ||
| 2201 | - obj_copier.object_map.end()) { | ||
| 2202 | - QTC::TC("qpdf", "QPDF already reserved object"); | 2204 | + if (!obj_copier.visiting.add(foreign_og)) { |
| 2203 | return; | 2205 | return; |
| 2204 | } | 2206 | } |
| 2205 | QTC::TC("qpdf", "QPDF copy indirect"); | 2207 | QTC::TC("qpdf", "QPDF copy indirect"); |
| 2206 | - obj_copier.visiting.insert(foreign_og); | ||
| 2207 | - auto mapping = obj_copier.object_map.find(foreign_og); | ||
| 2208 | - if (mapping == obj_copier.object_map.end()) { | 2208 | + if (obj_copier.object_map.count(foreign_og) == 0) { |
| 2209 | obj_copier.to_copy.push_back(foreign); | 2209 | obj_copier.to_copy.push_back(foreign); |
| 2210 | - QPDFObjectHandle reservation; | ||
| 2211 | - if (foreign.isStream()) { | ||
| 2212 | - reservation = newStream(); | ||
| 2213 | - } else { | ||
| 2214 | - reservation = QPDFObjectHandle::newReserved(this); | ||
| 2215 | - } | ||
| 2216 | - obj_copier.object_map[foreign_og] = reservation; | 2210 | + obj_copier.object_map[foreign_og] = foreign.isStream() |
| 2211 | + ? newStream() | ||
| 2212 | + : QPDFObjectHandle::newReserved(this); | ||
| 2217 | } | 2213 | } |
| 2218 | } | 2214 | } |
| 2219 | 2215 | ||
| 2220 | - if (foreign.isArray()) { | 2216 | + if (foreign_tc == ::ot_array) { |
| 2221 | QTC::TC("qpdf", "QPDF reserve array"); | 2217 | QTC::TC("qpdf", "QPDF reserve array"); |
| 2222 | int n = foreign.getArrayNItems(); | 2218 | int n = foreign.getArrayNItems(); |
| 2223 | for (int i = 0; i < n; ++i) { | 2219 | for (int i = 0; i < n; ++i) { |
| 2224 | reserveObjects(foreign.getArrayItem(i), obj_copier, false); | 2220 | reserveObjects(foreign.getArrayItem(i), obj_copier, false); |
| 2225 | } | 2221 | } |
| 2226 | - } else if (foreign.isDictionary()) { | 2222 | + } else if (foreign_tc == ::ot_dictionary) { |
| 2227 | QTC::TC("qpdf", "QPDF reserve dictionary"); | 2223 | QTC::TC("qpdf", "QPDF reserve dictionary"); |
| 2228 | for (auto const& key: foreign.getKeys()) { | 2224 | for (auto const& key: foreign.getKeys()) { |
| 2229 | reserveObjects(foreign.getKey(key), obj_copier, false); | 2225 | reserveObjects(foreign.getKey(key), obj_copier, false); |
| 2230 | } | 2226 | } |
| 2231 | - } else if (foreign.isStream()) { | 2227 | + } else if (foreign_tc == ::ot_stream) { |
| 2232 | QTC::TC("qpdf", "QPDF reserve stream"); | 2228 | QTC::TC("qpdf", "QPDF reserve stream"); |
| 2233 | reserveObjects(foreign.getDict(), obj_copier, false); | 2229 | reserveObjects(foreign.getDict(), obj_copier, false); |
| 2234 | } | 2230 | } |
| 2235 | 2231 | ||
| 2236 | - if (foreign.isIndirect()) { | ||
| 2237 | - QPDFObjGen foreign_og(foreign.getObjGen()); | ||
| 2238 | - obj_copier.visiting.erase(foreign_og); | ||
| 2239 | - } | 2232 | + obj_copier.visiting.erase(foreign); |
| 2240 | } | 2233 | } |
| 2241 | 2234 | ||
| 2242 | QPDFObjectHandle | 2235 | QPDFObjectHandle |
| 2243 | QPDF::replaceForeignIndirectObjects( | 2236 | QPDF::replaceForeignIndirectObjects( |
| 2244 | QPDFObjectHandle foreign, ObjCopier& obj_copier, bool top) | 2237 | QPDFObjectHandle foreign, ObjCopier& obj_copier, bool top) |
| 2245 | { | 2238 | { |
| 2239 | + auto foreign_tc = foreign.getTypeCode(); | ||
| 2246 | QPDFObjectHandle result; | 2240 | QPDFObjectHandle result; |
| 2247 | if ((!top) && foreign.isIndirect()) { | 2241 | if ((!top) && foreign.isIndirect()) { |
| 2248 | QTC::TC("qpdf", "QPDF replace indirect"); | 2242 | QTC::TC("qpdf", "QPDF replace indirect"); |
| 2249 | - QPDFObjGen foreign_og(foreign.getObjGen()); | ||
| 2250 | - auto mapping = obj_copier.object_map.find(foreign_og); | 2243 | + auto mapping = obj_copier.object_map.find(foreign.getObjGen()); |
| 2251 | if (mapping == obj_copier.object_map.end()) { | 2244 | if (mapping == obj_copier.object_map.end()) { |
| 2252 | // This case would occur if this is a reference to a Page | 2245 | // This case would occur if this is a reference to a Page |
| 2253 | // or Pages object that we didn't traverse into. | 2246 | // or Pages object that we didn't traverse into. |
| 2254 | QTC::TC("qpdf", "QPDF replace foreign indirect with null"); | 2247 | QTC::TC("qpdf", "QPDF replace foreign indirect with null"); |
| 2255 | result = QPDFObjectHandle::newNull(); | 2248 | result = QPDFObjectHandle::newNull(); |
| 2256 | } else { | 2249 | } else { |
| 2257 | - result = obj_copier.object_map[foreign_og]; | 2250 | + result = mapping->second; |
| 2258 | } | 2251 | } |
| 2259 | - } else if (foreign.isArray()) { | 2252 | + } else if (foreign_tc == ::ot_array) { |
| 2260 | QTC::TC("qpdf", "QPDF replace array"); | 2253 | QTC::TC("qpdf", "QPDF replace array"); |
| 2261 | result = QPDFObjectHandle::newArray(); | 2254 | result = QPDFObjectHandle::newArray(); |
| 2262 | int n = foreign.getArrayNItems(); | 2255 | int n = foreign.getArrayNItems(); |
| @@ -2266,7 +2259,7 @@ QPDF::replaceForeignIndirectObjects( | @@ -2266,7 +2259,7 @@ QPDF::replaceForeignIndirectObjects( | ||
| 2266 | replaceForeignIndirectObjects( | 2259 | replaceForeignIndirectObjects( |
| 2267 | foreign.getArrayItem(i), obj_copier, false)); | 2260 | foreign.getArrayItem(i), obj_copier, false)); |
| 2268 | } | 2261 | } |
| 2269 | - } else if (foreign.isDictionary()) { | 2262 | + } else if (foreign_tc == ::ot_dictionary) { |
| 2270 | QTC::TC("qpdf", "QPDF replace dictionary"); | 2263 | QTC::TC("qpdf", "QPDF replace dictionary"); |
| 2271 | result = QPDFObjectHandle::newDictionary(); | 2264 | result = QPDFObjectHandle::newDictionary(); |
| 2272 | std::set<std::string> keys = foreign.getKeys(); | 2265 | std::set<std::string> keys = foreign.getKeys(); |
| @@ -2276,10 +2269,9 @@ QPDF::replaceForeignIndirectObjects( | @@ -2276,10 +2269,9 @@ QPDF::replaceForeignIndirectObjects( | ||
| 2276 | replaceForeignIndirectObjects( | 2269 | replaceForeignIndirectObjects( |
| 2277 | foreign.getKey(iter), obj_copier, false)); | 2270 | foreign.getKey(iter), obj_copier, false)); |
| 2278 | } | 2271 | } |
| 2279 | - } else if (foreign.isStream()) { | 2272 | + } else if (foreign_tc == ::ot_stream) { |
| 2280 | QTC::TC("qpdf", "QPDF replace stream"); | 2273 | QTC::TC("qpdf", "QPDF replace stream"); |
| 2281 | - QPDFObjGen foreign_og(foreign.getObjGen()); | ||
| 2282 | - result = obj_copier.object_map[foreign_og]; | 2274 | + result = obj_copier.object_map[foreign.getObjGen()]; |
| 2283 | result.assertStream(); | 2275 | result.assertStream(); |
| 2284 | QPDFObjectHandle dict = result.getDict(); | 2276 | QPDFObjectHandle dict = result.getDict(); |
| 2285 | QPDFObjectHandle old_dict = foreign.getDict(); | 2277 | QPDFObjectHandle old_dict = foreign.getDict(); |