aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--archival/unzip.c22
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 {
82 ZIP_FILEHEADER_MAGIC = 0x504b0304, 82 ZIP_FILEHEADER_MAGIC = 0x504b0304,
83 ZIP_CDF_MAGIC = 0x504b0102, /* CDF item */ 83 ZIP_CDF_MAGIC = 0x504b0102, /* CDF item */
84 ZIP_CDE_MAGIC = 0x504b0506, /* End of CDF */ 84 ZIP_CDE_MAGIC = 0x504b0506, /* End of CDF */
85 ZIP64_CDE_MAGIC = 0x504b0606, /* End of Zip64 CDF */
85 ZIP_DD_MAGIC = 0x504b0708, 86 ZIP_DD_MAGIC = 0x504b0708,
86#else 87#else
87 ZIP_FILEHEADER_MAGIC = 0x04034b50, 88 ZIP_FILEHEADER_MAGIC = 0x04034b50,
88 ZIP_CDF_MAGIC = 0x02014b50, 89 ZIP_CDF_MAGIC = 0x02014b50,
89 ZIP_CDE_MAGIC = 0x06054b50, 90 ZIP_CDE_MAGIC = 0x06054b50,
91 ZIP64_CDE_MAGIC = 0x06064b50,
90 ZIP_DD_MAGIC = 0x08074b50, 92 ZIP_DD_MAGIC = 0x08074b50,
91#endif 93#endif
92}; 94};
@@ -260,6 +262,12 @@ static uint32_t find_cdf_offset(void)
260 continue; 262 continue;
261 /* we found CDE! */ 263 /* we found CDE! */
262 memcpy(cde.raw, p + 1, CDE_LEN); 264 memcpy(cde.raw, p + 1, CDE_LEN);
265 dbg("cde.this_disk_no:%d", cde.fmt.this_disk_no );
266 dbg("cde.disk_with_cdf_no:%d", cde.fmt.disk_with_cdf_no );
267 dbg("cde.cdf_entries_on_this_disk:%d", cde.fmt.cdf_entries_on_this_disk);
268 dbg("cde.cdf_entries_total:%d", cde.fmt.cdf_entries_total );
269 dbg("cde.cdf_size:%d", cde.fmt.cdf_size );
270 dbg("cde.cdf_offset:%x", cde.fmt.cdf_offset );
263 FIX_ENDIANNESS_CDE(cde); 271 FIX_ENDIANNESS_CDE(cde);
264 /* 272 /*
265 * I've seen .ZIP files with seemingly valid CDEs 273 * 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)
302 dbg("got ZIP_CDE_MAGIC"); 310 dbg("got ZIP_CDE_MAGIC");
303 return 0; /* EOF */ 311 return 0; /* EOF */
304 } 312 }
313 if (magic == ZIP64_CDE_MAGIC) { /* seen in .zip with >4GB files */
314 dbg("got ZIP64_CDE_MAGIC");
315 return 0; /* EOF */
316 }
305 xread(zip_fd, cdf->raw, CDF_HEADER_LEN); 317 xread(zip_fd, cdf->raw, CDF_HEADER_LEN);
306 318
307 FIX_ENDIANNESS_CDF(*cdf); 319 FIX_ENDIANNESS_CDF(*cdf);
308 dbg(" filename_len:%u extra_len:%u file_comment_length:%u", 320 dbg(" magic:%08x filename_len:%u extra_len:%u file_comment_length:%u",
321 magic,
309 (unsigned)cdf->fmt.filename_len, 322 (unsigned)cdf->fmt.filename_len,
310 (unsigned)cdf->fmt.extra_len, 323 (unsigned)cdf->fmt.extra_len,
311 (unsigned)cdf->fmt.file_comment_length 324 (unsigned)cdf->fmt.file_comment_length
312 ); 325 );
326//TODO: require that magic == ZIP_CDF_MAGIC?
327
313 cdf_offset += 4 + CDF_HEADER_LEN 328 cdf_offset += 4 + CDF_HEADER_LEN
314 + cdf->fmt.filename_len 329 + cdf->fmt.filename_len
315 + cdf->fmt.extra_len 330 + cdf->fmt.extra_len
316 + cdf->fmt.file_comment_length; 331 + cdf->fmt.file_comment_length;
317 332
333 dbg("Next cdf_offset 0x%x", cdf_offset);
318 return cdf_offset; 334 return cdf_offset;
319}; 335};
320#endif 336#endif
@@ -436,7 +452,9 @@ static void unzip_extract(zip_header_t *zip, int dst_fd)
436 } 452 }
437 453
438 /* Validate decompression - size */ 454 /* Validate decompression - size */
439 if (zip->fmt.ucmpsize != xstate.bytes_out) { 455 if (zip->fmt.ucmpsize != 0xffffffff /* seen on files with >4GB uncompressed data */
456 && zip->fmt.ucmpsize != xstate.bytes_out
457 ) {
440 /* Don't die. Who knows, maybe len calculation 458 /* Don't die. Who knows, maybe len calculation
441 * was botched somewhere. After all, crc matched! */ 459 * was botched somewhere. After all, crc matched! */
442 bb_simple_error_msg("bad length"); 460 bb_simple_error_msg("bad length");