Commit e28625144d8eb77b98d3e64107aa0f353863def4

Authored by m-holger
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() ||