summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'pdf/pdf_image.c')
-rw-r--r--pdf/pdf_image.c165
1 files changed, 122 insertions, 43 deletions
diff --git a/pdf/pdf_image.c b/pdf/pdf_image.c
index 554cc344..43b70f56 100644
--- a/pdf/pdf_image.c
+++ b/pdf/pdf_image.c
@@ -173,7 +173,7 @@ pdfi_find_alternate(pdf_context *ctx, pdf_obj *alt)
int code;
bool flag;
- if (alt->type != PDF_ARRAY)
+ if (pdfi_type_of(alt) != PDF_ARRAY)
return NULL;
array = (pdf_array *)alt;
@@ -528,6 +528,10 @@ pdfi_get_image_info(pdf_context *ctx, pdf_stream *image_obj,
}
info->BPC = 1;
}
+ else if (info->BPC != 1 && info->BPC != 2 && info->BPC != 4 && info->BPC != 8 && info->BPC != 16) {
+ code = gs_note_error(gs_error_rangecheck);
+ goto errorExit;
+ }
/* TODO: spec says if ImageMask is specified, and BPC is specified, then BPC must be 1
Should we flag an error if this is violated?
*/
@@ -541,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);
@@ -558,7 +569,7 @@ pdfi_get_image_info(pdf_context *ctx, pdf_stream *image_obj,
code = 0;
}
} else {
- if (info->SMask->type == PDF_NAME) {
+ if (pdfi_type_of(info->SMask) == PDF_NAME) {
pdf_obj *o = NULL;
code = pdfi_find_resource(ctx, (unsigned char *)"ExtGState", (pdf_name *)info->SMask, image_dict, page_dict, &o);
@@ -568,9 +579,12 @@ pdfi_get_image_info(pdf_context *ctx, pdf_stream *image_obj,
}
}
- if (info->SMask->type != PDF_STREAM){
+ 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;
}
}
@@ -592,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) */
@@ -607,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);
@@ -614,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 */
@@ -629,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);
@@ -643,10 +685,17 @@ 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;
- if (info->Filter && info->Filter->type == PDF_NAME) {
+ if (info->Filter && pdfi_type_of(info->Filter) == PDF_NAME) {
if (pdfi_name_is((pdf_name *)info->Filter, "JPXDecode"))
info->is_JPXDecode = true;
}
@@ -657,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;
@@ -987,6 +1043,9 @@ pdfi_do_image_smask(pdf_context *ctx, pdf_c_stream *source, pdfi_image_info_t *i
if (code < 0)
return code;
+ if (pdfi_type_of(image_info->SMask) != PDF_STREAM)
+ return_error(gs_error_typecheck);
+
if (image_info->SMask->object_num != 0) {
if (pdfi_loop_detector_check_object(ctx, image_info->SMask->object_num))
return gs_note_error(gs_error_circular_reference);
@@ -1018,22 +1077,23 @@ pdfi_do_image_smask(pdf_context *ctx, pdf_c_stream *source, pdfi_image_info_t *i
pdfi_seek(ctx, ctx->main_stream,
pdfi_stream_offset(ctx, (pdf_stream *)image_info->SMask), SEEK_SET);
- if (image_info->SMask->type == PDF_DICT) {
- code = pdfi_obj_dict_to_stream(ctx, (pdf_dict *)image_info->SMask, &stream_obj, false);
- if (code == 0) {
- code = pdfi_do_image_or_form(ctx, image_info->stream_dict,
- image_info->page_dict, (pdf_obj *)stream_obj);
+ switch (pdfi_type_of(image_info->SMask)) {
+ case PDF_DICT:
+ code = pdfi_obj_dict_to_stream(ctx, (pdf_dict *)image_info->SMask, &stream_obj, false);
+ if (code == 0) {
+ code = pdfi_do_image_or_form(ctx, image_info->stream_dict,
+ image_info->page_dict, (pdf_obj *)stream_obj);
- pdfi_countdown(stream_obj);
- }
- } else {
- if (image_info->SMask->type == PDF_STREAM)
+ pdfi_countdown(stream_obj);
+ }
+ break;
+ case PDF_STREAM:
code = pdfi_do_image_or_form(ctx, image_info->stream_dict,
image_info->page_dict, image_info->SMask);
- else {
+ break;
+ default:
code = gs_note_error(gs_error_typecheck);
goto exit;
- }
}
pdfi_seek(ctx, ctx->main_stream, savedoffset, SEEK_SET);
@@ -1434,7 +1494,7 @@ pdfi_image_get_color(pdf_context *ctx, pdf_c_stream *source, pdfi_image_info_t *
pcs, image_info->inline_image);
if (code < 0) {
dmprintf(ctx->memory, "WARNING: Image has unsupported ColorSpace ");
- if (ColorSpace->type == PDF_NAME) {
+ if (pdfi_type_of(ColorSpace) == PDF_NAME) {
pdf_name *name = (pdf_name *)ColorSpace;
char str[100];
int length = name->length;
@@ -1496,7 +1556,7 @@ pdfi_make_smask_dict(pdf_context *ctx, pdf_stream *image_stream, pdfi_image_info
goto exit;
}
- if (image_stream->type != PDF_STREAM) {
+ if (pdfi_type_of(image_stream) != PDF_STREAM) {
code = gs_note_error(gs_error_typecheck);
goto exit;
}
@@ -1623,7 +1683,7 @@ pdfi_do_image(pdf_context *ctx, pdf_dict *page_dict, pdf_dict *stream_dict, pdf_
memset(&smask_info, 0, sizeof(mask_info));
/* Make sure the image is a stream (which we will assume in later code) */
- if (image_stream->type != PDF_STREAM)
+ if (pdfi_type_of(image_stream) != PDF_STREAM)
return_error(gs_error_typecheck);
if (!inline_image) {
@@ -1867,23 +1927,26 @@ pdfi_do_image(pdf_context *ctx, pdf_dict *page_dict, pdf_dict *stream_dict, pdf_
/* Get the Mask data either as an array or a dict, if present */
if (image_info.Mask != NULL) {
- if (image_info.Mask->type == PDF_ARRAY) {
- mask_array = (pdf_array *)image_info.Mask;
- } else if (image_info.Mask->type == PDF_STREAM) {
- mask_stream = (pdf_stream *)image_info.Mask;
- code = pdfi_get_image_info(ctx, mask_stream, page_dict,
- stream_dict, inline_image, &mask_info);
- if (code < 0)
- goto cleanupExit;
- } else {
- pdfi_countdown(image_info.Mask);
- image_info.Mask = NULL;
- pdfi_set_warning(ctx, 0, NULL, W_PDF_MASK_ERROR, "pdfi_do_image", NULL);
+ switch (pdfi_type_of(image_info.Mask)) {
+ case PDF_ARRAY:
+ mask_array = (pdf_array *)image_info.Mask;
+ break;
+ case PDF_STREAM:
+ mask_stream = (pdf_stream *)image_info.Mask;
+ code = pdfi_get_image_info(ctx, mask_stream, page_dict,
+ stream_dict, inline_image, &mask_info);
+ if (code < 0)
+ goto cleanupExit;
+ break;
+ default:
+ pdfi_countdown(image_info.Mask);
+ image_info.Mask = NULL;
+ pdfi_set_warning(ctx, 0, NULL, W_PDF_MASK_ERROR, "pdfi_do_image", NULL);
}
}
/* Get the SMask info if we will need it (Type 3x images) */
- if (image_info.SMask && image_info.SMask->type == PDF_STREAM && ctx->device_state.preserve_smask) {
+ if (image_info.SMask && pdfi_type_of(image_info.SMask) == PDF_STREAM && ctx->device_state.preserve_smask) {
/* smask_dict non-NULL is used to flag a Type 3x image below */
smask_stream = (pdf_stream *)image_info.SMask;
code = pdfi_get_image_info(ctx, smask_stream, page_dict, stream_dict,
@@ -2305,7 +2368,7 @@ static int pdfi_form_stream_hack(pdf_context *ctx, pdf_dict *form_dict, pdf_stre
*hacked_stream = NULL;
- if (form_dict->type == PDF_STREAM)
+ if (pdfi_type_of(form_dict) == PDF_STREAM)
return 0;
if (!ctx->args.pdfstoponerror) {
@@ -2325,7 +2388,7 @@ static int pdfi_form_stream_hack(pdf_context *ctx, pdf_dict *form_dict, pdf_stre
pdfi_countup(d);
do {
code = pdfi_dict_knownget(ctx, d, "Parent", (pdf_obj **)&Parent);
- if (code > 0) {
+ if (code > 0 && pdfi_type_of(Parent) == PDF_DICT) {
if (Parent->object_num == stream_obj->object_num) {
pdfi_countdown(d);
pdfi_countdown(Parent);
@@ -2386,7 +2449,7 @@ static int pdfi_do_form(pdf_context *ctx, pdf_dict *page_dict, pdf_stream *form_
#if DEBUG_IMAGES
dbgmprintf(ctx->memory, "pdfi_do_form BEGIN\n");
#endif
- if (form_obj->type != PDF_STREAM) {
+ if (pdfi_type_of(form_obj) != PDF_STREAM) {
code = pdfi_form_stream_hack(ctx, (pdf_dict *)form_obj, &hacked_stream);
if (code < 0)
return code;
@@ -2530,10 +2593,15 @@ int pdfi_do_image_or_form(pdf_context *ctx, pdf_dict *stream_dict,
else
goto exit;
}
+ if (pdfi_type_of(n) != PDF_NAME) {
+ code = gs_note_error(gs_error_typecheck);
+ goto exit;
+ }
+
if (pdfi_name_is(n, "Image")) {
gs_offset_t savedoffset;
- if (xobject_obj->type != PDF_STREAM) {
+ if (pdfi_type_of(xobject_obj) != PDF_STREAM) {
code = gs_note_error(gs_error_typecheck);
goto exit;
}
@@ -2568,14 +2636,17 @@ int pdfi_Do(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict)
pdf_name *n = NULL;
pdf_obj *o = NULL;
pdf_dict *sdict = NULL;
- bool known = false;
+ bool known = false, AddedParent = false;
if (pdfi_count_stack(ctx) < 1) {
code = gs_note_error(gs_error_stackunderflow);
goto exit1;
}
n = (pdf_name *)ctx->stack_top[-1];
- if (n->type != PDF_NAME) {
+ pdfi_countup(n);
+ pdfi_pop(ctx, 1);
+
+ if (pdfi_type_of(n) != PDF_NAME) {
code = gs_note_error(gs_error_typecheck);
goto exit1;
}
@@ -2590,7 +2661,7 @@ int pdfi_Do(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict)
if (code < 0)
goto exit;
- if (o->type != PDF_STREAM && o->type != PDF_DICT) {
+ if (pdfi_type_of(o) != PDF_STREAM && pdfi_type_of(o) != PDF_DICT) {
code = gs_note_error(gs_error_typecheck);
goto exit;
}
@@ -2610,9 +2681,11 @@ int pdfi_Do(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict)
code = pdfi_dict_put(ctx, sdict, "Parent", (pdf_obj *)stream_dict);
if (code < 0)
goto exit;
+ pdfi_countup(sdict);
+ AddedParent = true;
}
- code = pdfi_loop_detector_cleartomark(ctx);
+ (void)pdfi_loop_detector_cleartomark(ctx);
/* NOTE: Used to have a pdfi_gsave/pdfi_grestore around this, but it actually makes
* things render incorrectly (and isn't in the PS code).
* It also causes demo.ai.pdf to crash.
@@ -2627,15 +2700,21 @@ int pdfi_Do(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict)
// pdfi_gsave(ctx);
code = pdfi_do_image_or_form(ctx, stream_dict, page_dict, o);
// pdfi_grestore(ctx);
+ pdfi_countdown(n);
pdfi_countdown(o);
- pdfi_pop(ctx, 1);
+ if (AddedParent == true) {
+ if (code >= 0)
+ code = pdfi_dict_delete(ctx, sdict, "Parent");
+ else
+ (void)pdfi_dict_delete(ctx, sdict, "Parent");
+ pdfi_countdown(sdict);
+ }
return code;
exit:
(void)pdfi_loop_detector_cleartomark(ctx);
exit1:
- /* No need to countdown 'n' because that points to the stack object, and we're going to pop that */
+ pdfi_countdown(n);
pdfi_countdown(o);
- pdfi_pop(ctx, 1);
return code;
}