diff options
author | kientzle <kientzle@FreeBSD.org> | 2005-11-08 07:42:42 +0000 |
---|---|---|
committer | kientzle <kientzle@FreeBSD.org> | 2005-11-08 07:42:42 +0000 |
commit | 943bf8651e7784aee54605585e75752ade073677 (patch) | |
tree | a46b0764b5a05fddee3b7e90b090fc37cc285717 /lib/libarchive/archive_read_support_compression_compress.c | |
parent | fdd1f596650d52654ab5ff474492a698fb1d29e7 (diff) | |
download | FreeBSD-src-943bf8651e7784aee54605585e75752ade073677.zip FreeBSD-src-943bf8651e7784aee54605585e75752ade073677.tar.gz |
Correctly clean up if gzip format gets mis-identified as compress format.
(This can only happen in the pathalogical case where the client is
providing single-byte blocks.)
Diffstat (limited to 'lib/libarchive/archive_read_support_compression_compress.c')
-rw-r--r-- | lib/libarchive/archive_read_support_compression_compress.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/lib/libarchive/archive_read_support_compression_compress.c b/lib/libarchive/archive_read_support_compression_compress.c index f6ec9f0..30a7377 100644 --- a/lib/libarchive/archive_read_support_compression_compress.c +++ b/lib/libarchive/archive_read_support_compression_compress.c @@ -200,6 +200,7 @@ init(struct archive *a, const void *buff, size_t n) return (ARCHIVE_FATAL); } memset(state, 0, sizeof(*state)); + a->compression_data = state; state->uncompressed_buffer_size = 64 * 1024; state->uncompressed_buffer = malloc(state->uncompressed_buffer_size); @@ -217,12 +218,19 @@ init(struct archive *a, const void *buff, size_t n) state->avail_out = state->uncompressed_buffer_size; code = getbits(a, state, 8); - if (code != 037) + if (code != 037) /* This should be impossible. */ goto fatal; code = getbits(a, state, 8); - if (code != 0235) + if (code != 0235) { + /* This can happen if the library is receiving 1-byte + * blocks and gzip and compress are both enabled. + * You can't distinguish gzip and compress only from + * the first byte. */ + archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT, + "Compress signature did not match."); goto fatal; + } code = getbits(a, state, 8); state->maxcode_bits = code & 0x1f; @@ -242,8 +250,6 @@ init(struct archive *a, const void *buff, size_t n) state->suffix[code] = code; } next_code(a, state); - a->compression_data = state; - return (ARCHIVE_OK); fatal: @@ -331,17 +337,19 @@ static int finish(struct archive *a) { struct private_data *state; - int ret; + int ret = ARCHIVE_OK; state = a->compression_data; - ret = ARCHIVE_OK; - free(state->uncompressed_buffer); - free(state); + if (state != NULL) { + if (state->uncompressed_buffer != NULL) + free(state->uncompressed_buffer); + free(state); + } a->compression_data = NULL; if (a->client_closer != NULL) - (a->client_closer)(a, a->client_data); + ret = (a->client_closer)(a, a->client_data); return (ret); } |