summaryrefslogtreecommitdiff
path: root/pdf/pdf_deref.c
diff options
context:
space:
mode:
authorKen Sharp <ken.sharp@artifex.com>2022-01-19 15:32:11 +0000
committerKen Sharp <ken.sharp@artifex.com>2022-01-19 15:32:44 +0000
commitf3e9e548102b872fb4d93996373152d36104ef82 (patch)
tree96b97004f7277011e5eb96fb0d52468ce81a46fc /pdf/pdf_deref.c
parentb78e943348f52f1dd72c0d3ea1b1a04123f98f18 (diff)
downloadghostpdl-f3e9e548102b872fb4d93996373152d36104ef82.tar.gz
OSS-fuzz #43781 - improve loop detection in pdfi_resolve_indirect
Add more and better detection of circular references when trying to recursively turn indirect references into direct objects for the 'mark' (pdfmark in PostScript) code. This has been a steady work in progress, there may be more cases yet.
Diffstat (limited to 'pdf/pdf_deref.c')
-rw-r--r--pdf/pdf_deref.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/pdf/pdf_deref.c b/pdf/pdf_deref.c
index 5781c0b69..34312aed0 100644
--- a/pdf/pdf_deref.c
+++ b/pdf/pdf_deref.c
@@ -1015,7 +1015,20 @@ static int pdfi_resolve_indirect_array(pdf_context *ctx, pdf_obj *obj, bool recu
arraysize = pdfi_array_size(array);
for (index = 0; index < arraysize; index++) {
+ if (ctx->loop_detection != NULL) {
+ code = pdfi_loop_detector_mark(ctx);
+ if (code < 0)
+ return code;
+ }
+
code = pdfi_array_get_no_store_R(ctx, array, index, &object);
+
+ if (ctx->loop_detection != NULL) {
+ int code1 = pdfi_loop_detector_cleartomark(ctx);
+ if (code1 < 0)
+ return code1;
+ }
+
if (code == gs_error_circular_reference) {
/* Just leave as an indirect ref */
code = 0;
@@ -1055,7 +1068,21 @@ static int pdfi_resolve_indirect_dict(pdf_context *ctx, pdf_obj *obj, bool recur
Key = (pdf_name *)dict->keys[index];
if (pdfi_name_is(Key, "Parent"))
continue;
+
+ if (ctx->loop_detection != NULL) {
+ code = pdfi_loop_detector_mark(ctx);
+ if (code < 0)
+ return code;
+ }
+
code = pdfi_dict_get_no_store_R_key(ctx, dict, Key, &Value);
+
+ if (ctx->loop_detection != NULL) {
+ int code1 = pdfi_loop_detector_cleartomark(ctx);
+ if (code1 < 0)
+ return code1;
+ }
+
if (code == gs_error_circular_reference) {
/* Just leave as an indirect ref */
code = 0;
@@ -1112,7 +1139,12 @@ int pdfi_resolve_indirect_loop_detect(pdf_context *ctx, pdf_obj *parent, pdf_obj
code = pdfi_loop_detector_add_object(ctx, parent->object_num);
if (code < 0) goto exit;
}
+
if (value->object_num != 0) {
+ if (pdfi_loop_detector_check_object(ctx, value->object_num)) {
+ code = gs_note_error(gs_error_circular_reference);
+ goto exit;
+ }
code = pdfi_loop_detector_add_object(ctx, value->object_num);
if (code < 0) goto exit;
}