diff options
-rw-r--r-- | include/mupdf/fitz/filter.h | 2 | ||||
-rw-r--r-- | source/fitz/filter-basic.c | 5 | ||||
-rw-r--r-- | source/pdf/pdf-crypt.c | 22 | ||||
-rw-r--r-- | source/pdf/pdf-stream.c | 111 |
4 files changed, 91 insertions, 49 deletions
diff --git a/include/mupdf/fitz/filter.h b/include/mupdf/fitz/filter.h index 58dc3e21..2f73f02f 100644 --- a/include/mupdf/fitz/filter.h +++ b/include/mupdf/fitz/filter.h @@ -12,7 +12,7 @@ typedef struct fz_jbig2_globals_s fz_jbig2_globals; fz_stream *fz_open_copy(fz_context *ctx, fz_stream *chain); fz_stream *fz_open_null(fz_context *ctx, fz_stream *chain, int len, fz_off_t offset); fz_stream *fz_open_concat(fz_context *ctx, int max, int pad); -void fz_concat_push(fz_context *ctx, fz_stream *concat, fz_stream *chain); /* Ownership of chain is passed in */ +void fz_concat_push_drop(fz_context *ctx, fz_stream *concat, fz_stream *chain); /* Ownership of chain is passed in */ fz_stream *fz_open_arc4(fz_context *ctx, fz_stream *chain, unsigned char *key, unsigned keylen); fz_stream *fz_open_aesd(fz_context *ctx, fz_stream *chain, unsigned char *key, unsigned keylen); fz_stream *fz_open_a85d(fz_context *ctx, fz_stream *chain); diff --git a/source/fitz/filter-basic.c b/source/fitz/filter-basic.c index 5630c37b..959006f9 100644 --- a/source/fitz/filter-basic.c +++ b/source/fitz/filter-basic.c @@ -162,12 +162,15 @@ fz_open_concat(fz_context *ctx, int len, int pad) } void -fz_concat_push(fz_context *ctx, fz_stream *concat, fz_stream *chain) +fz_concat_push_drop(fz_context *ctx, fz_stream *concat, fz_stream *chain) { struct concat_filter *state = (struct concat_filter *)concat->state; if (state->count == state->max) + { + fz_drop_stream(ctx, chain); fz_throw(ctx, FZ_ERROR_GENERIC, "Concat filter size exceeded"); + } state->chain[state->count++] = chain; } diff --git a/source/pdf/pdf-crypt.c b/source/pdf/pdf-crypt.c index e7f5f7a9..9f3b05e9 100644 --- a/source/pdf/pdf-crypt.c +++ b/source/pdf/pdf-crypt.c @@ -1023,12 +1023,26 @@ pdf_open_crypt(fz_context *ctx, fz_stream *chain, pdf_crypt *crypt, int num, int fz_stream * pdf_open_crypt_with_filter(fz_context *ctx, fz_stream *chain, pdf_crypt *crypt, pdf_obj *name, int num, int gen) { - if (!pdf_name_eq(ctx, name, PDF_NAME_Identity)) + fz_var(chain); + + fz_try(ctx) + { + if (!pdf_name_eq(ctx, name, PDF_NAME_Identity)) + { + pdf_crypt_filter cf; + fz_stream *tmp; + pdf_parse_crypt_filter(ctx, &cf, crypt, name); + tmp = chain; + chain = NULL; + chain = pdf_open_crypt_imp(ctx, tmp, crypt, &cf, num, gen); + } + } + fz_catch(ctx) { - pdf_crypt_filter cf; - pdf_parse_crypt_filter(ctx, &cf, crypt, name); - return pdf_open_crypt_imp(ctx, chain, crypt, &cf, num, gen); + fz_drop_stream(ctx, chain); + fz_rethrow(ctx); } + return chain; } diff --git a/source/pdf/pdf-stream.c b/source/pdf/pdf-stream.c index 34757aa8..baf9f0a6 100644 --- a/source/pdf/pdf-stream.c +++ b/source/pdf/pdf-stream.c @@ -155,58 +155,82 @@ static fz_stream * build_filter(fz_context *ctx, fz_stream *chain, pdf_document *doc, pdf_obj *f, pdf_obj *p, int num, int gen, fz_compression_params *params) { fz_compression_params local_params; + fz_stream *tmp; - if (params == NULL) - params = &local_params; - - build_compression_params(ctx, f, p, params); - - /* If we were using params we were passed in, and we successfully - * recognised the image type, we can use the existing filter and - * shortstop here. */ - if (params != &local_params && params->type != FZ_IMAGE_RAW) - return chain; + fz_var(chain); - if (params->type != FZ_IMAGE_RAW) - return fz_open_image_decomp_stream(ctx, chain, params, NULL); + fz_try(ctx) + { + if (params == NULL) + params = &local_params; - if (pdf_name_eq(ctx, f, PDF_NAME_ASCIIHexDecode) || pdf_name_eq(ctx, f, PDF_NAME_AHx)) - return fz_open_ahxd(ctx, chain); + build_compression_params(ctx, f, p, params); - else if (pdf_name_eq(ctx, f, PDF_NAME_ASCII85Decode) || pdf_name_eq(ctx, f, PDF_NAME_A85)) - return fz_open_a85d(ctx, chain); + /* If we were using params we were passed in, and we successfully + * recognised the image type, we can use the existing filter and + * shortstop here. */ + if (params != &local_params && params->type != FZ_IMAGE_RAW) + break; /* nothing to do */ - else if (pdf_name_eq(ctx, f, PDF_NAME_JBIG2Decode)) - { - fz_jbig2_globals *globals = NULL; - pdf_obj *obj = pdf_dict_get(ctx, p, PDF_NAME_JBIG2Globals); - if (pdf_is_indirect(ctx, obj)) - globals = pdf_load_jbig2_globals(ctx, doc, obj); - /* fz_open_jbig2d takes possession of globals */ - return fz_open_jbig2d(ctx, chain, globals); - } + else if (params->type != FZ_IMAGE_RAW) + { + tmp = chain; + chain = NULL; + chain = fz_open_image_decomp_stream(ctx, tmp, params, NULL); + } - else if (pdf_name_eq(ctx, f, PDF_NAME_JPXDecode)) - return chain; /* JPX decoding is special cased in the image loading code */ + else if (pdf_name_eq(ctx, f, PDF_NAME_ASCIIHexDecode) || pdf_name_eq(ctx, f, PDF_NAME_AHx)) + { + tmp = chain; + chain = NULL; + chain = fz_open_ahxd(ctx, tmp); + } - else if (pdf_name_eq(ctx, f, PDF_NAME_Crypt)) - { - pdf_obj *name; + else if (pdf_name_eq(ctx, f, PDF_NAME_ASCII85Decode) || pdf_name_eq(ctx, f, PDF_NAME_A85)) + { + tmp = chain; + chain = NULL; + chain = fz_open_a85d(ctx, tmp); + } - if (!doc->crypt) + else if (pdf_name_eq(ctx, f, PDF_NAME_JBIG2Decode)) { - fz_warn(ctx, "crypt filter in unencrypted document"); - return chain; + fz_jbig2_globals *globals = NULL; + pdf_obj *obj = pdf_dict_get(ctx, p, PDF_NAME_JBIG2Globals); + if (pdf_is_indirect(ctx, obj)) + globals = pdf_load_jbig2_globals(ctx, doc, obj); + tmp = chain; + chain = NULL; + chain = fz_open_jbig2d(ctx, tmp, globals); } - name = pdf_dict_get(ctx, p, PDF_NAME_Name); - if (pdf_is_name(ctx, name)) - return pdf_open_crypt_with_filter(ctx, chain, doc->crypt, name, num, gen); + else if (pdf_name_eq(ctx, f, PDF_NAME_JPXDecode)) + break; /* JPX decoding is special cased in the image loading code */ - return chain; + else if (pdf_name_eq(ctx, f, PDF_NAME_Crypt)) + { + if (!doc->crypt) + fz_warn(ctx, "crypt filter in unencrypted document"); + else + { + pdf_obj *name = pdf_dict_get(ctx, p, PDF_NAME_Name); + if (pdf_is_name(ctx, name)) + { + tmp = chain; + chain = NULL; + chain = pdf_open_crypt_with_filter(ctx, tmp, doc->crypt, name, num, gen); + } + } + } + else + fz_warn(ctx, "unknown filter name (%s)", pdf_to_name(ctx, f)); + } + fz_catch(ctx) + { + fz_drop_stream(ctx, chain); + fz_rethrow(ctx); } - fz_warn(ctx, "unknown filter name (%s)", pdf_to_name(ctx, f)); return chain; } @@ -635,14 +659,15 @@ pdf_open_object_array(fz_context *ctx, pdf_document *doc, pdf_obj *list) { pdf_obj *obj = pdf_array_get(ctx, list, i); fz_try(ctx) - { - fz_concat_push(ctx, stm, pdf_open_stream(ctx, obj)); - } + fz_concat_push_drop(ctx, stm, pdf_open_stream(ctx, obj)); fz_catch(ctx) { - fz_rethrow_if(ctx, FZ_ERROR_TRYLATER); + if (fz_caught(ctx) == FZ_ERROR_TRYLATER) + { + fz_drop_stream(ctx, stm); + fz_rethrow(ctx); + } fz_warn(ctx, "cannot load content stream part %d/%d", i + 1, n); - continue; } } |