poppler/PageLabelInfo.cc | 26 +++++++++++++++++++------- poppler/PageLabelInfo.h | 4 ++-- 2 files changed, 21 insertions(+), 9 deletions(-)
New commits: commit 2386bf37f9022cb5a9d434e30e8d8d55f4916e55 Author: Albert Astals Cid <[email protected]> Date: Sat Nov 28 01:31:05 2020 +0100 Protect against loops in the PageLabels Kids tree oss-fuzz/27991 diff --git a/poppler/PageLabelInfo.cc b/poppler/PageLabelInfo.cc index bfcaadc9..dde5f332 100644 --- a/poppler/PageLabelInfo.cc +++ b/poppler/PageLabelInfo.cc @@ -3,7 +3,7 @@ // This file is under the GPLv2 or later license // // Copyright (C) 2005-2006 Kristian Høgsberg <[email protected]> -// Copyright (C) 2005, 2009, 2013, 2017, 2018 Albert Astals Cid <[email protected]> +// Copyright (C) 2005, 2009, 2013, 2017, 2018, 2020 Albert Astals Cid <[email protected]> // Copyright (C) 2011 Simon Kellner <[email protected]> // Copyright (C) 2012 Fabio D'Urso <[email protected]> // Copyright (C) 2018 Adam Reichold <[email protected]> @@ -59,7 +59,8 @@ PageLabelInfo::Interval::Interval(Object *dict, int baseA) PageLabelInfo::PageLabelInfo(Object *tree, int numPages) { - parse(tree); + std::set<int> alreadyParsedRefs; + parse(tree, alreadyParsedRefs); if (intervals.empty()) return; @@ -71,7 +72,7 @@ PageLabelInfo::PageLabelInfo(Object *tree, int numPages) curr->length = std::max(0, numPages - curr->base); } -void PageLabelInfo::parse(Object *tree) +void PageLabelInfo::parse(const Object *tree, std::set<int> &alreadyParsedRefs) { // leaf node Object nums = tree->dictLookup("Nums"); @@ -93,10 +94,21 @@ void PageLabelInfo::parse(Object *tree) Object kids = tree->dictLookup("Kids"); if (kids.isArray()) { - for (int i = 0; i < kids.arrayGetLength(); ++i) { - Object kid = kids.arrayGet(i); - if (kid.isDict()) - parse(&kid); + const Array *kidsArray = kids.getArray(); + for (int i = 0; i < kidsArray->getLength(); ++i) { + Ref ref; + const Object kid = kidsArray->get(i, &ref); + if (ref != Ref::INVALID()) { + const int numObj = ref.num; + if (alreadyParsedRefs.find(numObj) != alreadyParsedRefs.end()) { + error(errSyntaxError, -1, "loop in PageLabelInfo (numObj: {0:d})", numObj); + continue; + } + alreadyParsedRefs.insert(numObj); + } + if (kid.isDict()) { + parse(&kid, alreadyParsedRefs); + } } } } diff --git a/poppler/PageLabelInfo.h b/poppler/PageLabelInfo.h index f5441784..bec70d32 100644 --- a/poppler/PageLabelInfo.h +++ b/poppler/PageLabelInfo.h @@ -3,7 +3,7 @@ // This file is under the GPLv2 or later license // // Copyright (C) 2005-2006 Kristian Høgsberg <[email protected]> -// Copyright (C) 2005, 2018, 2019 Albert Astals Cid <[email protected]> +// Copyright (C) 2005, 2018-2020 Albert Astals Cid <[email protected]> // Copyright (C) 2018 Adam Reichold <[email protected]> // Copyright (C) 2019 Oliver Sander <[email protected]> // @@ -37,7 +37,7 @@ public: bool indexToLabel(int index, GooString *label) const; private: - void parse(Object *tree); + void parse(const Object *tree, std::set<int> &parsedRefs); private: struct Interval _______________________________________________ poppler mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/poppler
