diff options
author | Sebastian Rasmussen <sebras@gmail.com> | 2016-08-17 10:08:19 +0800 |
---|---|---|
committer | Sebastian Rasmussen <sebras@gmail.com> | 2016-08-17 22:43:02 +0800 |
commit | 7f2c725945ac3da1202c6736fa2cdf6f74c2413c (patch) | |
tree | 6e6a60075df1e2cc2c3f989f76c80417758df220 | |
parent | 81037acb5af79a3da72729ed479f2496cac1e875 (diff) | |
download | mupdf-7f2c725945ac3da1202c6736fa2cdf6f74c2413c.tar.xz |
zip: Used unpacked entry size, not listed entry size.
The size listed in the central directory can be used to allocate an
output buffer and inflate can be told to not write more than this
number of bytes. The listed size cannot be assumed to be the size
of the output data however as the zip file may be corrupted. Instead
the size of the output data must be given by inflate and must be
less than or equal to the listed size.
The same reasoning goes for uncompressed entries and simply reading
the uncompressed data from the archive file (which may terminate
early).
Fixes indeterminism broken_png_image.xps.
-rw-r--r-- | source/fitz/unzip.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/source/fitz/unzip.c b/source/fitz/unzip.c index 929c1d5a..1d386209 100644 --- a/source/fitz/unzip.c +++ b/source/fitz/unzip.c @@ -292,6 +292,7 @@ static fz_buffer *read_zip_entry(fz_context *ctx, fz_archive *zip, struct zip_en int method; z_stream z; int code; + int len; method = read_zip_entry_header(ctx, zip, ent); @@ -302,7 +303,10 @@ static fz_buffer *read_zip_entry(fz_context *ctx, fz_archive *zip, struct zip_en { fz_try(ctx) { - fz_read(ctx, file, ubuf->data, ent->usize); + len = fz_read(ctx, file, ubuf->data, ubuf->len); + if (len < ubuf->len) + fz_warn(ctx, "premature end of data in stored archive entry"); + ubuf->len = len; } fz_catch(ctx) { @@ -343,6 +347,11 @@ static fz_buffer *read_zip_entry(fz_context *ctx, fz_archive *zip, struct zip_en { fz_throw(ctx, FZ_ERROR_GENERIC, "zlib inflateEnd error: %s", z.msg); } + + len = ent->usize - z.avail_out; + if (len < ubuf->len) + fz_warn(ctx, "premature end of data in compressed archive entry"); + ubuf->len = len; } fz_always(ctx) { |