diff options
author | Ken Sharp <ken.sharp@artifex.com> | 2022-09-02 15:24:24 +0100 |
---|---|---|
committer | Chris Liddell <chris.liddell@artifex.com> | 2022-09-06 08:30:27 +0100 |
commit | 31d0f82faef581d0afd694c89076a5b46014b679 (patch) | |
tree | d5d0fd7b8e0f8e3b03bbd1dbcffcc499fe490b38 | |
parent | a94b6e448324142ecd0e047ba067b5280b6aa2e2 (diff) | |
download | ghostpdl-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.c | 16 |
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; |