diff options
author | Dan Fandrich <dan@coneharvesters.com> | 2010-06-17 21:39:44 -0700 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-06-18 13:32:39 +0200 |
commit | b76f18d331f865225f1702794e66e87818584f99 (patch) | |
tree | 62c935bc2db0fd5af12fae2e3e060924a900e484 | |
parent | eafc6956f6fa86cb7d4bf488e96eeee34c551819 (diff) |
Improve unzip's handling of stream ZIP files
Search harder for the ZIP magic numbers at the end of a file by checking
16 KiB from the end instead of just 1 KiB. ZIP files with long comments
(such as certain cryptographically signed files) or those sitting in a
wrapper could have more than 1 KiB of data after the magic numbers, so
they couldn't be read.
Signed-off-by: Dan Fandrich <dan@coneharvesters.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | archival/unzip.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/archival/unzip.c b/archival/unzip.c index 1d3291ab8..84081c021 100644 --- a/archival/unzip.c +++ b/archival/unzip.c @@ -150,23 +150,26 @@ enum { zip_fd = 3 }; #if ENABLE_DESKTOP + +#define PEEK_FROM_END 16384 + /* NB: does not preserve file position! */ static uint32_t find_cdf_offset(void) { - unsigned char buf[1024]; cde_header_t cde_header; unsigned char *p; off_t end; + unsigned char *buf = xzalloc(PEEK_FROM_END); end = xlseek(zip_fd, 0, SEEK_END); - end -= 1024; + end -= PEEK_FROM_END; if (end < 0) end = 0; xlseek(zip_fd, end, SEEK_SET); - full_read(zip_fd, buf, 1024); + full_read(zip_fd, buf, PEEK_FROM_END); p = buf; - while (p <= buf + 1024 - CDE_HEADER_LEN - 4) { + while (p <= buf + PEEK_FROM_END - CDE_HEADER_LEN - 4) { if (*p != 'P') { p++; continue; @@ -180,8 +183,10 @@ static uint32_t find_cdf_offset(void) /* we found CDE! */ memcpy(cde_header.raw, p + 1, CDE_HEADER_LEN); FIX_ENDIANNESS_CDE(cde_header); + free(buf); return cde_header.formatted.cdf_offset; } + //free(buf); bb_error_msg_and_die("can't find file table"); }; |