2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-05-30 00:40:52 +00:00

Fix loop detection error (fuzz issue 23172)

This commit is contained in:
Jay Berkenbilt 2020-10-22 05:11:58 -04:00
parent 6cc9489fd8
commit 24196c08cb
5 changed files with 17 additions and 9 deletions

View File

@ -1,3 +1,8 @@
2020-10-22 Jay Berkenbilt <ejb@ql.org>
* Fix loop detection problem when traversing page thumbnails
during optimization (fuzz issue 23172).
2020-10-21 Jay Berkenbilt <ejb@ql.org> 2020-10-21 Jay Berkenbilt <ejb@ql.org>
* Bug fix: properly handle copying foreign streams that have * Bug fix: properly handle copying foreign streams that have

1
TODO
View File

@ -65,7 +65,6 @@ Fuzz Errors
* https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=<N> * https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=<N>
* New: * New:
* 23172: stack overflow (https://oss-fuzz.com/testcase-detail/5719543787028480)
* 23599: integer overflow: https://oss-fuzz.com/testcase?key=6290807920525312 * 23599: integer overflow: https://oss-fuzz.com/testcase?key=6290807920525312
* 23642: leak: https://oss-fuzz.com/testcase-detail/4906569690251264 * 23642: leak: https://oss-fuzz.com/testcase-detail/4906569690251264

BIN
fuzz/qpdf_extra/23172.fuzz Normal file

Binary file not shown.

View File

@ -1341,7 +1341,8 @@ class QPDF
std::set<QPDFObjGen>& visited); std::set<QPDFObjGen>& visited);
void updateObjectMaps(ObjUser const& ou, QPDFObjectHandle oh); void updateObjectMaps(ObjUser const& ou, QPDFObjectHandle oh);
void updateObjectMapsInternal(ObjUser const& ou, QPDFObjectHandle oh, void updateObjectMapsInternal(ObjUser const& ou, QPDFObjectHandle oh,
std::set<QPDFObjGen>& visited, bool top); std::set<QPDFObjGen>& visited, bool top,
int depth);
void filterCompressedObjects(std::map<int, int> const& object_stream_data); void filterCompressedObjects(std::map<int, int> const& object_stream_data);
// Type conversion helper methods // Type conversion helper methods

View File

@ -354,12 +354,13 @@ void
QPDF::updateObjectMaps(ObjUser const& ou, QPDFObjectHandle oh) QPDF::updateObjectMaps(ObjUser const& ou, QPDFObjectHandle oh)
{ {
std::set<QPDFObjGen> visited; std::set<QPDFObjGen> visited;
updateObjectMapsInternal(ou, oh, visited, true); updateObjectMapsInternal(ou, oh, visited, true, 0);
} }
void void
QPDF::updateObjectMapsInternal(ObjUser const& ou, QPDFObjectHandle oh, QPDF::updateObjectMapsInternal(ObjUser const& ou, QPDFObjectHandle oh,
std::set<QPDFObjGen>& visited, bool top) std::set<QPDFObjGen>& visited, bool top,
int depth)
{ {
// Traverse the object tree from this point taking care to avoid // Traverse the object tree from this point taking care to avoid
// crossing page boundaries. // crossing page boundaries.
@ -397,7 +398,8 @@ QPDF::updateObjectMapsInternal(ObjUser const& ou, QPDFObjectHandle oh,
int n = oh.getArrayNItems(); int n = oh.getArrayNItems();
for (int i = 0; i < n; ++i) for (int i = 0; i < n; ++i)
{ {
updateObjectMapsInternal(ou, oh.getArrayItem(i), visited, false); updateObjectMapsInternal(
ou, oh.getArrayItem(i), visited, false, 1 + depth);
} }
} }
else if (oh.isDictionary() || oh.isStream()) else if (oh.isDictionary() || oh.isStream())
@ -417,8 +419,9 @@ QPDF::updateObjectMapsInternal(ObjUser const& ou, QPDFObjectHandle oh,
{ {
// Traverse page thumbnail dictionaries as a special // Traverse page thumbnail dictionaries as a special
// case. // case.
updateObjectMaps(ObjUser(ObjUser::ou_thumb, ou.pageno), updateObjectMapsInternal(
dict.getKey(key)); ObjUser(ObjUser::ou_thumb, ou.pageno),
dict.getKey(key), visited, false, 1 + depth);
} }
else if (is_page_node && (key == "/Parent")) else if (is_page_node && (key == "/Parent"))
{ {
@ -426,8 +429,8 @@ QPDF::updateObjectMapsInternal(ObjUser const& ou, QPDFObjectHandle oh,
} }
else else
{ {
updateObjectMapsInternal(ou, dict.getKey(key), updateObjectMapsInternal(
visited, false); ou, dict.getKey(key), visited, false, 1 + depth);
} }
} }
} }