summaryrefslogtreecommitdiff
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
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.
-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);