From ef3cfb2a49b5be82d56d783f505319754dc65cb8 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Wed, 28 Mar 2018 15:17:27 +0200 Subject: Don't implicitly drop in fz_open_* chained filters. --- source/fitz/compressed-buffer.c | 130 +++++++++++------- source/fitz/filter-basic.c | 148 +++++++-------------- source/fitz/filter-dct.c | 30 ++--- source/fitz/filter-fax.c | 22 ++- source/fitz/filter-flate.c | 38 ++---- source/fitz/filter-jbig2.c | 23 ++-- source/fitz/filter-leech.c | 21 +-- source/fitz/filter-lzw.c | 74 +++++------ source/fitz/filter-predict.c | 52 +++----- source/fitz/filter-sgi.c | 14 +- source/fitz/filter-thunder.c | 14 +- source/fitz/image.c | 27 ++-- source/fitz/load-gif.c | 4 +- source/fitz/load-png.c | 16 ++- source/fitz/load-tiff.c | 7 +- source/fitz/stream-open.c | 2 +- source/gprf/gprf-doc.c | 12 +- source/pdf/pdf-crypt.c | 26 +--- source/pdf/pdf-form.c | 2 +- source/pdf/pdf-stream.c | 287 +++++++++++++++++----------------------- 20 files changed, 403 insertions(+), 546 deletions(-) (limited to 'source') diff --git a/source/fitz/compressed-buffer.c b/source/fitz/compressed-buffer.c index 3846fcb2..e8ea08e0 100644 --- a/source/fitz/compressed-buffer.c +++ b/source/fitz/compressed-buffer.c @@ -6,77 +6,115 @@ void fz_drop_compressed_buffer(fz_context *ctx, fz_compressed_buffer *buf) { - if (!buf) - return; - - fz_drop_buffer(ctx, buf->buffer); - fz_free(ctx, buf); + if (buf) + { + fz_drop_buffer(ctx, buf->buffer); + fz_free(ctx, buf); + } } fz_stream * fz_open_image_decomp_stream_from_buffer(fz_context *ctx, fz_compressed_buffer *buffer, int *l2factor) { - fz_stream *chain = fz_open_buffer(ctx, buffer->buffer); + fz_stream *head, *tail; - return fz_open_image_decomp_stream(ctx, chain, &buffer->params, l2factor); + tail = fz_open_buffer(ctx, buffer->buffer); + fz_try(ctx) + head = fz_open_image_decomp_stream(ctx, tail, &buffer->params, l2factor); + fz_always(ctx) + fz_drop_stream(ctx, tail); + fz_catch(ctx) + fz_rethrow(ctx); + return head; } fz_stream * -fz_open_image_decomp_stream(fz_context *ctx, fz_stream *chain, fz_compression_params *params, int *l2factor) +fz_open_image_decomp_stream(fz_context *ctx, fz_stream *tail, fz_compression_params *params, int *l2factor) { + fz_stream *head = NULL, *body = NULL; int our_l2factor = 0; - switch (params->type) + fz_var(body); + + fz_try(ctx) { - case FZ_IMAGE_FAX: - return fz_open_faxd(ctx, chain, - params->u.fax.k, - params->u.fax.end_of_line, - params->u.fax.encoded_byte_align, - params->u.fax.columns, - params->u.fax.rows, - params->u.fax.end_of_block, - params->u.fax.black_is_1); - case FZ_IMAGE_JPEG: - if (l2factor) + switch (params->type) { - our_l2factor = *l2factor; - if (our_l2factor > 3) - our_l2factor = 3; - *l2factor -= our_l2factor; + default: + head = fz_keep_stream(ctx, tail); + break; + + case FZ_IMAGE_FAX: + head = fz_open_faxd(ctx, tail, + params->u.fax.k, + params->u.fax.end_of_line, + params->u.fax.encoded_byte_align, + params->u.fax.columns, + params->u.fax.rows, + params->u.fax.end_of_block, + params->u.fax.black_is_1); + break; + + case FZ_IMAGE_JPEG: + if (l2factor) + { + our_l2factor = *l2factor; + if (our_l2factor > 3) + our_l2factor = 3; + *l2factor -= our_l2factor; + } + head = fz_open_dctd(ctx, tail, params->u.jpeg.color_transform, our_l2factor, NULL); + break; + + case FZ_IMAGE_RLD: + head = fz_open_rld(ctx, tail); + break; + + case FZ_IMAGE_FLATE: + head = fz_open_flated(ctx, tail, 15); + if (params->u.flate.predictor > 1) + { + body = head; + head = fz_open_predict(ctx, body, + params->u.flate.predictor, + params->u.flate.columns, + params->u.flate.colors, + params->u.flate.bpc); + } + break; + + case FZ_IMAGE_LZW: + head = fz_open_lzwd(ctx, tail, params->u.lzw.early_change, 9, 0, 0); + if (params->u.flate.predictor > 1) + { + body = head; + head = fz_open_predict(ctx, body, + params->u.lzw.predictor, + params->u.lzw.columns, + params->u.lzw.colors, + params->u.lzw.bpc); + } + break; } - return fz_open_dctd(ctx, chain, params->u.jpeg.color_transform, our_l2factor, NULL); - case FZ_IMAGE_RLD: - return fz_open_rld(ctx, chain); - case FZ_IMAGE_FLATE: - chain = fz_open_flated(ctx, chain, 15); - if (params->u.flate.predictor > 1) - chain = fz_open_predict(ctx, chain, params->u.flate.predictor, params->u.flate.columns, params->u.flate.colors, params->u.flate.bpc); - return chain; - case FZ_IMAGE_LZW: - chain = fz_open_lzwd(ctx, chain, params->u.lzw.early_change, 9, 0, 0); - if (params->u.lzw.predictor > 1) - chain = fz_open_predict(ctx, chain, params->u.lzw.predictor, params->u.lzw.columns, params->u.lzw.colors, params->u.lzw.bpc); - return chain; - default: - break; } + fz_always(ctx) + fz_drop_stream(ctx, body); + fz_catch(ctx) + fz_rethrow(ctx); - return chain; + return head; } fz_stream * fz_open_compressed_buffer(fz_context *ctx, fz_compressed_buffer *buffer) { - int l2factor = 0; - - return fz_open_image_decomp_stream_from_buffer(ctx, buffer, &l2factor); + return fz_open_image_decomp_stream_from_buffer(ctx, buffer, NULL); } size_t fz_compressed_buffer_size(fz_compressed_buffer *buffer) { - if (!buffer || !buffer->buffer) - return 0; - return (size_t)buffer->buffer->cap; + if (buffer && buffer->buffer) + return (size_t)buffer->buffer->cap; + return 0; } diff --git a/source/fitz/filter-basic.c b/source/fitz/filter-basic.c index e5d7a4e4..f558f43b 100644 --- a/source/fitz/filter-basic.c +++ b/source/fitz/filter-basic.c @@ -60,10 +60,9 @@ static void close_null(fz_context *ctx, void *state_) { struct null_filter *state = (struct null_filter *)state_; - fz_stream *chain = state->chain; + fz_drop_stream(ctx, state->chain); fz_free(ctx, state->ranges); fz_free(ctx, state); - fz_drop_stream(ctx, chain); } fz_stream * @@ -71,23 +70,32 @@ fz_open_null_n(fz_context *ctx, fz_stream *chain, fz_range *ranges, int nranges) { struct null_filter *state = NULL; - fz_var(state); + state = fz_malloc_struct(ctx, struct null_filter); fz_try(ctx) { - state = fz_malloc_struct(ctx, struct null_filter); - state->ranges = fz_calloc(ctx, nranges, sizeof(*ranges)); - memcpy(state->ranges, ranges, nranges * sizeof(*ranges)); - state->nranges = nranges; - state->next_range = 1; - state->chain = chain; - state->remain = nranges ? ranges[0].len : 0; - state->offset = nranges ? ranges[0].offset : 0; + if (nranges > 0) + { + state->ranges = fz_calloc(ctx, nranges, sizeof(*ranges)); + memcpy(state->ranges, ranges, nranges * sizeof(*ranges)); + state->nranges = nranges; + state->next_range = 1; + state->remain = ranges[0].len; + state->offset = ranges[0].offset; + } + else + { + state->ranges = NULL; + state->nranges = 0; + state->next_range = 1; + state->remain = 0; + state->offset = 0; + } + state->chain = fz_keep_stream(ctx, chain); } fz_catch(ctx) { fz_free(ctx, state->ranges); fz_free(ctx, state); - fz_drop_stream(ctx, chain); fz_rethrow(ctx); } @@ -303,28 +311,16 @@ static void close_ahxd(fz_context *ctx, void *state_) { fz_ahxd *state = (fz_ahxd *)state_; - fz_stream *chain = state->chain; + fz_drop_stream(ctx, state->chain); fz_free(ctx, state); - fz_drop_stream(ctx, chain); } fz_stream * fz_open_ahxd(fz_context *ctx, fz_stream *chain) { - fz_ahxd *state = NULL; - - fz_try(ctx) - { - state = fz_malloc_struct(ctx, fz_ahxd); - state->chain = chain; - state->eod = 0; - } - fz_catch(ctx) - { - fz_drop_stream(ctx, chain); - fz_rethrow(ctx); - } - + fz_ahxd *state = fz_malloc_struct(ctx, fz_ahxd); + state->chain = fz_keep_stream(ctx, chain); + state->eod = 0; return fz_new_stream(ctx, state, next_ahxd, close_ahxd); } @@ -446,29 +442,16 @@ static void close_a85d(fz_context *ctx, void *state_) { fz_a85d *state = (fz_a85d *)state_; - fz_stream *chain = state->chain; - + fz_drop_stream(ctx, state->chain); fz_free(ctx, state); - fz_drop_stream(ctx, chain); } fz_stream * fz_open_a85d(fz_context *ctx, fz_stream *chain) { - fz_a85d *state = NULL; - - fz_try(ctx) - { - state = fz_malloc_struct(ctx, fz_a85d); - state->chain = chain; - state->eod = 0; - } - fz_catch(ctx) - { - fz_drop_stream(ctx, chain); - fz_rethrow(ctx); - } - + fz_a85d *state = fz_malloc_struct(ctx, fz_a85d); + state->chain = fz_keep_stream(ctx, chain); + state->eod = 0; return fz_new_stream(ctx, state, next_a85d, close_a85d); } @@ -557,31 +540,18 @@ static void close_rld(fz_context *ctx, void *state_) { fz_rld *state = (fz_rld *)state_; - fz_stream *chain = state->chain; - + fz_drop_stream(ctx, state->chain); fz_free(ctx, state); - fz_drop_stream(ctx, chain); } fz_stream * fz_open_rld(fz_context *ctx, fz_stream *chain) { - fz_rld *state = NULL; - - fz_try(ctx) - { - state = fz_malloc_struct(ctx, fz_rld); - state->chain = chain; - state->run = 0; - state->n = 0; - state->c = 0; - } - fz_catch(ctx) - { - fz_drop_stream(ctx, chain); - fz_rethrow(ctx); - } - + fz_rld *state = fz_malloc_struct(ctx, fz_rld); + state->chain = fz_keep_stream(ctx, chain); + state->run = 0; + state->n = 0; + state->c = 0; return fz_new_stream(ctx, state, next_rld, close_rld); } @@ -620,29 +590,16 @@ static void close_arc4(fz_context *ctx, void *state_) { fz_arc4c *state = (fz_arc4c *)state_; - fz_stream *chain = state->chain; - + fz_drop_stream(ctx, state->chain); fz_free(ctx, state); - fz_drop_stream(ctx, chain); } fz_stream * fz_open_arc4(fz_context *ctx, fz_stream *chain, unsigned char *key, unsigned keylen) { - fz_arc4c *state = NULL; - - fz_try(ctx) - { - state = fz_malloc_struct(ctx, fz_arc4c); - state->chain = chain; - fz_arc4_init(&state->arc4, key, keylen); - } - fz_catch(ctx) - { - fz_drop_stream(ctx, chain); - fz_rethrow(ctx); - } - + fz_arc4c *state = fz_malloc_struct(ctx, fz_arc4c); + state->chain = fz_keep_stream(ctx, chain); + fz_arc4_init(&state->arc4, key, keylen); return fz_new_stream(ctx, state, next_arc4, close_arc4); } @@ -722,35 +679,22 @@ static void close_aesd(fz_context *ctx, void *state_) { fz_aesd *state = (fz_aesd *)state_; - fz_stream *chain = state->chain; - + fz_drop_stream(ctx, state->chain); fz_free(ctx, state); - fz_drop_stream(ctx, chain); } fz_stream * fz_open_aesd(fz_context *ctx, fz_stream *chain, unsigned char *key, unsigned keylen) { - fz_aesd *state = NULL; - - fz_var(state); - - fz_try(ctx) - { - state = fz_malloc_struct(ctx, fz_aesd); - state->chain = chain; - if (fz_aes_setkey_dec(&state->aes, key, keylen * 8)) - fz_throw(ctx, FZ_ERROR_GENERIC, "AES key init failed (keylen=%d)", keylen * 8); - state->ivcount = 0; - state->rp = state->bp; - state->wp = state->bp; - } - fz_catch(ctx) + fz_aesd *state = fz_malloc_struct(ctx, fz_aesd); + if (fz_aes_setkey_dec(&state->aes, key, keylen * 8)) { fz_free(ctx, state); - fz_drop_stream(ctx, chain); - fz_rethrow(ctx); + fz_throw(ctx, FZ_ERROR_GENERIC, "AES key init failed (keylen=%d)", keylen * 8); } - + state->ivcount = 0; + state->rp = state->bp; + state->wp = state->bp; + state->chain = fz_keep_stream(ctx, chain); return fz_new_stream(ctx, state, next_aesd, close_aesd); } diff --git a/source/fitz/filter-dct.c b/source/fitz/filter-dct.c index 644d0dfc..a3ada67e 100644 --- a/source/fitz/filter-dct.c +++ b/source/fitz/filter-dct.c @@ -317,29 +317,17 @@ skip: fz_stream * fz_open_dctd(fz_context *ctx, fz_stream *chain, int color_transform, int l2factor, fz_stream *jpegtables) { - fz_dctd *state = NULL; + fz_dctd *state = fz_malloc_struct(ctx, fz_dctd); - fz_var(state); + state->ctx = ctx; + state->color_transform = color_transform; + state->init = 0; + state->l2factor = l2factor; + state->cinfo.client_data = NULL; - fz_try(ctx) - { - state = fz_malloc_struct(ctx, fz_dctd); - state->ctx = ctx; - state->chain = chain; - state->jpegtables = jpegtables; - state->curr_stm = chain; - state->color_transform = color_transform; - state->init = 0; - state->l2factor = l2factor; - state->cinfo.client_data = NULL; - } - fz_catch(ctx) - { - fz_free(ctx, state); - fz_drop_stream(ctx, chain); - fz_drop_stream(ctx, jpegtables); - fz_rethrow(ctx); - } + state->chain = fz_keep_stream(ctx, chain); + state->jpegtables = fz_keep_stream(ctx, jpegtables); + state->curr_stm = state->chain; return fz_new_stream(ctx, state, next_dctd, close_dctd); } diff --git a/source/fitz/filter-fax.c b/source/fitz/filter-fax.c index a4ca8ab5..ae117029 100644 --- a/source/fitz/filter-fax.c +++ b/source/fitz/filter-fax.c @@ -775,18 +775,14 @@ fz_open_faxd(fz_context *ctx, fz_stream *chain, int k, int end_of_line, int encoded_byte_align, int columns, int rows, int end_of_block, int black_is_1) { - fz_faxd *fax = NULL; + fz_faxd *fax; - fz_var(fax); + if (columns < 0 || columns >= INT_MAX - 7) + fz_throw(ctx, FZ_ERROR_GENERIC, "too many columns lead to an integer overflow (%d)", columns); + fax = fz_malloc_struct(ctx, fz_faxd); fz_try(ctx) { - if (columns < 0 || columns >= INT_MAX - 7) - fz_throw(ctx, FZ_ERROR_GENERIC, "too many columns lead to an integer overflow (%d)", columns); - - fax = fz_malloc_struct(ctx, fz_faxd); - fax->chain = chain; - fax->ref = NULL; fax->dst = NULL; @@ -816,16 +812,14 @@ fz_open_faxd(fz_context *ctx, fz_stream *chain, memset(fax->ref, 0, fax->stride); memset(fax->dst, 0, fax->stride); + + fax->chain = fz_keep_stream(ctx, chain); } fz_catch(ctx) { - if (fax) - { - fz_free(ctx, fax->dst); - fz_free(ctx, fax->ref); - } + fz_free(ctx, fax->dst); + fz_free(ctx, fax->ref); fz_free(ctx, fax); - fz_drop_stream(ctx, chain); fz_rethrow(ctx); } diff --git a/source/fitz/filter-flate.c b/source/fitz/filter-flate.c index a7bbb273..b986a228 100644 --- a/source/fitz/filter-flate.c +++ b/source/fitz/filter-flate.c @@ -102,34 +102,24 @@ close_flated(fz_context *ctx, void *state_) fz_stream * fz_open_flated(fz_context *ctx, fz_stream *chain, int window_bits) { - fz_inflate_state *state = NULL; - int code = Z_OK; + fz_inflate_state *state; + int code; - fz_var(code); - fz_var(state); + state = fz_malloc_struct(ctx, fz_inflate_state); + state->z.zalloc = zalloc_flate; + state->z.zfree = zfree_flate; + state->z.opaque = ctx; + state->z.next_in = NULL; + state->z.avail_in = 0; - fz_try(ctx) - { - state = fz_malloc_struct(ctx, fz_inflate_state); - state->chain = chain; - - state->z.zalloc = zalloc_flate; - state->z.zfree = zfree_flate; - state->z.opaque = ctx; - state->z.next_in = NULL; - state->z.avail_in = 0; - - code = inflateInit2(&state->z, window_bits); - if (code != Z_OK) - fz_throw(ctx, FZ_ERROR_GENERIC, "zlib error: inflateInit: %s", state->z.msg); - } - fz_catch(ctx) + code = inflateInit2(&state->z, window_bits); + if (code != Z_OK) { - if (state && code == Z_OK) - inflateEnd(&state->z); fz_free(ctx, state); - fz_drop_stream(ctx, chain); - fz_rethrow(ctx); + fz_throw(ctx, FZ_ERROR_GENERIC, "zlib error: inflateInit2 failed"); } + + state->chain = fz_keep_stream(ctx, chain); + return fz_new_stream(ctx, state, next_flated, close_flated); } diff --git a/source/fitz/filter-jbig2.c b/source/fitz/filter-jbig2.c index 74fdae66..0d581b95 100644 --- a/source/fitz/filter-jbig2.c +++ b/source/fitz/filter-jbig2.c @@ -220,27 +220,21 @@ fz_open_jbig2d(fz_context *ctx, fz_stream *chain, fz_jbig2_globals *globals) { fz_jbig2d *state = NULL; - fz_var(state); - fz_try(ctx) - { state = fz_malloc_struct(ctx, fz_jbig2d); - state->ctx = ctx; - state->gctx = globals; - state->chain = chain; - state->idx = 0; - state->output = NULL; - state->doc = NULL; - fz_warn(ctx, "opening jbig2"); - } fz_catch(ctx) { fz_drop_jbig2_globals(ctx, globals); - fz_free(ctx, state); - fz_drop_stream(ctx, chain); fz_rethrow(ctx); } + state->ctx = ctx; + state->gctx = globals; + state->chain = fz_keep_stream(ctx, chain); + state->idx = 0; + state->output = NULL; + state->doc = NULL; + return fz_new_stream(ctx, state, next_jbig2d, close_jbig2d); } @@ -415,7 +409,6 @@ fz_open_jbig2d(fz_context *ctx, fz_stream *chain, fz_jbig2_globals *globals) { state = fz_malloc_struct(ctx, fz_jbig2d); state->gctx = globals; - state->chain = chain; state->alloc.ctx = ctx; state->alloc.alloc.alloc = fz_jbig2_alloc; state->alloc.alloc.free = fz_jbig2_free; @@ -423,6 +416,7 @@ fz_open_jbig2d(fz_context *ctx, fz_stream *chain, fz_jbig2_globals *globals) state->ctx = jbig2_ctx_new((Jbig2Allocator *) &state->alloc, JBIG2_OPTIONS_EMBEDDED, globals ? globals->gctx : NULL, error_callback, ctx); state->page = NULL; state->idx = 0; + state->chain = fz_keep_stream(ctx, chain); } fz_catch(ctx) { @@ -433,7 +427,6 @@ fz_open_jbig2d(fz_context *ctx, fz_stream *chain, fz_jbig2_globals *globals) jbig2_ctx_free(state->ctx); } fz_free(ctx, state); - fz_drop_stream(ctx, chain); fz_rethrow(ctx); } diff --git a/source/fitz/filter-leech.c b/source/fitz/filter-leech.c index cc98b972..77485068 100644 --- a/source/fitz/filter-leech.c +++ b/source/fitz/filter-leech.c @@ -41,29 +41,16 @@ static void close_leech(fz_context *ctx, void *state_) { fz_leech *state = (fz_leech *)state_; - fz_drop_stream(ctx, state->chain); + fz_drop_buffer(ctx, state->buffer); fz_free(ctx, state); } fz_stream * fz_open_leecher(fz_context *ctx, fz_stream *chain, fz_buffer *buffer) { - fz_leech *state = NULL; - - fz_var(state); - - fz_try(ctx) - { - state = fz_malloc_struct(ctx, fz_leech); - state->chain = chain; - state->buffer = buffer; - } - fz_catch(ctx) - { - fz_free(ctx, state); - fz_drop_stream(ctx, chain); - fz_rethrow(ctx); - } + fz_leech *state = fz_malloc_struct(ctx, fz_leech); + state->chain = fz_keep_stream(ctx, chain); + state->buffer = fz_keep_buffer(ctx, buffer); return fz_new_stream(ctx, state, next_leech, close_leech); } diff --git a/source/fitz/filter-lzw.c b/source/fitz/filter-lzw.c index a7d7d430..9198d081 100644 --- a/source/fitz/filter-lzw.c +++ b/source/fitz/filter-lzw.c @@ -207,55 +207,45 @@ close_lzwd(fz_context *ctx, void *state_) fz_stream * fz_open_lzwd(fz_context *ctx, fz_stream *chain, int early_change, int min_bits, int reverse_bits, int old_tiff) { - fz_lzwd *lzw = NULL; + fz_lzwd *lzw; int i; - fz_var(lzw); - - fz_try(ctx) + if (min_bits > MAX_BITS) { - if (min_bits > MAX_BITS) - { - fz_warn(ctx, "out of range initial lzw code size"); - min_bits = MAX_BITS; - } - - lzw = fz_malloc_struct(ctx, fz_lzwd); - lzw->chain = chain; - lzw->eod = 0; - lzw->early_change = early_change; - lzw->reverse_bits = reverse_bits; - lzw->old_tiff = old_tiff; - lzw->min_bits = min_bits; - lzw->code_bits = lzw->min_bits; - lzw->code = -1; - lzw->next_code = LZW_FIRST(lzw); - lzw->old_code = -1; - lzw->rp = lzw->bp; - lzw->wp = lzw->bp; - - for (i = 0; i < LZW_CLEAR(lzw); i++) - { - lzw->table[i].value = i; - lzw->table[i].first_char = i; - lzw->table[i].length = 1; - lzw->table[i].prev = -1; - } + fz_warn(ctx, "out of range initial lzw code size"); + min_bits = MAX_BITS; + } - for (i = LZW_CLEAR(lzw); i < NUM_CODES; i++) - { - lzw->table[i].value = 0; - lzw->table[i].first_char = 0; - lzw->table[i].length = 0; - lzw->table[i].prev = -1; - } + lzw = fz_malloc_struct(ctx, fz_lzwd); + lzw->eod = 0; + lzw->early_change = early_change; + lzw->reverse_bits = reverse_bits; + lzw->old_tiff = old_tiff; + lzw->min_bits = min_bits; + lzw->code_bits = lzw->min_bits; + lzw->code = -1; + lzw->next_code = LZW_FIRST(lzw); + lzw->old_code = -1; + lzw->rp = lzw->bp; + lzw->wp = lzw->bp; + + for (i = 0; i < LZW_CLEAR(lzw); i++) + { + lzw->table[i].value = i; + lzw->table[i].first_char = i; + lzw->table[i].length = 1; + lzw->table[i].prev = -1; } - fz_catch(ctx) + + for (i = LZW_CLEAR(lzw); i < NUM_CODES; i++) { - fz_free(ctx, lzw); - fz_drop_stream(ctx, chain); - fz_rethrow(ctx); + lzw->table[i].value = 0; + lzw->table[i].first_char = 0; + lzw->table[i].length = 0; + lzw->table[i].prev = -1; } + lzw->chain = fz_keep_stream(ctx, chain); + return fz_new_stream(ctx, lzw, next_lzwd, close_lzwd); } diff --git a/source/fitz/filter-predict.c b/source/fitz/filter-predict.c index 24007bfe..e00e07fd 100644 --- a/source/fitz/filter-predict.c +++ b/source/fitz/filter-predict.c @@ -226,9 +226,7 @@ close_predict(fz_context *ctx, void *state_) fz_stream * fz_open_predict(fz_context *ctx, fz_stream *chain, int predictor, int columns, int colors, int bpc) { - fz_predict *state = NULL; - - fz_var(state); + fz_predict *state; if (predictor < 1) predictor = 1; @@ -239,34 +237,30 @@ fz_open_predict(fz_context *ctx, fz_stream *chain, int predictor, int columns, i if (bpc < 1) bpc = 8; - fz_try(ctx) + if (bpc != 1 && bpc != 2 && bpc != 4 && bpc != 8 && bpc != 16) + fz_throw(ctx, FZ_ERROR_GENERIC, "invalid number of bits per component: %d", bpc); + if (colors > FZ_MAX_COLORS) + fz_throw(ctx, FZ_ERROR_GENERIC, "too many color components (%d > %d)", colors, FZ_MAX_COLORS); + if (columns >= INT_MAX / (bpc * colors)) + fz_throw(ctx, FZ_ERROR_GENERIC, "too many columns lead to an integer overflow (%d)", columns); + + if (predictor != 1 && predictor != 2 && + predictor != 10 && predictor != 11 && + predictor != 12 && predictor != 13 && + predictor != 14 && predictor != 15) { - if (bpc != 1 && bpc != 2 && bpc != 4 && bpc != 8 && bpc != 16) - fz_throw(ctx, FZ_ERROR_GENERIC, "invalid number of bits per component: %d", bpc); - if (colors > FZ_MAX_COLORS) - fz_throw(ctx, FZ_ERROR_GENERIC, "too many color components (%d > %d)", colors, FZ_MAX_COLORS); - if (columns >= INT_MAX / (bpc * colors)) - fz_throw(ctx, FZ_ERROR_GENERIC, "too many columns lead to an integer overflow (%d)", columns); - - state = fz_malloc_struct(ctx, fz_predict); - state->in = NULL; - state->out = NULL; - state->chain = chain; + fz_warn(ctx, "invalid predictor: %d", predictor); + predictor = 1; + } + state = fz_malloc_struct(ctx, fz_predict); + fz_try(ctx) + { state->predictor = predictor; state->columns = columns; state->colors = colors; state->bpc = bpc; - if (state->predictor != 1 && state->predictor != 2 && - state->predictor != 10 && state->predictor != 11 && - state->predictor != 12 && state->predictor != 13 && - state->predictor != 14 && state->predictor != 15) - { - fz_warn(ctx, "invalid predictor: %d", state->predictor); - state->predictor = 1; - } - state->stride = (state->bpc * state->colors * state->columns + 7) / 8; state->bpp = (state->bpc * state->colors + 7) / 8; @@ -277,16 +271,14 @@ fz_open_predict(fz_context *ctx, fz_stream *chain, int predictor, int columns, i state->wp = state->out; memset(state->ref, 0, state->stride); + + state->chain = fz_keep_stream(ctx, chain); } fz_catch(ctx) { - if (state) - { - fz_free(ctx, state->in); - fz_free(ctx, state->out); - } + fz_free(ctx, state->in); + fz_free(ctx, state->out); fz_free(ctx, state); - fz_drop_stream(ctx, chain); fz_rethrow(ctx); } diff --git a/source/fitz/filter-sgi.c b/source/fitz/filter-sgi.c index 518751ed..43bade71 100644 --- a/source/fitz/filter-sgi.c +++ b/source/fitz/filter-sgi.c @@ -645,36 +645,28 @@ static void close_sgilog32(fz_context *ctx, void *state_) { fz_sgilog32 *state = (fz_sgilog32 *)state_; - fz_stream *chain = state->chain; - + fz_drop_stream(ctx, state->chain); fz_free(ctx, state->temp); fz_free(ctx, state); - fz_drop_stream(ctx, chain); } fz_stream * fz_open_sgilog32(fz_context *ctx, fz_stream *chain, int w) { - fz_sgilog32 *state = NULL; - - fz_var(state); - + fz_sgilog32 *state = fz_malloc_struct(ctx, fz_sgilog32); fz_try(ctx) { - state = fz_malloc_struct(ctx, fz_sgilog32); - state->chain = chain; state->run = 0; state->n = 0; state->c = 0; state->w = w; state->temp = fz_malloc(ctx, w * sizeof(uint32_t)); + state->chain = fz_keep_stream(ctx, chain); } fz_catch(ctx) { fz_free(ctx, state); - fz_drop_stream(ctx, chain); fz_rethrow(ctx); } - return fz_new_stream(ctx, state, next_sgilog32, close_sgilog32); } diff --git a/source/fitz/filter-thunder.c b/source/fitz/filter-thunder.c index 82d313a0..db96fbeb 100644 --- a/source/fitz/filter-thunder.c +++ b/source/fitz/filter-thunder.c @@ -116,36 +116,28 @@ static void close_thunder(fz_context *ctx, void *state_) { fz_thunder *state = (fz_thunder *)state_; - fz_stream *chain = state->chain; - + fz_drop_stream(ctx, state->chain); fz_free(ctx, state->buffer); fz_free(ctx, state); - fz_drop_stream(ctx, chain); } fz_stream * fz_open_thunder(fz_context *ctx, fz_stream *chain, int w) { - fz_thunder *state = NULL; - - fz_var(state); - + fz_thunder *state = fz_malloc_struct(ctx, fz_thunder); fz_try(ctx) { - state = fz_malloc_struct(ctx, fz_thunder); - state->chain = chain; state->run = 0; state->pixel = 0; state->lastpixel = 0; state->len = w / 2; state->buffer = fz_malloc(ctx, state->len); + state->chain = fz_keep_stream(ctx, chain); } fz_catch(ctx) { fz_free(ctx, state); - fz_drop_stream(ctx, chain); fz_rethrow(ctx); } - return fz_new_stream(ctx, state, next_thunder, close_thunder); } diff --git a/source/fitz/image.c b/source/fitz/image.c index b61a606d..51699772 100644 --- a/source/fitz/image.c +++ b/source/fitz/image.c @@ -427,10 +427,6 @@ fz_decomp_image_from_stream(fz_context *ctx, fz_stream *stm, fz_compressed_image if (image->use_colorkey && image->mask) fz_unblend_masked_tile(ctx, tile, image); } - fz_always(ctx) - { - fz_drop_stream(ctx, stm); - } fz_catch(ctx) { fz_drop_pixmap(ctx, tile); @@ -532,12 +528,18 @@ compressed_image_get_pixmap(fz_context *ctx, fz_image *image_, fz_irect *subarea default: native_l2factor = l2factor ? *l2factor : 0; stm = fz_open_image_decomp_stream_from_buffer(ctx, image->buffer, l2factor); - if (l2factor) - native_l2factor -= *l2factor; - - indexed = fz_colorspace_is_indexed(ctx, image->super.colorspace); - can_sub = 1; - tile = fz_decomp_image_from_stream(ctx, stm, image, subarea, indexed, native_l2factor); + fz_try(ctx) + { + if (l2factor) + native_l2factor -= *l2factor; + indexed = fz_colorspace_is_indexed(ctx, image->super.colorspace); + can_sub = 1; + tile = fz_decomp_image_from_stream(ctx, stm, image, subarea, indexed, native_l2factor); + } + fz_always(ctx) + fz_drop_stream(ctx, stm); + fz_catch(ctx) + fz_rethrow(ctx); /* CMYK JPEGs in XPS documents have to be inverted */ if (image->super.invert_cmyk_jpeg && @@ -925,7 +927,7 @@ fz_compressed_buffer *fz_compressed_image_buffer(fz_context *ctx, fz_image *imag void fz_set_compressed_image_buffer(fz_context *ctx, fz_compressed_image *image, fz_compressed_buffer *buf) { assert(image != NULL && image->super.get_pixmap == compressed_image_get_pixmap); - ((fz_compressed_image *)image)->buffer = buf; + ((fz_compressed_image *)image)->buffer = buf; /* Note: compressed buffers are not reference counted */ } fz_pixmap *fz_compressed_image_tile(fz_context *ctx, fz_compressed_image *image) @@ -938,7 +940,8 @@ fz_pixmap *fz_compressed_image_tile(fz_context *ctx, fz_compressed_image *image) void fz_set_compressed_image_tile(fz_context *ctx, fz_compressed_image *image, fz_pixmap *pix) { assert(image != NULL && image->super.get_pixmap == compressed_image_get_pixmap); - ((fz_compressed_image *)image)->tile = pix; + fz_drop_pixmap(ctx, ((fz_compressed_image *)image)->tile); + ((fz_compressed_image *)image)->tile = fz_keep_pixmap(ctx, pix); } fz_pixmap *fz_pixmap_image_tile(fz_context *ctx, fz_pixmap_image *image) diff --git a/source/fitz/load-gif.c b/source/fitz/load-gif.c index 25a37e3f..ca73a537 100644 --- a/source/fitz/load-gif.c +++ b/source/fitz/load-gif.c @@ -237,7 +237,7 @@ gif_read_line(fz_context *ctx, struct info *info, unsigned char *dest, int ct_en static const unsigned char * gif_read_tbid(fz_context *ctx, struct info *info, unsigned char *dest, const unsigned char *p, const unsigned char *end) { - fz_stream *stm, *lzwstm = NULL; + fz_stream *stm = NULL, *lzwstm = NULL; unsigned int mincodesize, y; fz_buffer *compressed = NULL, *uncompressed = NULL; const unsigned char *ct; @@ -258,6 +258,7 @@ gif_read_tbid(fz_context *ctx, struct info *info, unsigned char *dest, const uns fz_var(compressed); fz_var(lzwstm); + fz_var(stm); fz_var(uncompressed); fz_try(ctx) @@ -309,6 +310,7 @@ gif_read_tbid(fz_context *ctx, struct info *info, unsigned char *dest, const uns fz_drop_buffer(ctx, uncompressed); fz_drop_buffer(ctx, compressed); fz_drop_stream(ctx, lzwstm); + fz_drop_stream(ctx, stm); } fz_catch(ctx) { diff --git a/source/fitz/load-png.c b/source/fitz/load-png.c index c5bc925c..39c4ea81 100644 --- a/source/fitz/load-png.c +++ b/source/fitz/load-png.c @@ -344,7 +344,7 @@ png_read_trns(fz_context *ctx, struct info *info, const unsigned char *p, unsign static void png_read_icc(fz_context *ctx, struct info *info, const unsigned char *p, unsigned int size) { - fz_stream *stm = NULL; + fz_stream *mstm = NULL, *zstm = NULL; fz_colorspace *cs = NULL; size_t m = fz_mini(80, size); size_t n = strnlen((const char *)p, m); @@ -354,17 +354,23 @@ png_read_icc(fz_context *ctx, struct info *info, const unsigned char *p, unsigne return; } - stm = fz_open_memory(ctx, p + n + 2, size - n - 2); - stm = fz_open_flated(ctx, stm, 15); + fz_var(mstm); + fz_var(zstm); + fz_try(ctx) { - cs = fz_new_icc_colorspace_from_stream(ctx, (const char *)p, stm); + mstm = fz_open_memory(ctx, p + n + 2, size - n - 2); + zstm = fz_open_flated(ctx, mstm, 15); + cs = fz_new_icc_colorspace_from_stream(ctx, (const char *)p, zstm); /* drop old one in case we have multiple ICC profiles */ fz_drop_colorspace(ctx, info->cs); info->cs = cs; } fz_always(ctx) - fz_drop_stream(ctx, stm); + { + fz_drop_stream(ctx, mstm); + fz_drop_stream(ctx, zstm); + } fz_catch(ctx) fz_warn(ctx, "cannot read embedded ICC profile"); } diff --git a/source/fitz/load-tiff.c b/source/fitz/load-tiff.c index 2da9e635..3dad8a82 100644 --- a/source/fitz/load-tiff.c +++ b/source/fitz/load-tiff.c @@ -309,12 +309,12 @@ tiff_decode_data(fz_context *ctx, struct tiff *tiff, const unsigned char *rp, un rp = reversed; } + fz_var(jpegtables); fz_var(encstm); fz_var(stm); fz_try(ctx) { - /* each decoder will close this */ encstm = fz_open_memory(ctx, rp, rlen); /* switch on compression to create a filter */ @@ -331,7 +331,7 @@ tiff_decode_data(fz_context *ctx, struct tiff *tiff, const unsigned char *rp, un { case 1: /* stm already open and reading uncompressed data */ - stm = encstm; + stm = fz_keep_stream(ctx, encstm); break; case 2: case 3: @@ -385,7 +385,6 @@ tiff_decode_data(fz_context *ctx, struct tiff *tiff, const unsigned char *rp, un stm = fz_open_thunder(ctx, encstm, tiff->imagewidth); break; default: - stm = encstm; fz_throw(ctx, FZ_ERROR_GENERIC, "unknown TIFF compression: %d", tiff->compression); } @@ -393,6 +392,8 @@ tiff_decode_data(fz_context *ctx, struct tiff *tiff, const unsigned char *rp, un } fz_always(ctx) { + fz_drop_stream(ctx, jpegtables); + fz_drop_stream(ctx, encstm); fz_drop_stream(ctx, stm); fz_free(ctx, reversed); } diff --git a/source/fitz/stream-open.c b/source/fitz/stream-open.c index 813b7099..39994285 100644 --- a/source/fitz/stream-open.c +++ b/source/fitz/stream-open.c @@ -232,7 +232,7 @@ fz_open_memory(fz_context *ctx, const unsigned char *data, size_t len) { fz_stream *stm; - stm = fz_new_stream(ctx, NULL, next_buffer, drop_buffer); + stm = fz_new_stream(ctx, NULL, next_buffer, NULL); stm->seek = seek_buffer; stm->rp = (unsigned char *)data; diff --git a/source/gprf/gprf-doc.c b/source/gprf/gprf-doc.c index 2c508139..44e12ebc 100644 --- a/source/gprf/gprf-doc.c +++ b/source/gprf/gprf-doc.c @@ -353,8 +353,9 @@ gprf_get_pixmap(fz_context *ctx, fz_image *image_, fz_irect *area, int w, int h, unsigned char equiv[3 + FZ_MAX_SEPARATIONS][4]; int bytes_per_channel = image->super.w * image->super.h; unsigned char *out = fz_pixmap_samples(ctx, pix); + fz_stream *tmp_file = NULL; - fz_var(file); + fz_var(tmp_file); if (area) { @@ -404,9 +405,11 @@ gprf_get_pixmap(fz_context *ctx, fz_image *image_, fz_irect *area, int w, int h, read_sep[i] = 2; memset(&data[i * decode_chunk_size], 0, decode_chunk_size); } - file[i] = fz_open_file(ctx, image->file->filename); - fz_seek(ctx, file[i], image->offset[i], SEEK_SET); - file[i] = fz_open_flated(ctx, file[i], 15); + tmp_file = fz_open_file(ctx, image->file->filename); + fz_seek(ctx, tmp_file, image->offset[i], SEEK_SET); + file[i] = fz_open_flated(ctx, tmp_file, 15); + fz_drop_stream(ctx, tmp_file); + tmp_file = NULL; } /* Now actually do the decode */ @@ -463,6 +466,7 @@ gprf_get_pixmap(fz_context *ctx, fz_image *image_, fz_irect *area, int w, int h, } fz_always(ctx) { + fz_drop_stream(ctx, tmp_file); for (i = 0; i < 3+num_seps; i++) fz_drop_stream(ctx, file[i]); } diff --git a/source/pdf/pdf-crypt.c b/source/pdf/pdf-crypt.c index 2e31f356..1056b4fe 100644 --- a/source/pdf/pdf-crypt.c +++ b/source/pdf/pdf-crypt.c @@ -1023,7 +1023,7 @@ pdf_open_crypt_imp(fz_context *ctx, fz_stream *chain, pdf_crypt *crypt, pdf_cryp if (stmf->method == PDF_CRYPT_AESV2 || stmf->method == PDF_CRYPT_AESV3) return fz_open_aesd(ctx, chain, key, len); - return chain; + return fz_keep_stream(ctx, chain); } fz_stream * @@ -1035,27 +1035,13 @@ 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) { - 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) + if (!pdf_name_eq(ctx, name, PDF_NAME_Identity)) { - fz_drop_stream(ctx, chain); - fz_rethrow(ctx); + pdf_crypt_filter cf; + pdf_parse_crypt_filter(ctx, &cf, crypt, name); + return pdf_open_crypt_imp(ctx, chain, crypt, &cf, num, gen); } - - return chain; + return fz_keep_stream(ctx, chain); } void diff --git a/source/pdf/pdf-form.c b/source/pdf/pdf-form.c index f3d4e3c6..6c2e0434 100644 --- a/source/pdf/pdf-form.c +++ b/source/pdf/pdf-form.c @@ -1292,7 +1292,7 @@ fz_stream *pdf_signature_widget_hash_bytes(fz_context *ctx, pdf_document *doc, p pdf_signature_widget_byte_range(ctx, doc, widget, byte_range); } - bytes = fz_open_null_n(ctx, fz_keep_stream(ctx, doc->file), byte_range, byte_range_len); + bytes = fz_open_null_n(ctx, doc->file, byte_range, byte_range_len); } fz_always(ctx) { diff --git a/source/pdf/pdf-stream.c b/source/pdf/pdf-stream.c index 34ffe7af..379ed504 100644 --- a/source/pdf/pdf-stream.c +++ b/source/pdf/pdf-stream.c @@ -158,116 +158,93 @@ 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; - fz_var(chain); + if (params == NULL) + params = &local_params; - fz_try(ctx) - { - if (params == NULL) - params = &local_params; + build_compression_params(ctx, f, p, 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 fz_keep_stream(ctx, chain); /* nothing to do */ - /* 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 (params->type != FZ_IMAGE_RAW) + return fz_open_image_decomp_stream(ctx, chain, params, NULL); - 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_ASCIIHexDecode) || pdf_name_eq(ctx, f, PDF_NAME_AHx)) + return fz_open_ahxd(ctx, chain); - 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_ASCII85Decode) || pdf_name_eq(ctx, f, PDF_NAME_A85)) - { - tmp = chain; - chain = NULL; - chain = fz_open_a85d(ctx, tmp); - } + else if (pdf_name_eq(ctx, f, PDF_NAME_ASCII85Decode) || pdf_name_eq(ctx, f, PDF_NAME_A85)) + return fz_open_a85d(ctx, chain); - else if (pdf_name_eq(ctx, f, PDF_NAME_JBIG2Decode)) + 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 (obj) { - fz_jbig2_globals *globals = NULL; - pdf_obj *obj = pdf_dict_get(ctx, p, PDF_NAME_JBIG2Globals); - if (obj) - { - if (!pdf_is_stream(ctx, obj)) - fz_warn(ctx, "jbig2 globals is not a stream, skipping globals"); - else - globals = pdf_load_jbig2_globals(ctx, doc, obj); - } - tmp = chain; - chain = NULL; - chain = fz_open_jbig2d(ctx, tmp, globals); + if (!pdf_is_stream(ctx, obj)) + fz_warn(ctx, "jbig2 globals is not a stream, skipping globals"); + else + globals = pdf_load_jbig2_globals(ctx, doc, obj); } + return fz_open_jbig2d(ctx, chain, globals); /* takes ownership of jbig2_globals */ + } - else if (pdf_name_eq(ctx, f, PDF_NAME_JPXDecode)) - break; /* JPX decoding is special cased in the image loading code */ + else if (pdf_name_eq(ctx, f, PDF_NAME_JPXDecode)) + return fz_keep_stream(ctx, chain); /* JPX decoding is special cased in the image loading code */ - else if (pdf_name_eq(ctx, f, PDF_NAME_Crypt)) + else if (pdf_name_eq(ctx, f, PDF_NAME_Crypt)) + { + if (!doc->crypt) + fz_warn(ctx, "crypt filter in unencrypted document"); + else { - 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); - } - } + pdf_obj *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 - fz_warn(ctx, "unknown filter name (%s)", pdf_to_name(ctx, f)); } + + else + fz_warn(ctx, "unknown filter name (%s)", pdf_to_name(ctx, f)); + + return fz_keep_stream(ctx, chain); +} + +/* Build filter, and assume ownership of chain */ +static fz_stream * +build_filter_drop(fz_context *ctx, fz_stream *tail, pdf_document *doc, pdf_obj *f, pdf_obj *p, int num, int gen, fz_compression_params *params) +{ + fz_stream *head; + fz_try(ctx) + head = build_filter(ctx, tail, doc, f, p, num, gen, params); + fz_always(ctx) + fz_drop_stream(ctx, tail); fz_catch(ctx) - { - fz_drop_stream(ctx, chain); fz_rethrow(ctx); - } - - return chain; + return head; } /* * Build a chain of filters given filter names and param dicts. - * If head is given, start filter chain with it. - * Assume ownership of head. + * If chain is given, start filter chain with it. + * Assume ownership of chain. */ static fz_stream * -build_filter_chain(fz_context *ctx, fz_stream *chain, pdf_document *doc, pdf_obj *fs, pdf_obj *ps, int num, int gen, fz_compression_params *params) +build_filter_chain_drop(fz_context *ctx, fz_stream *chain, pdf_document *doc, pdf_obj *fs, pdf_obj *ps, int num, int gen, fz_compression_params *params) { - pdf_obj *f; - pdf_obj *p; - int i, n; - fz_var(chain); - fz_try(ctx) { - n = pdf_array_len(ctx, fs); + int i, n = pdf_array_len(ctx, fs); for (i = 0; i < n; i++) { - fz_stream *chain2; - - f = pdf_array_get(ctx, fs, i); - p = pdf_array_get(ctx, ps, i); - chain2 = chain; - chain = NULL; - chain = build_filter(ctx, chain2, doc, f, p, num, gen, (i == n-1 ? params : NULL)); + pdf_obj *f = pdf_array_get(ctx, fs, i); + pdf_obj *p = pdf_array_get(ctx, ps, i); + chain = build_filter_drop(ctx, chain, doc, f, p, num, gen, (i == n-1 ? params : NULL)); } } fz_catch(ctx) @@ -275,10 +252,15 @@ build_filter_chain(fz_context *ctx, fz_stream *chain, pdf_document *doc, pdf_obj fz_drop_stream(ctx, chain); fz_rethrow(ctx); } - return chain; } +static fz_stream * +build_filter_chain(fz_context *ctx, fz_stream *chain, pdf_document *doc, pdf_obj *fs, pdf_obj *ps, int num, int gen, fz_compression_params *params) +{ + return build_filter_chain_drop(ctx, fz_keep_stream(ctx, chain), doc, fs, ps, num, gen, params); +} + /* * Build a filter for reading raw stream data. * This is a null filter to constrain reading to the stream length (and to @@ -288,10 +270,10 @@ build_filter_chain(fz_context *ctx, fz_stream *chain, pdf_document *doc, pdf_obj * orig_num and orig_gen are used purely to seed the encryption. */ static fz_stream * -pdf_open_raw_filter(fz_context *ctx, fz_stream *chain, pdf_document *doc, pdf_obj *stmobj, int num, int *orig_num, int *orig_gen, int64_t offset) +pdf_open_raw_filter(fz_context *ctx, fz_stream *file_stm, pdf_document *doc, pdf_obj *stmobj, int num, int *orig_num, int *orig_gen, int64_t offset) { pdf_xref_entry *x = NULL; - fz_stream *chain2; + fz_stream *null_stm, *crypt_stm; int hascrypt; int len; @@ -311,33 +293,20 @@ pdf_open_raw_filter(fz_context *ctx, fz_stream *chain, pdf_document *doc, pdf_ob *orig_gen = 0; } - chain = fz_keep_stream(ctx, chain); - - fz_var(chain); - - fz_try(ctx) + hascrypt = pdf_stream_has_crypt(ctx, stmobj); + len = pdf_to_int(ctx, pdf_dict_get(ctx, stmobj, PDF_NAME_Length)); + null_stm = fz_open_null(ctx, file_stm, len, offset); + if (doc->crypt && !hascrypt) { - len = pdf_to_int(ctx, pdf_dict_get(ctx, stmobj, PDF_NAME_Length)); - - chain2 = chain; - chain = NULL; - chain = fz_open_null(ctx, chain2, len, offset); - - hascrypt = pdf_stream_has_crypt(ctx, stmobj); - if (doc->crypt && !hascrypt) - { - chain2 = chain; - chain = NULL; - chain = pdf_open_crypt(ctx, chain2, doc->crypt, *orig_num, *orig_gen); - } - } - fz_catch(ctx) - { - fz_drop_stream(ctx, chain); - fz_rethrow(ctx); + fz_try(ctx) + crypt_stm = pdf_open_crypt(ctx, null_stm, doc->crypt, *orig_num, *orig_gen); + fz_always(ctx) + fz_drop_stream(ctx, null_stm); + fz_catch(ctx) + fz_rethrow(ctx); + return crypt_stm; } - - return chain; + return null_stm; } /* @@ -345,41 +314,29 @@ pdf_open_raw_filter(fz_context *ctx, fz_stream *chain, pdf_document *doc, pdf_ob * to stream length and decrypting. */ static fz_stream * -pdf_open_filter(fz_context *ctx, pdf_document *doc, fz_stream *chain, pdf_obj *stmobj, int num, int64_t offset, fz_compression_params *imparams) +pdf_open_filter(fz_context *ctx, pdf_document *doc, fz_stream *file_stm, pdf_obj *stmobj, int num, int64_t offset, fz_compression_params *imparams) { - pdf_obj *filters; - pdf_obj *params; + pdf_obj *filters = pdf_dict_geta(ctx, stmobj, PDF_NAME_Filter, PDF_NAME_F); + pdf_obj *params = pdf_dict_geta(ctx, stmobj, PDF_NAME_DecodeParms, PDF_NAME_DP); int orig_num, orig_gen; + fz_stream *rstm, *fstm; - filters = pdf_dict_geta(ctx, stmobj, PDF_NAME_Filter, PDF_NAME_F); - params = pdf_dict_geta(ctx, stmobj, PDF_NAME_DecodeParms, PDF_NAME_DP); - - chain = pdf_open_raw_filter(ctx, chain, doc, stmobj, num, &orig_num, &orig_gen, offset); - - fz_var(chain); - + rstm = pdf_open_raw_filter(ctx, file_stm, doc, stmobj, num, &orig_num, &orig_gen, offset); fz_try(ctx) { if (pdf_is_name(ctx, filters)) - { - fz_stream *chain2 = chain; - chain = NULL; - chain = build_filter(ctx, chain2, doc, filters, params, orig_num, orig_gen, imparams); - } + fstm = build_filter(ctx, rstm, doc, filters, params, orig_num, orig_gen, imparams); else if (pdf_array_len(ctx, filters) > 0) - { - fz_stream *chain2 = chain; - chain = NULL; - chain = build_filter_chain(ctx, chain2, doc, filters, params, orig_num, orig_gen, imparams); - } + fstm = build_filter_chain(ctx, rstm, doc, filters, params, orig_num, orig_gen, imparams); + else + fstm = fz_keep_stream(ctx, rstm); } + fz_always(ctx) + fz_drop_stream(ctx, rstm); fz_catch(ctx) - { - fz_drop_stream(ctx, chain); fz_rethrow(ctx); - } - return chain; + return fstm; } /* @@ -387,54 +344,52 @@ pdf_open_filter(fz_context *ctx, pdf_document *doc, fz_stream *chain, pdf_obj *s * constraining to stream length, and without decryption. */ fz_stream * -pdf_open_inline_stream(fz_context *ctx, pdf_document *doc, pdf_obj *stmobj, int length, fz_stream *chain, fz_compression_params *imparams) +pdf_open_inline_stream(fz_context *ctx, pdf_document *doc, pdf_obj *stmobj, int length, fz_stream *file_stm, fz_compression_params *imparams) { - pdf_obj *filters; - pdf_obj *params; - int64_t offset; - - filters = pdf_dict_geta(ctx, stmobj, PDF_NAME_Filter, PDF_NAME_F); - params = pdf_dict_geta(ctx, stmobj, PDF_NAME_DecodeParms, PDF_NAME_DP); - - /* don't close chain when we close this filter */ - fz_keep_stream(ctx, chain); + pdf_obj *filters = pdf_dict_geta(ctx, stmobj, PDF_NAME_Filter, PDF_NAME_F); + pdf_obj *params = pdf_dict_geta(ctx, stmobj, PDF_NAME_DecodeParms, PDF_NAME_DP); if (pdf_is_name(ctx, filters)) - return build_filter(ctx, chain, doc, filters, params, 0, 0, imparams); - if (pdf_array_len(ctx, filters) > 0) - return build_filter_chain(ctx, chain, doc, filters, params, 0, 0, imparams); + return build_filter(ctx, file_stm, doc, filters, params, 0, 0, imparams); + else if (pdf_array_len(ctx, filters) > 0) + return build_filter_chain(ctx, file_stm, doc, filters, params, 0, 0, imparams); if (imparams) imparams->type = FZ_IMAGE_RAW; - - fz_try(ctx) - offset = fz_tell(ctx, chain); - fz_catch(ctx) - { - fz_drop_stream(ctx, chain); - fz_rethrow(ctx); - } - - return fz_open_null(ctx, chain, length, offset); + return fz_open_null(ctx, file_stm, length, fz_tell(ctx, file_stm)); } void -pdf_load_compressed_inline_image(fz_context *ctx, pdf_document *doc, pdf_obj *dict, int length, fz_stream *stm, int indexed, fz_compressed_image *image) +pdf_load_compressed_inline_image(fz_context *ctx, pdf_document *doc, pdf_obj *dict, int length, fz_stream *file_stm, int indexed, fz_compressed_image *image) { - fz_compressed_buffer *bc = fz_malloc_struct(ctx, fz_compressed_buffer); + fz_stream *istm, *leech, *decomp; + fz_pixmap *pixmap; + fz_compressed_buffer *bc; + int dummy_l2factor = 0; + fz_var(istm); + fz_var(leech); + fz_var(decomp); + fz_var(pixmap); + + bc = fz_malloc_struct(ctx, fz_compressed_buffer); fz_try(ctx) { - int dummy_l2factor = 0; bc->buffer = fz_new_buffer(ctx, 1024); - - stm = pdf_open_inline_stream(ctx, doc, dict, length, stm, &bc->params); - stm = fz_open_leecher(ctx, stm, bc->buffer); - stm = fz_open_image_decomp_stream(ctx, stm, &bc->params, &dummy_l2factor); - - fz_set_compressed_image_tile(ctx, image, fz_decomp_image_from_stream(ctx, stm, image, NULL, indexed, 0)); + istm = pdf_open_inline_stream(ctx, doc, dict, length, file_stm, &bc->params); + leech = fz_open_leecher(ctx, istm, bc->buffer); + decomp = fz_open_image_decomp_stream(ctx, leech, &bc->params, &dummy_l2factor); + pixmap = fz_decomp_image_from_stream(ctx, leech, image, NULL, indexed, 0); + fz_set_compressed_image_tile(ctx, image, pixmap); fz_set_compressed_image_buffer(ctx, image, bc); } + fz_always(ctx) + { + fz_drop_stream(ctx, istm); + fz_drop_stream(ctx, leech); + fz_drop_stream(ctx, decomp); + fz_drop_pixmap(ctx, pixmap); + } fz_catch(ctx) { fz_drop_compressed_buffer(ctx, bc); -- cgit v1.2.3