summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorSebastian Rasmussen <sebras@gmail.com>2018-07-31 03:31:06 +0800
committerSebastian Rasmussen <sebras@gmail.com>2018-08-30 21:11:41 +0800
commit984887ee8fb431e5c5d243c40dcb73d5149b033f (patch)
treeb70ce55f4be537c7cbb1506f6752d7449ba24412 /source
parent7ae91795c6830d0a8e708746193d2fb1243a0deb (diff)
downloadmupdf-984887ee8fb431e5c5d243c40dcb73d5149b033f.tar.xz
Bug 699694: Fix reference counting for JBIG2 globals.
fz_open_jbig2d() is called at two locations in MuPDF. At one location a reference to the JBIG2 globals struct was taken before passing it to fz_open_jbig2d(). At the other location no such reference was taken, but rather ownership of the struct was implicitly transferred to fz_open_jbig2d(). This inconsistency led to a leak of the globals struct at the first location. Now, passing a JBIG2 globals struct to fz_open_jbig2d() never implictly takes ownership. Instead the JBIG2 stream will take a reference if it needs it and drops it in case of error. As usual it is the callers responsibility to drop the reference to the globals struct it owns.
Diffstat (limited to 'source')
-rw-r--r--source/fitz/compressed-buffer.c2
-rw-r--r--source/fitz/filter-jbig2.c45
-rw-r--r--source/pdf/pdf-stream.c13
3 files changed, 26 insertions, 34 deletions
diff --git a/source/fitz/compressed-buffer.c b/source/fitz/compressed-buffer.c
index 35b0868b..9a4f5c23 100644
--- a/source/fitz/compressed-buffer.c
+++ b/source/fitz/compressed-buffer.c
@@ -69,7 +69,7 @@ fz_open_image_decomp_stream(fz_context *ctx, fz_stream *tail, fz_compression_par
break;
case FZ_IMAGE_JBIG2:
- head = fz_open_jbig2d(ctx, tail, fz_keep_jbig2_globals(ctx, params->u.jbig2.globals));
+ head = fz_open_jbig2d(ctx, tail, params->u.jbig2.globals);
break;
case FZ_IMAGE_RLD:
diff --git a/source/fitz/filter-jbig2.c b/source/fitz/filter-jbig2.c
index e984b6cf..7fadc02b 100644
--- a/source/fitz/filter-jbig2.c
+++ b/source/fitz/filter-jbig2.c
@@ -226,16 +226,9 @@ fz_open_jbig2d(fz_context *ctx, fz_stream *chain, fz_jbig2_globals *globals)
{
fz_jbig2d *state = NULL;
- fz_try(ctx)
- state = fz_malloc_struct(ctx, fz_jbig2d);
- fz_catch(ctx)
- {
- fz_drop_jbig2_globals(ctx, globals);
- fz_rethrow(ctx);
- }
-
+ state = fz_malloc_struct(ctx, fz_jbig2d);
state->ctx = ctx;
- state->gctx = globals;
+ state->gctx = fz_keep_jbig2_globals(ctx, globals);
state->chain = fz_keep_stream(ctx, chain);
state->idx = 0;
state->output = NULL;
@@ -416,30 +409,16 @@ fz_open_jbig2d(fz_context *ctx, fz_stream *chain, fz_jbig2_globals *globals)
fz_var(state);
- fz_try(ctx)
- {
- state = fz_malloc_struct(ctx, fz_jbig2d);
- state->gctx = globals;
- state->alloc.ctx = ctx;
- state->alloc.alloc.alloc = fz_jbig2_alloc;
- state->alloc.alloc.free = fz_jbig2_free;
- state->alloc.alloc.realloc = fz_jbig2_realloc;
- 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)
- {
- if (state)
- {
- fz_drop_jbig2_globals(ctx, state->gctx);
- if (state->ctx)
- jbig2_ctx_free(state->ctx);
- }
- fz_free(ctx, state);
- fz_rethrow(ctx);
- }
+ state = fz_malloc_struct(ctx, fz_jbig2d);
+ state->gctx = fz_keep_jbig2_globals(ctx, globals);
+ state->alloc.ctx = ctx;
+ state->alloc.alloc.alloc = fz_jbig2_alloc;
+ state->alloc.alloc.free = fz_jbig2_free;
+ state->alloc.alloc.realloc = fz_jbig2_realloc;
+ 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);
return fz_new_stream(ctx, state, next_jbig2d, close_jbig2d);
}
diff --git a/source/pdf/pdf-stream.c b/source/pdf/pdf-stream.c
index f52539cf..29301f5d 100644
--- a/source/pdf/pdf-stream.c
+++ b/source/pdf/pdf-stream.c
@@ -173,6 +173,7 @@ build_filter(fz_context *ctx, fz_stream *chain, pdf_document *doc, pdf_obj *f, p
{
fz_compression_params local_params;
+ local_params.u.jbig2.globals = NULL;
if (params == NULL)
params = &local_params;
@@ -184,6 +185,18 @@ build_filter(fz_context *ctx, fz_stream *chain, pdf_document *doc, pdf_obj *f, p
if (params != &local_params && params->type != FZ_IMAGE_RAW)
return fz_keep_stream(ctx, chain); /* nothing to do */
+ else if (params->type == FZ_IMAGE_JBIG2)
+ {
+ fz_stream *stm;
+ fz_try(ctx)
+ stm = fz_open_image_decomp_stream(ctx, chain, params, NULL);
+ fz_always(ctx)
+ fz_drop_jbig2_globals(ctx, local_params.u.jbig2.globals);
+ fz_catch(ctx)
+ fz_rethrow(ctx);
+ return stm;
+ }
+
else if (params->type != FZ_IMAGE_RAW)
return fz_open_image_decomp_stream(ctx, chain, params, NULL);