diff options
author | Ken Sharp <ken.sharp@artifex.com> | 2022-01-19 15:32:11 +0000 |
---|---|---|
committer | Ken Sharp <ken.sharp@artifex.com> | 2022-01-19 15:32:44 +0000 |
commit | f3e9e548102b872fb4d93996373152d36104ef82 (patch) | |
tree | 96b97004f7277011e5eb96fb0d52468ce81a46fc /pdf/pdf_deref.c | |
parent | b78e943348f52f1dd72c0d3ea1b1a04123f98f18 (diff) | |
download | ghostpdl-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.c | 32 |
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; } |