Commit df61f3a6c62487ee4e4208cca473b763a2140cee
1 parent
ba477e0b
Improve getCompressibleObjGens fix to handle gen > 0
Showing
1 changed file
with
9 additions
and
3 deletions
libqpdf/QPDF.cc
| ... | ... | @@ -2378,6 +2378,7 @@ QPDF::getCompressibleObjGens() |
| 2378 | 2378 | |
| 2379 | 2379 | const size_t max_obj = getObjectCount(); |
| 2380 | 2380 | std::vector<bool> visited(max_obj, false); |
| 2381 | + QPDFObjGen::set visited_gen; // for objects with generation > 0 | |
| 2381 | 2382 | std::vector<QPDFObjectHandle> queue; |
| 2382 | 2383 | queue.reserve(512); |
| 2383 | 2384 | queue.push_back(m->trailer); |
| ... | ... | @@ -2388,14 +2389,19 @@ QPDF::getCompressibleObjGens() |
| 2388 | 2389 | if (obj.isIndirect()) { |
| 2389 | 2390 | QPDFObjGen og = obj.getObjGen(); |
| 2390 | 2391 | const size_t id = toS(og.getObj() - 1); |
| 2392 | + const int gen = og.getGen(); | |
| 2391 | 2393 | if (id >= max_obj) |
| 2392 | - throw std::runtime_error( | |
| 2394 | + throw std::logic_error( | |
| 2393 | 2395 | "unexpected object id encountered in getCompressibleObjGens"); |
| 2394 | - if (visited[id]) { | |
| 2396 | + if ((gen == 0 && visited[id]) || visited_gen.count(og)) { | |
| 2395 | 2397 | QTC::TC("qpdf", "QPDF loop detected traversing objects"); |
| 2396 | 2398 | continue; |
| 2397 | 2399 | } |
| 2398 | - visited[id] = true; | |
| 2400 | + if (gen == 0) { | |
| 2401 | + visited[id] = true; | |
| 2402 | + } else { | |
| 2403 | + visited_gen.insert(og); | |
| 2404 | + } | |
| 2399 | 2405 | if (og == encryption_dict_og) { |
| 2400 | 2406 | QTC::TC("qpdf", "QPDF exclude encryption dictionary"); |
| 2401 | 2407 | } else if (!(obj.isStream() || | ... | ... |