summaryrefslogtreecommitdiff
path: root/source/pdf/pdf-function.c
diff options
context:
space:
mode:
authorSimon Bünzli <zeniko@gmail.com>2014-10-28 14:51:34 +0100
committerSimon Bünzli <zeniko@gmail.com>2014-10-28 15:45:03 +0100
commitb1542d7c2f33a4412606c013a5ba6ce0ad31c034 (patch)
tree9078fec12f117b289949f902bb03e4fd36b06be7 /source/pdf/pdf-function.c
parent362d23df9f6151446419757d48a53ff33b67cf2f (diff)
downloadmupdf-b1542d7c2f33a4412606c013a5ba6ce0ad31c034.tar.xz
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).
Diffstat (limited to 'source/pdf/pdf-function.c')
-rw-r--r--source/pdf/pdf-function.c91
1 files changed, 49 insertions, 42 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