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>
This commit is contained in:
parent
eafc6956f6
commit
b76f18d331
@ -150,23 +150,26 @@ enum { zip_fd = 3 };
|
|||||||
|
|
||||||
|
|
||||||
#if ENABLE_DESKTOP
|
#if ENABLE_DESKTOP
|
||||||
|
|
||||||
|
#define PEEK_FROM_END 16384
|
||||||
|
|
||||||
/* NB: does not preserve file position! */
|
/* NB: does not preserve file position! */
|
||||||
static uint32_t find_cdf_offset(void)
|
static uint32_t find_cdf_offset(void)
|
||||||
{
|
{
|
||||||
unsigned char buf[1024];
|
|
||||||
cde_header_t cde_header;
|
cde_header_t cde_header;
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
off_t end;
|
off_t end;
|
||||||
|
unsigned char *buf = xzalloc(PEEK_FROM_END);
|
||||||
|
|
||||||
end = xlseek(zip_fd, 0, SEEK_END);
|
end = xlseek(zip_fd, 0, SEEK_END);
|
||||||
end -= 1024;
|
end -= PEEK_FROM_END;
|
||||||
if (end < 0)
|
if (end < 0)
|
||||||
end = 0;
|
end = 0;
|
||||||
xlseek(zip_fd, end, SEEK_SET);
|
xlseek(zip_fd, end, SEEK_SET);
|
||||||
full_read(zip_fd, buf, 1024);
|
full_read(zip_fd, buf, PEEK_FROM_END);
|
||||||
|
|
||||||
p = buf;
|
p = buf;
|
||||||
while (p <= buf + 1024 - CDE_HEADER_LEN - 4) {
|
while (p <= buf + PEEK_FROM_END - CDE_HEADER_LEN - 4) {
|
||||||
if (*p != 'P') {
|
if (*p != 'P') {
|
||||||
p++;
|
p++;
|
||||||
continue;
|
continue;
|
||||||
@ -180,8 +183,10 @@ static uint32_t find_cdf_offset(void)
|
|||||||
/* we found CDE! */
|
/* we found CDE! */
|
||||||
memcpy(cde_header.raw, p + 1, CDE_HEADER_LEN);
|
memcpy(cde_header.raw, p + 1, CDE_HEADER_LEN);
|
||||||
FIX_ENDIANNESS_CDE(cde_header);
|
FIX_ENDIANNESS_CDE(cde_header);
|
||||||
|
free(buf);
|
||||||
return cde_header.formatted.cdf_offset;
|
return cde_header.formatted.cdf_offset;
|
||||||
}
|
}
|
||||||
|
//free(buf);
|
||||||
bb_error_msg_and_die("can't find file table");
|
bb_error_msg_and_die("can't find file table");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user