diff options
author | Ken Sharp <ken.sharp@artifex.com> | 2022-09-08 11:32:31 +0100 |
---|---|---|
committer | Chris Liddell <chris.liddell@artifex.com> | 2022-09-08 14:11:06 +0100 |
commit | 61f7c698fd479258d7391ce2fd50fb8547de2e7c (patch) | |
tree | c748a73d8cf01b65254d591dc85f220c6963fcbc | |
parent | c315444579f3b54a890569d3ac3c5e938e227843 (diff) | |
download | ghostpdl-61f7c698fd479258d7391ce2fd50fb8547de2e7c.tar.gz |
GhostPDF - type check Image dictionary contents
Bug #705784 "NULL pointer dereference in pdf/pdf_image.c:883 pdfi_data_image_params"
The function picking out the required image information wasn't type
checking some elements, which was comparatively safe (but still wrong)
before the change to handling some objects as low integer values rather
than pointers to objects. That change causes us to try and dereference
pointers to low memory and causes a crash.
We should type check all the image dictionary contents before use, this
commit just adds that. If we find an optional entry that isn't a valid
type we raise a warning but continue unless PDFSTOPONWARNING is set.
We ignore the invalid value which may still cause further errors or
incorrect rendering though.
-rw-r--r-- | pdf/pdf_image.c | 54 |
1 files changed, 53 insertions, 1 deletions
diff --git a/pdf/pdf_image.c b/pdf/pdf_image.c index 441b9ed07..43b70f567 100644 --- a/pdf/pdf_image.c +++ b/pdf/pdf_image.c @@ -545,11 +545,18 @@ pdfi_get_image_info(pdf_context *ctx, pdf_stream *image_obj, * GS implementation does. */ if (code != gs_error_undefined) { - pdfi_set_warning(ctx, 0, NULL, W_PDF_BAD_IMAGEDICT, "pdfi_get_image_info", NULL); + pdfi_set_warning(ctx, 0, NULL, W_PDF_BAD_IMAGEDICT, "pdfi_get_image_info", NULL); if (ctx->args.pdfstoponwarning) goto errorExit; } } + if (info->Mask != NULL && (pdfi_type_of(info->Mask) != PDF_ARRAY && pdfi_type_of(info->Mask) != PDF_STREAM)) { + pdfi_countdown(info->Mask); + info->Mask = NULL; + pdfi_set_warning(ctx, 0, NULL, W_PDF_BAD_IMAGEDICT, "pdfi_get_image_info", NULL); + if (ctx->args.pdfstoponwarning) + goto errorExit; + } /* Optional (apparently there is no abbreviation for "SMask"? */ code = pdfi_dict_get(ctx, image_dict, "SMask", &info->SMask); @@ -575,6 +582,9 @@ pdfi_get_image_info(pdf_context *ctx, pdf_stream *image_obj, if (pdfi_type_of(info->SMask) != PDF_STREAM){ pdfi_countdown(info->SMask); info->SMask = NULL; + pdfi_set_warning(ctx, 0, NULL, W_PDF_BAD_IMAGEDICT, "pdfi_get_image_info", NULL); + if (ctx->args.pdfstoponwarning) + goto errorExit; } } @@ -596,6 +606,13 @@ pdfi_get_image_info(pdf_context *ctx, pdf_stream *image_obj, if (code != gs_error_undefined) goto errorExit; } + if (info->ColorSpace != NULL && (pdfi_type_of(info->ColorSpace) != PDF_NAME && pdfi_type_of(info->ColorSpace) != PDF_ARRAY)) { + pdfi_countdown(info->ColorSpace); + info->ColorSpace = NULL; + pdfi_set_warning(ctx, 0, NULL, W_PDF_BAD_IMAGEDICT, "pdfi_get_image_info", NULL); + if (ctx->args.pdfstoponwarning) + goto errorExit; + } /* Optional (default is to use from graphics state) */ /* (no abbreviation for inline) */ @@ -611,6 +628,13 @@ pdfi_get_image_info(pdf_context *ctx, pdf_stream *image_obj, if (code != gs_error_undefined) goto errorExit; } + if (info->Alternates != NULL && pdfi_type_of(info->Alternates) != PDF_ARRAY) { + pdfi_countdown(info->Alternates); + info->Alternates = NULL; + pdfi_set_warning(ctx, 0, NULL, W_PDF_BAD_IMAGEDICT, "pdfi_get_image_info", NULL); + if (ctx->args.pdfstoponwarning) + goto errorExit; + } /* Optional (required in PDF1.0, obsolete, do we support?) */ code = pdfi_dict_get(ctx, image_dict, "Name", &info->Name); @@ -618,6 +642,13 @@ pdfi_get_image_info(pdf_context *ctx, pdf_stream *image_obj, if (code != gs_error_undefined) goto errorExit; } + if (info->Name != NULL && pdfi_type_of(info->Name) != PDF_NAME) { + pdfi_countdown(info->Name); + info->Name = NULL; + pdfi_set_warning(ctx, 0, NULL, W_PDF_BAD_IMAGEDICT, "pdfi_get_image_info", NULL); + if (ctx->args.pdfstoponwarning) + goto errorExit; + } /* Required "if image is structural content item" */ /* TODO: Figure out what to do here */ @@ -633,6 +664,13 @@ pdfi_get_image_info(pdf_context *ctx, pdf_stream *image_obj, if (code != gs_error_undefined) goto errorExit; } + if (info->Decode != NULL && pdfi_type_of(info->Decode) != PDF_ARRAY) { + pdfi_countdown(info->Decode); + info->Decode = NULL; + pdfi_set_warning(ctx, 0, NULL, W_PDF_BAD_IMAGEDICT, "pdfi_get_image_info", NULL); + if (ctx->args.pdfstoponwarning) + goto errorExit; + } /* Optional "Optional Content" */ code = pdfi_dict_get_type(ctx, image_dict, "OC", PDF_DICT, (pdf_obj **)&info->OC); @@ -647,6 +685,13 @@ pdfi_get_image_info(pdf_context *ctx, pdf_stream *image_obj, if (code != gs_error_undefined) goto errorExit; } + if (info->Filter != NULL && (pdfi_type_of(info->Filter) != PDF_NAME && pdfi_type_of(info->Filter) != PDF_ARRAY)) { + pdfi_countdown(info->Filter); + info->Filter = NULL; + pdfi_set_warning(ctx, 0, NULL, W_PDF_BAD_IMAGEDICT, "pdfi_get_image_info", NULL); + if (ctx->args.pdfstoponwarning) + goto errorExit; + } /* Check and set JPXDecode flag for later */ info->is_JPXDecode = false; @@ -661,6 +706,13 @@ pdfi_get_image_info(pdf_context *ctx, pdf_stream *image_obj, if (code != gs_error_undefined) goto errorExit; } + if (info->DecodeParms != NULL && (pdfi_type_of(info->DecodeParms) != PDF_DICT && pdfi_type_of(info->DecodeParms) != PDF_ARRAY)) { + pdfi_countdown(info->DecodeParms); + info->DecodeParms = NULL; + pdfi_set_warning(ctx, 0, NULL, W_PDF_BAD_IMAGEDICT, "pdfi_get_image_info", NULL); + if (ctx->args.pdfstoponwarning) + goto errorExit; + } return 0; |