aboutsummaryrefslogtreecommitdiffstats
path: root/libqpdf/QPDF.cc
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2024-01-07 21:21:38 +0100
committerJay Berkenbilt <ejb@ql.org>2024-01-07 21:22:04 +0100
commitdf61f3a6c62487ee4e4208cca473b763a2140cee (patch)
tree22f0aebb5b3851c356df4087d645d571bc83fad1 /libqpdf/QPDF.cc
parentba477e0b335ea430451711e125843f7624803ae5 (diff)
downloadqpdf-df61f3a6c62487ee4e4208cca473b763a2140cee.tar.zst
Improve getCompressibleObjGens fix to handle gen > 0
Diffstat (limited to 'libqpdf/QPDF.cc')
-rw-r--r--libqpdf/QPDF.cc12
1 files changed, 9 insertions, 3 deletions
diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc
index 4ed5d852..3718eb7e 100644
--- a/libqpdf/QPDF.cc
+++ b/libqpdf/QPDF.cc
@@ -2378,6 +2378,7 @@ QPDF::getCompressibleObjGens()
const size_t max_obj = getObjectCount();
std::vector<bool> visited(max_obj, false);
+ QPDFObjGen::set visited_gen; // for objects with generation > 0
std::vector<QPDFObjectHandle> queue;
queue.reserve(512);
queue.push_back(m->trailer);
@@ -2388,14 +2389,19 @@ QPDF::getCompressibleObjGens()
if (obj.isIndirect()) {
QPDFObjGen og = obj.getObjGen();
const size_t id = toS(og.getObj() - 1);
+ const int gen = og.getGen();
if (id >= max_obj)
- throw std::runtime_error(
+ throw std::logic_error(
"unexpected object id encountered in getCompressibleObjGens");
- if (visited[id]) {
+ if ((gen == 0 && visited[id]) || visited_gen.count(og)) {
QTC::TC("qpdf", "QPDF loop detected traversing objects");
continue;
}
- visited[id] = true;
+ if (gen == 0) {
+ visited[id] = true;
+ } else {
+ visited_gen.insert(og);
+ }
if (og == encryption_dict_og) {
QTC::TC("qpdf", "QPDF exclude encryption dictionary");
} else if (!(obj.isStream() ||