From b1542d7c2f33a4412606c013a5ba6ce0ad31c034 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20B=C3=BCnzli?= Date: Tue, 28 Oct 2014 14:51:34 +0100 Subject: fix memory leaks in load_sample_func and pdf_load_compressed_inline_image In load_sample_func, the stream is not closed and thus leaked if one of the fz_read_byte or fz_read_bits calls throws (which might happen e.g. on a Deflate data error). In pdf_load_compressed_inline_image, the allocated buffer is not freed if one of the stream initializers or the tile creation throws (fz_open_leecher does not take ownership of the stream). --- source/pdf/pdf-function.c | 91 +++++++++++++++++++++++++---------------------- source/pdf/pdf-stream.c | 2 +- 2 files changed, 50 insertions(+), 43 deletions(-) diff --git a/source/pdf/pdf-function.c b/source/pdf/pdf-function.c index a8faae32..b94e508a 100644 --- a/source/pdf/pdf-function.c +++ b/source/pdf/pdf-function.c @@ -918,6 +918,8 @@ load_sample_func(pdf_function *func, pdf_document *doc, pdf_obj *dict, int num, int bps; int i; + fz_var(stream); + func->u.sa.samples = NULL; obj = pdf_dict_gets(dict, "Size"); @@ -988,52 +990,57 @@ load_sample_func(pdf_function *func, pdf_document *doc, pdf_obj *dict, int num, stream = pdf_open_stream(doc, num, gen); - /* read samples */ - for (i = 0; i < samplecount; i++) + fz_try(ctx) { - unsigned int x; - float s; - - if (fz_is_eof_bits(stream)) - { - fz_close(stream); - fz_throw(ctx, FZ_ERROR_GENERIC, "truncated sample function stream"); - } - - switch (bps) + /* read samples */ + for (i = 0; i < samplecount; i++) { - case 1: s = fz_read_bits(stream, 1); break; - case 2: s = fz_read_bits(stream, 2) / 3.0f; break; - case 4: s = fz_read_bits(stream, 4) / 15.0f; break; - case 8: s = fz_read_byte(stream) / 255.0f; break; - case 12: s = fz_read_bits(stream, 12) / 4095.0f; break; - case 16: - x = fz_read_byte(stream) << 8; - x |= fz_read_byte(stream); - s = x / 65535.0f; - break; - case 24: - x = fz_read_byte(stream) << 16; - x |= fz_read_byte(stream) << 8; - x |= fz_read_byte(stream); - s = x / 16777215.0f; - break; - case 32: - x = fz_read_byte(stream) << 24; - x |= fz_read_byte(stream) << 16; - x |= fz_read_byte(stream) << 8; - x |= fz_read_byte(stream); - s = x / 4294967295.0f; - break; - default: - fz_close(stream); - fz_throw(ctx, FZ_ERROR_GENERIC, "sample stream bit depth %d unsupported", bps); + unsigned int x; + float s; + + if (fz_is_eof_bits(stream)) + fz_throw(ctx, FZ_ERROR_GENERIC, "truncated sample function stream"); + + switch (bps) + { + case 1: s = fz_read_bits(stream, 1); break; + case 2: s = fz_read_bits(stream, 2) / 3.0f; break; + case 4: s = fz_read_bits(stream, 4) / 15.0f; break; + case 8: s = fz_read_byte(stream) / 255.0f; break; + case 12: s = fz_read_bits(stream, 12) / 4095.0f; break; + case 16: + x = fz_read_byte(stream) << 8; + x |= fz_read_byte(stream); + s = x / 65535.0f; + break; + case 24: + x = fz_read_byte(stream) << 16; + x |= fz_read_byte(stream) << 8; + x |= fz_read_byte(stream); + s = x / 16777215.0f; + break; + case 32: + x = fz_read_byte(stream) << 24; + x |= fz_read_byte(stream) << 16; + x |= fz_read_byte(stream) << 8; + x |= fz_read_byte(stream); + s = x / 4294967295.0f; + break; + default: + fz_throw(ctx, FZ_ERROR_GENERIC, "sample stream bit depth %d unsupported", bps); + } + + func->u.sa.samples[i] = s; } - - func->u.sa.samples[i] = s; } - - fz_close(stream); + fz_always(ctx) + { + fz_close(stream); + } + fz_catch(ctx) + { + fz_rethrow(ctx); + } } static float diff --git a/source/pdf/pdf-stream.c b/source/pdf/pdf-stream.c index 930c30cb..1b5cd79c 100644 --- a/source/pdf/pdf-stream.c +++ b/source/pdf/pdf-stream.c @@ -385,7 +385,7 @@ pdf_load_compressed_inline_image(pdf_document *doc, pdf_obj *dict, int length, f } fz_catch(ctx) { - fz_free(ctx, bc); + fz_free_compressed_buffer(ctx, bc); fz_rethrow(ctx); } image->buffer = bc; -- cgit v1.2.3