diff options
-rw-r--r-- | archival/unzip.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/archival/unzip.c b/archival/unzip.c index d94bbabcf..12db4e579 100644 --- a/archival/unzip.c +++ b/archival/unzip.c @@ -82,11 +82,13 @@ enum { ZIP_FILEHEADER_MAGIC = 0x504b0304, ZIP_CDF_MAGIC = 0x504b0102, /* CDF item */ ZIP_CDE_MAGIC = 0x504b0506, /* End of CDF */ + ZIP64_CDE_MAGIC = 0x504b0606, /* End of Zip64 CDF */ ZIP_DD_MAGIC = 0x504b0708, #else ZIP_FILEHEADER_MAGIC = 0x04034b50, ZIP_CDF_MAGIC = 0x02014b50, ZIP_CDE_MAGIC = 0x06054b50, + ZIP64_CDE_MAGIC = 0x06064b50, ZIP_DD_MAGIC = 0x08074b50, #endif }; @@ -260,6 +262,12 @@ static uint32_t find_cdf_offset(void) continue; /* we found CDE! */ memcpy(cde.raw, p + 1, CDE_LEN); + dbg("cde.this_disk_no:%d", cde.fmt.this_disk_no ); + dbg("cde.disk_with_cdf_no:%d", cde.fmt.disk_with_cdf_no ); + dbg("cde.cdf_entries_on_this_disk:%d", cde.fmt.cdf_entries_on_this_disk); + dbg("cde.cdf_entries_total:%d", cde.fmt.cdf_entries_total ); + dbg("cde.cdf_size:%d", cde.fmt.cdf_size ); + dbg("cde.cdf_offset:%x", cde.fmt.cdf_offset ); FIX_ENDIANNESS_CDE(cde); /* * I've seen .ZIP files with seemingly valid CDEs @@ -302,19 +310,27 @@ static uint32_t read_next_cdf(uint32_t cdf_offset, cdf_header_t *cdf) dbg("got ZIP_CDE_MAGIC"); return 0; /* EOF */ } + if (magic == ZIP64_CDE_MAGIC) { /* seen in .zip with >4GB files */ + dbg("got ZIP64_CDE_MAGIC"); + return 0; /* EOF */ + } xread(zip_fd, cdf->raw, CDF_HEADER_LEN); FIX_ENDIANNESS_CDF(*cdf); - dbg(" filename_len:%u extra_len:%u file_comment_length:%u", + dbg(" magic:%08x filename_len:%u extra_len:%u file_comment_length:%u", + magic, (unsigned)cdf->fmt.filename_len, (unsigned)cdf->fmt.extra_len, (unsigned)cdf->fmt.file_comment_length ); +//TODO: require that magic == ZIP_CDF_MAGIC? + cdf_offset += 4 + CDF_HEADER_LEN + cdf->fmt.filename_len + cdf->fmt.extra_len + cdf->fmt.file_comment_length; + dbg("Next cdf_offset 0x%x", cdf_offset); return cdf_offset; }; #endif @@ -436,7 +452,9 @@ static void unzip_extract(zip_header_t *zip, int dst_fd) } /* Validate decompression - size */ - if (zip->fmt.ucmpsize != xstate.bytes_out) { + if (zip->fmt.ucmpsize != 0xffffffff /* seen on files with >4GB uncompressed data */ + && zip->fmt.ucmpsize != xstate.bytes_out + ) { /* Don't die. Who knows, maybe len calculation * was botched somewhere. After all, crc matched! */ bb_simple_error_msg("bad length"); |