Commit e28625144d8eb77b98d3e64107aa0f353863def4
Committed by
Jay Berkenbilt
1 parent
adb866ef
Tweak QPDF::getCompressibleObjGens
Showing
1 changed file
with
12 additions
and
7 deletions
libqpdf/QPDF.cc
| @@ -2398,7 +2398,6 @@ QPDF::getCompressibleObjGens() | @@ -2398,7 +2398,6 @@ QPDF::getCompressibleObjGens() | ||
| 2398 | 2398 | ||
| 2399 | const size_t max_obj = getObjectCount(); | 2399 | const size_t max_obj = getObjectCount(); |
| 2400 | std::vector<bool> visited(max_obj, false); | 2400 | std::vector<bool> visited(max_obj, false); |
| 2401 | - QPDFObjGen::set visited_gen; // for objects with generation > 0 | ||
| 2402 | std::vector<QPDFObjectHandle> queue; | 2401 | std::vector<QPDFObjectHandle> queue; |
| 2403 | queue.reserve(512); | 2402 | queue.reserve(512); |
| 2404 | queue.push_back(m->trailer); | 2403 | queue.push_back(m->trailer); |
| @@ -2409,19 +2408,25 @@ QPDF::getCompressibleObjGens() | @@ -2409,19 +2408,25 @@ QPDF::getCompressibleObjGens() | ||
| 2409 | if (obj.isIndirect()) { | 2408 | if (obj.isIndirect()) { |
| 2410 | QPDFObjGen og = obj.getObjGen(); | 2409 | QPDFObjGen og = obj.getObjGen(); |
| 2411 | const size_t id = toS(og.getObj() - 1); | 2410 | const size_t id = toS(og.getObj() - 1); |
| 2412 | - const int gen = og.getGen(); | ||
| 2413 | if (id >= max_obj) | 2411 | if (id >= max_obj) |
| 2414 | throw std::logic_error( | 2412 | throw std::logic_error( |
| 2415 | "unexpected object id encountered in getCompressibleObjGens"); | 2413 | "unexpected object id encountered in getCompressibleObjGens"); |
| 2416 | - if ((gen == 0 && visited[id]) || visited_gen.count(og)) { | 2414 | + if (visited[id]) { |
| 2417 | QTC::TC("qpdf", "QPDF loop detected traversing objects"); | 2415 | QTC::TC("qpdf", "QPDF loop detected traversing objects"); |
| 2418 | continue; | 2416 | continue; |
| 2419 | } | 2417 | } |
| 2420 | - if (gen == 0) { | ||
| 2421 | - visited[id] = true; | ||
| 2422 | - } else { | ||
| 2423 | - visited_gen.insert(og); | 2418 | + |
| 2419 | + // Check whether this is the current object. If not, remove it (which changes it into a | ||
| 2420 | + // direct null and therefore stops us from revisiting it) and move on to the next object | ||
| 2421 | + // in the queue. | ||
| 2422 | + auto upper = m->obj_cache.upper_bound(og); | ||
| 2423 | + if (upper != m->obj_cache.end() && upper->first.getObj() == og.getObj()) { | ||
| 2424 | + removeObject(og); | ||
| 2425 | + continue; | ||
| 2424 | } | 2426 | } |
| 2427 | + | ||
| 2428 | + visited[id] = true; | ||
| 2429 | + | ||
| 2425 | if (og == encryption_dict_og) { | 2430 | if (og == encryption_dict_og) { |
| 2426 | QTC::TC("qpdf", "QPDF exclude encryption dictionary"); | 2431 | QTC::TC("qpdf", "QPDF exclude encryption dictionary"); |
| 2427 | } else if (!(obj.isStream() || | 2432 | } else if (!(obj.isStream() || |