diff options
author | Ken Sharp <ken.sharp@artifex.com> | 2022-02-01 09:55:09 +0000 |
---|---|---|
committer | Ken Sharp <ken.sharp@artifex.com> | 2022-02-01 09:55:25 +0000 |
commit | 092b4890aa824a020daa4171c51781fdbff6e1bd (patch) | |
tree | 07227fc4eca1021b85ddbbb93b7ebc160d99df84 /pdf/pdf_obj.c | |
parent | 3c75a977879b066c20f6c9587481ac93e476630b (diff) | |
download | ghostpdl-092b4890aa824a020daa4171c51781fdbff6e1bd.tar.gz |
OSS-fuzz #44232 - sort loop detection in pdfmark generation
The pdfmark generation code ignores circular references in dereferenced
objects, which I'm not certain is going to be viable in the long term,
but I've chosen to leave alone just now.
However, it was not checking for loops when writing dictionary contents
which could, with a sufficiently broken annotation, cause us to enter
an endless loop trying to write a dictionary with looping references.
This addresses the problem, but I suspect more work needs to be done
here.
Diffstat (limited to 'pdf/pdf_obj.c')
-rw-r--r-- | pdf/pdf_obj.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/pdf/pdf_obj.c b/pdf/pdf_obj.c index e64fc7745..680eedae5 100644 --- a/pdf/pdf_obj.c +++ b/pdf/pdf_obj.c @@ -23,6 +23,7 @@ #include "pdf_deref.h" /* for replace_cache_entry() */ #include "pdf_mark.h" #include "pdf_file.h" /* for pdfi_stream_to_buffer() */ +#include "pdf_loop_detect.h" /***********************************************************************************/ /* Functions to create the various kinds of 'PDF objects', Created objects have a */ @@ -575,7 +576,7 @@ static int pdfi_obj_indirect_str(pdf_context *ctx, pdf_obj *obj, byte **data, in ref->is_highlevelform = false; } else { if (!ref->is_marking) { - code = pdfi_dereference(ctx, ref->ref_object_num, ref->ref_generation_num, &object); + code = pdfi_deref_loop_detect(ctx, ref->ref_object_num, ref->ref_generation_num, &object); if (code == gs_error_undefined) { /* Do something sensible for undefined reference (this would be a broken file) */ /* TODO: Flag an error? */ @@ -853,6 +854,15 @@ static int pdfi_obj_dict_str(pdf_context *ctx, pdf_obj *obj, byte **data, int *l /* Note: We specifically fetch without dereferencing, so there will be no circular * references to handle here. */ + /* Wrong.... */ + + code = pdfi_loop_detector_mark(ctx); + if (dict->object_num !=0 ) { + if (pdfi_loop_detector_check_object(ctx, dict->object_num)) + return_error(gs_error_circular_reference); + code = pdfi_loop_detector_add_object(ctx, dict->object_num); + } + /* Get each (key,val) pair from dict and setup param for it */ code = pdfi_dict_key_first(ctx, dict, (pdf_obj **)&Key, &index); while (code >= 0) { @@ -916,6 +926,10 @@ static int pdfi_obj_dict_str(pdf_context *ctx, pdf_obj *obj, byte **data, int *l pdfi_countdown(Key); pdfi_countdown(Value); pdfi_bufstream_free(ctx, &bufstream); + if (code < 0) + (void)pdfi_loop_detector_cleartomark(ctx); + else + code = pdfi_loop_detector_cleartomark(ctx); return code; } |