summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Sharp <ken.sharp@artifex.com>2022-09-08 11:32:31 +0100
committerChris Liddell <chris.liddell@artifex.com>2022-09-08 14:11:06 +0100
commit61f7c698fd479258d7391ce2fd50fb8547de2e7c (patch)
treec748a73d8cf01b65254d591dc85f220c6963fcbc
parentc315444579f3b54a890569d3ac3c5e938e227843 (diff)
downloadghostpdl-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.c54
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;