summaryrefslogtreecommitdiff
path: root/source/fitz/unzip.c
diff options
context:
space:
mode:
authorSebastian Rasmussen <sebras@gmail.com>2016-08-17 10:08:19 +0800
committerSebastian Rasmussen <sebras@gmail.com>2016-08-17 22:43:02 +0800
commit7f2c725945ac3da1202c6736fa2cdf6f74c2413c (patch)
tree6e6a60075df1e2cc2c3f989f76c80417758df220 /source/fitz/unzip.c
parent81037acb5af79a3da72729ed479f2496cac1e875 (diff)
downloadmupdf-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.
Diffstat (limited to 'source/fitz/unzip.c')
-rw-r--r--source/fitz/unzip.c11
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)
{