summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Sharp <ken.sharp@artifex.com>2022-09-02 15:24:24 +0100
committerChris Liddell <chris.liddell@artifex.com>2022-09-06 08:30:27 +0100
commit31d0f82faef581d0afd694c89076a5b46014b679 (patch)
treed5d0fd7b8e0f8e3b03bbd1dbcffcc499fe490b38
parenta94b6e448324142ecd0e047ba067b5280b6aa2e2 (diff)
downloadghostpdl-31d0f82faef581d0afd694c89076a5b46014b679.tar.gz
GhostPDF - check for circular references when checking Parent resources
OSS-fuzz 50857 The file is corrupted in a way which causes the Parent of a Widget annotation to be an indirect reference to an indirect reference, which points back to the Widget annotation. Add loop detection to the Widget Parent dereferencing/checking to avoid this.
-rw-r--r--pdf/pdf_annot.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/pdf/pdf_annot.c b/pdf/pdf_annot.c
index a7a2c56ea..e24abd8ef 100644
--- a/pdf/pdf_annot.c
+++ b/pdf/pdf_annot.c
@@ -3654,9 +3654,19 @@ static int pdfi_annot_draw_Widget(pdf_context *ctx, pdf_dict *annot, pdf_obj *No
/* TODO: See top part of pdf_draw.ps/drawwidget
* check for /FT and /T and stuff
*/
+ code = pdfi_loop_detector_mark(ctx);
+ if (code < 0)
+ goto exit;
+
currdict = annot;
pdfi_countup(currdict);
while (true) {
+ if (currdict->object_num != 0) {
+ code = pdfi_loop_detector_add_object(ctx, currdict->object_num);
+ if (code < 0)
+ break;
+ }
+
code = pdfi_dict_knownget(ctx, currdict, "T", &T);
if (code < 0) goto exit;
if (code > 0) {
@@ -3682,8 +3692,10 @@ static int pdfi_annot_draw_Widget(pdf_context *ctx, pdf_dict *annot, pdf_obj *No
if (code >= 0 && known == true)
{
code = pdfi_dict_get_no_store_R(ctx, currdict, "Parent", (pdf_obj **)&Parent);
- if (code < 0)
+ if (code < 0) {
+ (void)pdfi_loop_detector_cleartomark(ctx);
goto exit;
+ }
if (pdfi_type_of(Parent) != PDF_DICT) {
if (pdfi_type_of(Parent) == PDF_INDIRECT) {
pdf_indirect_ref *o = (pdf_indirect_ref *)Parent;
@@ -3703,6 +3715,8 @@ static int pdfi_annot_draw_Widget(pdf_context *ctx, pdf_dict *annot, pdf_obj *No
break;
}
+ (void)pdfi_loop_detector_cleartomark(ctx);
+
code = 0;
if (!found_T || !found_FT) {
*render_done = true;