aboutsummaryrefslogtreecommitdiff
path: root/lib/libarchive/archive_read_support_format_zip.c
diff options
context:
space:
mode:
authorTim Kientzle <kientzle@FreeBSD.org>2007-03-03 07:37:37 +0000
committerTim Kientzle <kientzle@FreeBSD.org>2007-03-03 07:37:37 +0000
commitf81da3e58463558f4efc2a76aac410e9fc03c096 (patch)
tree1b026213a337089af577dee3ed6d194ee1b87d88 /lib/libarchive/archive_read_support_format_zip.c
parent4fce38ec78121b2c00e603f58a0159da7bd974e1 (diff)
Notes
Diffstat (limited to 'lib/libarchive/archive_read_support_format_zip.c')
-rw-r--r--lib/libarchive/archive_read_support_format_zip.c108
1 files changed, 58 insertions, 50 deletions
diff --git a/lib/libarchive/archive_read_support_format_zip.c b/lib/libarchive/archive_read_support_format_zip.c
index 5807e560d91e..f15eba0585f0 100644
--- a/lib/libarchive/archive_read_support_format_zip.c
+++ b/lib/libarchive/archive_read_support_format_zip.c
@@ -44,15 +44,16 @@ __FBSDID("$FreeBSD$");
#include "archive.h"
#include "archive_entry.h"
#include "archive_private.h"
+#include "archive_read_private.h"
struct zip {
/* entry_bytes_remaining is the number of bytes we expect. */
- off_t entry_bytes_remaining;
- off_t entry_offset;
+ int64_t entry_bytes_remaining;
+ int64_t entry_offset;
/* These count the number of bytes actually read for the entry. */
- off_t entry_compressed_bytes_read;
- off_t entry_uncompressed_bytes_read;
+ int64_t entry_compressed_bytes_read;
+ int64_t entry_uncompressed_bytes_read;
unsigned version;
unsigned system;
@@ -74,8 +75,8 @@ struct zip {
long crc32;
ssize_t filename_length;
ssize_t extra_length;
- off_t uncompressed_size;
- off_t compressed_size;
+ int64_t uncompressed_size;
+ int64_t compressed_size;
unsigned char *uncompressed_buffer;
size_t uncompressed_buffer_size;
@@ -115,36 +116,40 @@ static const char *compression_names[] = {
"deflation"
};
-static int archive_read_format_zip_bid(struct archive *);
-static int archive_read_format_zip_cleanup(struct archive *);
-static int archive_read_format_zip_read_data(struct archive *,
+static int archive_read_format_zip_bid(struct archive_read *);
+static int archive_read_format_zip_cleanup(struct archive_read *);
+static int archive_read_format_zip_read_data(struct archive_read *,
const void **, size_t *, off_t *);
-static int archive_read_format_zip_read_data_skip(struct archive *a);
-static int archive_read_format_zip_read_header(struct archive *,
+static int archive_read_format_zip_read_data_skip(struct archive_read *a);
+static int archive_read_format_zip_read_header(struct archive_read *,
struct archive_entry *);
static int i2(const char *);
static int i4(const char *);
static unsigned int u2(const char *);
static unsigned int u4(const char *);
static uint64_t u8(const char *);
-static int zip_read_data_deflate(struct archive *a, const void **buff,
+static int zip_read_data_deflate(struct archive_read *a, const void **buff,
size_t *size, off_t *offset);
-static int zip_read_data_none(struct archive *a, const void **buff,
+static int zip_read_data_none(struct archive_read *a, const void **buff,
size_t *size, off_t *offset);
-static int zip_read_file_header(struct archive *a,
+static int zip_read_file_header(struct archive_read *a,
struct archive_entry *entry, struct zip *zip);
static time_t zip_time(const char *);
static void process_extra(const void* extra, struct zip* zip);
+/* Largest 32-bit unsigned value, stored in a 64-bit constant. */
+static const uint64_t max_uint32 = (((uint64_t)1) << 32) - 1;
+
int
-archive_read_support_format_zip(struct archive *a)
+archive_read_support_format_zip(struct archive *_a)
{
+ struct archive_read *a = (struct archive_read *)_a;
struct zip *zip;
int r;
zip = (struct zip *)malloc(sizeof(*zip));
if (zip == NULL) {
- archive_set_error(a, ENOMEM, "Can't allocate zip data");
+ archive_set_error(&a->archive, ENOMEM, "Can't allocate zip data");
return (ARCHIVE_FATAL);
}
memset(zip, 0, sizeof(*zip));
@@ -164,14 +169,14 @@ archive_read_support_format_zip(struct archive *a)
static int
-archive_read_format_zip_bid(struct archive *a)
+archive_read_format_zip_bid(struct archive_read *a)
{
int bytes_read;
int bid = 0;
const void *h;
const char *p;
- if (a->archive_format == ARCHIVE_FORMAT_ZIP)
+ if (a->archive.archive_format == ARCHIVE_FORMAT_ZIP)
bid += 1;
bytes_read = (a->compression_read_ahead)(a, &h, 4);
@@ -194,7 +199,7 @@ archive_read_format_zip_bid(struct archive *a)
}
static int
-archive_read_format_zip_read_header(struct archive *a,
+archive_read_format_zip_read_header(struct archive_read *a,
struct archive_entry *entry)
{
int bytes_read;
@@ -202,9 +207,9 @@ archive_read_format_zip_read_header(struct archive *a,
const char *signature;
struct zip *zip;
- a->archive_format = ARCHIVE_FORMAT_ZIP;
- if (a->archive_format_name == NULL)
- a->archive_format_name = "ZIP";
+ a->archive.archive_format = ARCHIVE_FORMAT_ZIP;
+ if (a->archive.archive_format_name == NULL)
+ a->archive.archive_format_name = "ZIP";
zip = (struct zip *)*(a->pformat_data);
zip->decompress_init = 0;
@@ -218,7 +223,7 @@ archive_read_format_zip_read_header(struct archive *a,
signature = (const char *)h;
if (signature[0] != 'P' || signature[1] != 'K') {
- archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Bad ZIP file");
return (ARCHIVE_FATAL);
}
@@ -243,19 +248,19 @@ archive_read_format_zip_read_header(struct archive *a,
* We should never encounter this record here;
* see ZIP_LENGTH_AT_END handling below for details.
*/
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Bad ZIP file: Unexpected end-of-entry record");
return (ARCHIVE_FATAL);
}
- archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Damaged ZIP file or unsupported format variant (%d,%d)",
signature[2], signature[3]);
return (ARCHIVE_FATAL);
}
int
-zip_read_file_header(struct archive *a, struct archive_entry *entry,
+zip_read_file_header(struct archive_read *a, struct archive_entry *entry,
struct zip *zip)
{
const struct zip_file_header *p;
@@ -266,7 +271,7 @@ zip_read_file_header(struct archive *a, struct archive_entry *entry,
bytes_read =
(a->compression_read_ahead)(a, &h, sizeof(struct zip_file_header));
if (bytes_read < (int)sizeof(struct zip_file_header)) {
- archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Truncated ZIP file header");
return (ARCHIVE_FATAL);
}
@@ -299,7 +304,7 @@ zip_read_file_header(struct archive *a, struct archive_entry *entry,
/* Read the filename. */
bytes_read = (a->compression_read_ahead)(a, &h, zip->filename_length);
if (bytes_read < zip->filename_length) {
- archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Truncated ZIP file header");
return (ARCHIVE_FATAL);
}
@@ -316,7 +321,7 @@ zip_read_file_header(struct archive *a, struct archive_entry *entry,
/* Read the extra data. */
bytes_read = (a->compression_read_ahead)(a, &h, zip->extra_length);
if (bytes_read < zip->extra_length) {
- archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Truncated ZIP file header");
return (ARCHIVE_FATAL);
}
@@ -341,7 +346,7 @@ zip_read_file_header(struct archive *a, struct archive_entry *entry,
sprintf(zip->format_name, "ZIP %d.%d (%s)",
zip->version / 10, zip->version % 10,
zip->compression_name);
- a->archive_format_name = zip->format_name;
+ a->archive.archive_format_name = zip->format_name;
return (ARCHIVE_OK);
}
@@ -368,7 +373,7 @@ zip_time(const char *p)
}
static int
-archive_read_format_zip_read_data(struct archive *a,
+archive_read_format_zip_read_data(struct archive_read *a,
const void **buff, size_t *size, off_t *offset)
{
int r;
@@ -388,7 +393,7 @@ archive_read_format_zip_read_data(struct archive *a,
int bytes_read =
(a->compression_read_ahead)(a, &h, 16);
if (bytes_read < 16) {
- archive_set_error(a,
+ archive_set_error(&a->archive,
ARCHIVE_ERRNO_FILE_FORMAT,
"Truncated ZIP end-of-file record");
return (ARCHIVE_FATAL);
@@ -402,19 +407,21 @@ archive_read_format_zip_read_data(struct archive *a,
/* Check file size, CRC against these values. */
if (zip->compressed_size != zip->entry_compressed_bytes_read) {
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"ZIP compressed data is wrong size");
return (ARCHIVE_WARN);
}
- if (zip->uncompressed_size != zip->entry_uncompressed_bytes_read) {
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ /* Size field only stores the lower 32 bits of the actual size. */
+ if ((zip->uncompressed_size & max_uint32)
+ != (zip->entry_uncompressed_bytes_read & max_uint32)) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"ZIP uncompressed data is wrong size");
return (ARCHIVE_WARN);
}
/* TODO: Compute CRC. */
/*
if (zip->crc32 != zip->entry_crc32_calculated) {
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"ZIP data CRC error");
return (ARCHIVE_WARN);
}
@@ -437,7 +444,7 @@ archive_read_format_zip_read_data(struct archive *a,
*size = 0;
*offset = 0;
/* Return a warning. */
- archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Unsupported ZIP compression method (%s)",
zip->compression_name);
if (zip->flags & ZIP_LENGTH_AT_END) {
@@ -472,7 +479,7 @@ archive_read_format_zip_read_data(struct archive *a,
* zip->end_of_entry if it consumes all of the data.
*/
static int
-zip_read_data_none(struct archive *a, const void **buff,
+zip_read_data_none(struct archive_read *a, const void **buff,
size_t *size, off_t *offset)
{
struct zip *zip;
@@ -495,7 +502,7 @@ zip_read_data_none(struct archive *a, const void **buff,
*/
bytes_avail = (a->compression_read_ahead)(a, buff, 1);
if (bytes_avail <= 0) {
- archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Truncated ZIP file data");
return (ARCHIVE_FATAL);
}
@@ -513,7 +520,7 @@ zip_read_data_none(struct archive *a, const void **buff,
#ifdef HAVE_ZLIB_H
static int
-zip_read_data_deflate(struct archive *a, const void **buff,
+zip_read_data_deflate(struct archive_read *a, const void **buff,
size_t *size, off_t *offset)
{
struct zip *zip;
@@ -529,7 +536,7 @@ zip_read_data_deflate(struct archive *a, const void **buff,
zip->uncompressed_buffer
= (unsigned char *)malloc(zip->uncompressed_buffer_size);
if (zip->uncompressed_buffer == NULL) {
- archive_set_error(a, ENOMEM,
+ archive_set_error(&a->archive, ENOMEM,
"No memory for ZIP decompression");
return (ARCHIVE_FATAL);
}
@@ -540,7 +547,7 @@ zip_read_data_deflate(struct archive *a, const void **buff,
r = inflateInit2(&zip->stream,
-15 /* Don't check for zlib header */);
if (r != Z_OK) {
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Can't initialize ZIP decompression.");
return (ARCHIVE_FATAL);
}
@@ -555,7 +562,7 @@ zip_read_data_deflate(struct archive *a, const void **buff,
*/
bytes_avail = (a->compression_read_ahead)(a, &compressed_buff, 1);
if (bytes_avail <= 0) {
- archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Truncated ZIP file body");
return (ARCHIVE_FATAL);
}
@@ -581,11 +588,11 @@ zip_read_data_deflate(struct archive *a, const void **buff,
zip->end_of_entry = 1;
break;
case Z_MEM_ERROR:
- archive_set_error(a, ENOMEM,
+ archive_set_error(&a->archive, ENOMEM,
"Out of memory for ZIP decompression");
return (ARCHIVE_FATAL);
default:
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"ZIP decompression failed (%d)", r);
return (ARCHIVE_FATAL);
}
@@ -605,20 +612,20 @@ zip_read_data_deflate(struct archive *a, const void **buff,
}
#else
static int
-zip_read_data_deflate(struct archive *a, const void **buff,
+zip_read_data_deflate(struct archive_read *a, const void **buff,
size_t *size, off_t *offset)
{
*buff = NULL;
*size = 0;
*offset = 0;
- archive_set_error(a, ARCHIVE_ERRNO_MISC,
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"libarchive compiled without deflate support (no libz)");
return (ARCHIVE_FATAL);
}
#endif
static int
-archive_read_format_zip_read_data_skip(struct archive *a)
+archive_read_format_zip_read_data_skip(struct archive_read *a)
{
struct zip *zip;
const void *buff = NULL;
@@ -648,7 +655,8 @@ archive_read_format_zip_read_data_skip(struct archive *a)
while (zip->entry_bytes_remaining > 0) {
bytes_avail = (a->compression_read_ahead)(a, &buff, 1);
if (bytes_avail <= 0) {
- archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
"Truncated ZIP file body");
return (ARCHIVE_FATAL);
}
@@ -663,7 +671,7 @@ archive_read_format_zip_read_data_skip(struct archive *a)
}
static int
-archive_read_format_zip_cleanup(struct archive *a)
+archive_read_format_zip_cleanup(struct archive_read *a)
{
struct zip *zip;