summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorkientzle <kientzle@FreeBSD.org>2009-03-06 04:50:39 +0000
committerkientzle <kientzle@FreeBSD.org>2009-03-06 04:50:39 +0000
commit409cc977f6064716e39b1fec8562cb8aaab07e48 (patch)
tree121e15a94ddfcf8ce362b1908b6ba2c3bdc71ce2 /lib
parent559aad6489401705ac2b4f98ca4fbe15b69908e4 (diff)
downloadFreeBSD-src-409cc977f6064716e39b1fec8562cb8aaab07e48.zip
FreeBSD-src-409cc977f6064716e39b1fec8562cb8aaab07e48.tar.gz
Merge r407,r508 from libarchive.googlecode.com: Correctly handle
Zip entries that are zero length but stored with deflate. This is arguably a silly thing to do (deflating a zero-length file actually makes it bigger) but apparently quite a few Zip writers do this. This was broken in two places: archive_write_disk disliked being asked to write data to zero-length files (even if the write was zero-length) and zip_read_file_header tripped over itself when non-regular files had compressed bodies.
Diffstat (limited to 'lib')
-rw-r--r--lib/libarchive/archive_read_support_format_zip.c85
-rw-r--r--lib/libarchive/archive_write_disk.c3
2 files changed, 44 insertions, 44 deletions
diff --git a/lib/libarchive/archive_read_support_format_zip.c b/lib/libarchive/archive_read_support_format_zip.c
index a86c533..aead1c4 100644
--- a/lib/libarchive/archive_read_support_format_zip.c
+++ b/lib/libarchive/archive_read_support_format_zip.c
@@ -75,7 +75,6 @@ struct zip {
/* Flags to mark progress of decompression. */
char decompress_init;
char end_of_entry;
- char end_of_entry_cleanup;
unsigned long crc32;
ssize_t filename_length;
@@ -298,7 +297,6 @@ archive_read_format_zip_read_header(struct archive_read *a,
zip = (struct zip *)(a->format->data);
zip->decompress_init = 0;
zip->end_of_entry = 0;
- zip->end_of_entry_cleanup = 0;
zip->entry_uncompressed_bytes_read = 0;
zip->entry_compressed_bytes_read = 0;
zip->entry_crc32 = crc32(0, NULL, 0);
@@ -373,7 +371,7 @@ archive_read_format_zip_read_header(struct archive_read *a,
return (ARCHIVE_FATAL);
}
-int
+static int
zip_read_file_header(struct archive_read *a, struct archive_entry *entry,
struct zip *zip)
{
@@ -499,45 +497,6 @@ archive_read_format_zip_read_data(struct archive_read *a,
* ARCHIVE_EOF this time.
*/
if (zip->end_of_entry) {
- if (!zip->end_of_entry_cleanup) {
- if (zip->flags & ZIP_LENGTH_AT_END) {
- const char *p;
-
- if ((p = __archive_read_ahead(a, 16, NULL)) == NULL) {
- archive_set_error(&a->archive,
- ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated ZIP end-of-file record");
- return (ARCHIVE_FATAL);
- }
- zip->crc32 = archive_le32dec(p + 4);
- zip->compressed_size = archive_le32dec(p + 8);
- zip->uncompressed_size = archive_le32dec(p + 12);
- __archive_read_consume(a, 16);
- }
-
- /* Check file size, CRC against these values. */
- if (zip->compressed_size != zip->entry_compressed_bytes_read) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "ZIP compressed data is wrong size");
- return (ARCHIVE_WARN);
- }
- /* Size field only stores the lower 32 bits of the actual size. */
- if ((zip->uncompressed_size & UINT32_MAX)
- != (zip->entry_uncompressed_bytes_read & UINT32_MAX)) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "ZIP uncompressed data is wrong size");
- return (ARCHIVE_WARN);
- }
- /* Check computed CRC against header */
- if (zip->crc32 != zip->entry_crc32) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "ZIP bad CRC: 0x%lx should be 0x%lx",
- zip->entry_crc32, zip->crc32);
- return (ARCHIVE_WARN);
- }
- /* End-of-entry cleanup done. */
- zip->end_of_entry_cleanup = 1;
- }
*offset = zip->entry_uncompressed_bytes_read;
*size = 0;
*buff = NULL;
@@ -580,6 +539,44 @@ archive_read_format_zip_read_data(struct archive_read *a,
if (*size)
zip->entry_crc32 =
crc32(zip->entry_crc32, *buff, *size);
+ /* If we hit the end, swallow any end-of-data marker. */
+ if (zip->end_of_entry) {
+ if (zip->flags & ZIP_LENGTH_AT_END) {
+ const char *p;
+
+ if ((p = __archive_read_ahead(a, 16, NULL)) == NULL) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated ZIP end-of-file record");
+ return (ARCHIVE_FATAL);
+ }
+ zip->crc32 = archive_le32dec(p + 4);
+ zip->compressed_size = archive_le32dec(p + 8);
+ zip->uncompressed_size = archive_le32dec(p + 12);
+ __archive_read_consume(a, 16);
+ }
+ /* Check file size, CRC against these values. */
+ if (zip->compressed_size != zip->entry_compressed_bytes_read) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "ZIP compressed data is wrong size");
+ return (ARCHIVE_WARN);
+ }
+ /* Size field only stores the lower 32 bits of the actual size. */
+ if ((zip->uncompressed_size & UINT32_MAX)
+ != (zip->entry_uncompressed_bytes_read & UINT32_MAX)) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "ZIP uncompressed data is wrong size");
+ return (ARCHIVE_WARN);
+ }
+ /* Check computed CRC against header */
+ if (zip->crc32 != zip->entry_crc32) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "ZIP bad CRC: 0x%lx should be 0x%lx",
+ zip->entry_crc32, zip->crc32);
+ return (ARCHIVE_WARN);
+ }
+ }
+
/* Return EOF immediately if this is a non-regular file. */
if (AE_IFREG != (zip->mode & AE_IFMT))
return (ARCHIVE_EOF);
@@ -761,7 +758,7 @@ archive_read_format_zip_read_data_skip(struct archive_read *a)
zip = (struct zip *)(a->format->data);
/* If we've already read to end of data, we're done. */
- if (zip->end_of_entry_cleanup)
+ if (zip->end_of_entry)
return (ARCHIVE_OK);
/*
@@ -788,7 +785,7 @@ archive_read_format_zip_read_data_skip(struct archive_read *a)
return (ARCHIVE_FATAL);
/* This entry is finished and done. */
- zip->end_of_entry_cleanup = zip->end_of_entry = 1;
+ zip->end_of_entry = 1;
return (ARCHIVE_OK);
}
diff --git a/lib/libarchive/archive_write_disk.c b/lib/libarchive/archive_write_disk.c
index a6b7ffc..a9417f4 100644
--- a/lib/libarchive/archive_write_disk.c
+++ b/lib/libarchive/archive_write_disk.c
@@ -519,6 +519,9 @@ write_data_block(struct archive_write_disk *a, const char *buff, size_t size)
ssize_t bytes_written = 0;
ssize_t block_size = 0, bytes_to_write;
+ if (size == 0)
+ return (ARCHIVE_OK);
+
if (a->filesize == 0 || a->fd < 0) {
archive_set_error(&a->archive, 0,
"Attempt to write to an empty file");
OpenPOWER on IntegriCloud