summaryrefslogtreecommitdiff
path: root/libarchive/libarchive-2.5.5/libarchive/archive_read_support_compression_bzip2.c
diff options
context:
space:
mode:
Diffstat (limited to 'libarchive/libarchive-2.5.5/libarchive/archive_read_support_compression_bzip2.c')
-rw-r--r--libarchive/libarchive-2.5.5/libarchive/archive_read_support_compression_bzip2.c426
1 files changed, 0 insertions, 426 deletions
diff --git a/libarchive/libarchive-2.5.5/libarchive/archive_read_support_compression_bzip2.c b/libarchive/libarchive-2.5.5/libarchive/archive_read_support_compression_bzip2.c
deleted file mode 100644
index 824b0cd..0000000
--- a/libarchive/libarchive-2.5.5/libarchive/archive_read_support_compression_bzip2.c
+++ /dev/null
@@ -1,426 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "archive_platform.h"
-
-__FBSDID("$FreeBSD: src/lib/libarchive/archive_read_support_compression_bzip2.c,v 1.18 2008/05/26 17:00:22 kientzle Exp $");
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include <stdio.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_BZLIB_H
-#include <bzlib.h>
-#endif
-
-#include "archive.h"
-#include "archive_private.h"
-#include "archive_read_private.h"
-
-#if HAVE_BZLIB_H
-struct private_data {
- bz_stream stream;
- char *uncompressed_buffer;
- size_t uncompressed_buffer_size;
- char *read_next;
- int64_t total_out;
- char eof; /* True = found end of compressed data. */
-};
-
-static int finish(struct archive_read *);
-static ssize_t read_ahead(struct archive_read *, const void **, size_t);
-static ssize_t read_consume(struct archive_read *, size_t);
-static int drive_decompressor(struct archive_read *a, struct private_data *);
-#endif
-
-/* These two functions are defined even if we lack the library. See below. */
-static int bid(const void *, size_t);
-static int init(struct archive_read *, const void *, size_t);
-
-int
-archive_read_support_compression_bzip2(struct archive *_a)
-{
- struct archive_read *a = (struct archive_read *)_a;
- if (__archive_read_register_compression(a, bid, init) != NULL)
- return (ARCHIVE_OK);
- return (ARCHIVE_FATAL);
-}
-
-/*
- * Test whether we can handle this data.
- *
- * This logic returns zero if any part of the signature fails. It
- * also tries to Do The Right Thing if a very short buffer prevents us
- * from verifying as much as we would like.
- */
-static int
-bid(const void *buff, size_t len)
-{
- const unsigned char *buffer;
- int bits_checked;
-
- if (len < 1)
- return (0);
-
- buffer = (const unsigned char *)buff;
- bits_checked = 0;
- if (buffer[0] != 'B') /* Verify first ID byte. */
- return (0);
- bits_checked += 8;
- if (len < 2)
- return (bits_checked);
-
- if (buffer[1] != 'Z') /* Verify second ID byte. */
- return (0);
- bits_checked += 8;
- if (len < 3)
- return (bits_checked);
-
- if (buffer[2] != 'h') /* Verify third ID byte. */
- return (0);
- bits_checked += 8;
- if (len < 4)
- return (bits_checked);
-
- if (buffer[3] < '1' || buffer[3] > '9')
- return (0);
- bits_checked += 5;
- if (len < 5)
- return (bits_checked);
-
- /* After BZh[1-9], there must be either a data block
- * which begins with 0x314159265359 or an end-of-data
- * marker of 0x177245385090. */
-
- if (buffer[4] == 0x31) {
- /* Verify the data block signature. */
- size_t s = len;
- if (s > 10) s = 10;
- if (memcmp(buffer + 4, "\x31\x41\x59\x26\x53\x59", s - 4) != 0)
- return (0);
- bits_checked += 8 * (s - 4);
- } else if (buffer[4] == 0x17) {
- /* Verify the end-of-data marker. */
- size_t s = len;
- if (s > 10) s = 10;
- if (memcmp(buffer + 4, "\x17\x72\x45\x38\x50\x90", s - 4) != 0)
- return (0);
- bits_checked += 8 * (s - 4);
- } else
- return (0);
-
- return (bits_checked);
-}
-
-#ifndef HAVE_BZLIB_H
-
-/*
- * If we don't have the library on this system, we can't actually do the
- * decompression. We can, however, still detect compressed archives
- * and emit a useful message.
- */
-static int
-init(struct archive_read *a, const void *buff, size_t n)
-{
- (void)a; /* UNUSED */
- (void)buff; /* UNUSED */
- (void)n; /* UNUSED */
-
- archive_set_error(&a->archive, -1,
- "This version of libarchive was compiled without bzip2 support");
- return (ARCHIVE_FATAL);
-}
-
-
-#else
-
-/*
- * Setup the callbacks.
- */
-static int
-init(struct archive_read *a, const void *buff, size_t n)
-{
- struct private_data *state;
- int ret;
-
- a->archive.compression_code = ARCHIVE_COMPRESSION_BZIP2;
- a->archive.compression_name = "bzip2";
-
- state = (struct private_data *)malloc(sizeof(*state));
- if (state == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate data for %s decompression",
- a->archive.compression_name);
- return (ARCHIVE_FATAL);
- }
- memset(state, 0, sizeof(*state));
-
- state->uncompressed_buffer_size = 64 * 1024;
- state->uncompressed_buffer = (char *)malloc(state->uncompressed_buffer_size);
- state->stream.next_out = state->uncompressed_buffer;
- state->read_next = state->uncompressed_buffer;
- state->stream.avail_out = state->uncompressed_buffer_size;
-
- if (state->uncompressed_buffer == NULL) {
- archive_set_error(&a->archive, ENOMEM,
- "Can't allocate %s decompression buffers",
- a->archive.compression_name);
- free(state);
- return (ARCHIVE_FATAL);
- }
-
- /*
- * A bug in bzlib.h: stream.next_in should be marked 'const'
- * but isn't (the library never alters data through the
- * next_in pointer, only reads it). The result: this ugly
- * cast to remove 'const'.
- */
- state->stream.next_in = (char *)(uintptr_t)(const void *)buff;
- state->stream.avail_in = n;
-
- a->decompressor->read_ahead = read_ahead;
- a->decompressor->consume = read_consume;
- a->decompressor->skip = NULL; /* not supported */
- a->decompressor->finish = finish;
-
- /* Initialize compression library. */
- ret = BZ2_bzDecompressInit(&(state->stream),
- 0 /* library verbosity */,
- 0 /* don't use slow low-mem algorithm */);
-
- /* If init fails, try using low-memory algorithm instead. */
- if (ret == BZ_MEM_ERROR) {
- ret = BZ2_bzDecompressInit(&(state->stream),
- 0 /* library verbosity */,
- 1 /* do use slow low-mem algorithm */);
- }
-
- if (ret == BZ_OK) {
- a->decompressor->data = state;
- return (ARCHIVE_OK);
- }
-
- /* Library setup failed: Clean up. */
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Internal error initializing %s library",
- a->archive.compression_name);
- free(state->uncompressed_buffer);
- free(state);
-
- /* Override the error message if we know what really went wrong. */
- switch (ret) {
- case BZ_PARAM_ERROR:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Internal error initializing compression library: "
- "invalid setup parameter");
- break;
- case BZ_MEM_ERROR:
- archive_set_error(&a->archive, ENOMEM,
- "Internal error initializing compression library: "
- "out of memory");
- break;
- case BZ_CONFIG_ERROR:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Internal error initializing compression library: "
- "mis-compiled library");
- break;
- }
-
- return (ARCHIVE_FATAL);
-}
-
-/*
- * Return a block of data from the decompression buffer. Decompress more
- * as necessary.
- */
-static ssize_t
-read_ahead(struct archive_read *a, const void **p, size_t min)
-{
- struct private_data *state;
- size_t read_avail, was_avail;
- int ret;
-
- state = (struct private_data *)a->decompressor->data;
- if (!a->client_reader) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
- "No read callback is registered? "
- "This is probably an internal programming error.");
- return (ARCHIVE_FATAL);
- }
-
- read_avail = state->stream.next_out - state->read_next;
-
- if (read_avail + state->stream.avail_out < min) {
- memmove(state->uncompressed_buffer, state->read_next,
- read_avail);
- state->read_next = state->uncompressed_buffer;
- state->stream.next_out = state->read_next + read_avail;
- state->stream.avail_out
- = state->uncompressed_buffer_size - read_avail;
- }
-
- while (read_avail < min && /* Haven't satisfied min. */
- read_avail < state->uncompressed_buffer_size) { /* !full */
- was_avail = read_avail;
- if ((ret = drive_decompressor(a, state)) < ARCHIVE_OK)
- return (ret);
- if (ret == ARCHIVE_EOF)
- break; /* Break on EOF even if we haven't met min. */
- read_avail = state->stream.next_out - state->read_next;
- if (was_avail == read_avail) /* No progress? */
- break;
- }
-
- *p = state->read_next;
- return (read_avail);
-}
-
-/*
- * Mark a previously-returned block of data as read.
- */
-static ssize_t
-read_consume(struct archive_read *a, size_t n)
-{
- struct private_data *state;
-
- state = (struct private_data *)a->decompressor->data;
- a->archive.file_position += n;
- state->read_next += n;
- if (state->read_next > state->stream.next_out)
- __archive_errx(1, "Request to consume too many "
- "bytes from bzip2 decompressor");
- return (n);
-}
-
-/*
- * Clean up the decompressor.
- */
-static int
-finish(struct archive_read *a)
-{
- struct private_data *state;
- int ret;
-
- state = (struct private_data *)a->decompressor->data;
- ret = ARCHIVE_OK;
- switch (BZ2_bzDecompressEnd(&(state->stream))) {
- case BZ_OK:
- break;
- default:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "Failed to clean up %s compressor",
- a->archive.compression_name);
- ret = ARCHIVE_FATAL;
- }
-
- free(state->uncompressed_buffer);
- free(state);
-
- a->decompressor->data = NULL;
- return (ret);
-}
-
-/*
- * Utility function to pull data through decompressor, reading input
- * blocks as necessary.
- */
-static int
-drive_decompressor(struct archive_read *a, struct private_data *state)
-{
- ssize_t ret;
- int decompressed, total_decompressed;
- char *output;
- const void *read_buf;
-
- if (state->eof)
- return (ARCHIVE_EOF);
- total_decompressed = 0;
- for (;;) {
- if (state->stream.avail_in == 0) {
- read_buf = state->stream.next_in;
- ret = (a->client_reader)(&a->archive, a->client_data,
- &read_buf);
- state->stream.next_in = (void *)(uintptr_t)read_buf;
- if (ret < 0) {
- /*
- * TODO: Find a better way to handle
- * this read failure.
- */
- goto fatal;
- }
- if (ret == 0 && total_decompressed == 0) {
- archive_set_error(&a->archive, EIO,
- "Premature end of %s compressed data",
- a->archive.compression_name);
- return (ARCHIVE_FATAL);
- }
- a->archive.raw_position += ret;
- state->stream.avail_in = ret;
- }
-
- {
- output = state->stream.next_out;
-
- /* Decompress some data. */
- ret = BZ2_bzDecompress(&(state->stream));
- decompressed = state->stream.next_out - output;
-
- /* Accumulate the total bytes of output. */
- state->total_out += decompressed;
- total_decompressed += decompressed;
-
- switch (ret) {
- case BZ_OK: /* Decompressor made some progress. */
- if (decompressed > 0)
- return (ARCHIVE_OK);
- break;
- case BZ_STREAM_END: /* Found end of stream. */
- state->eof = 1;
- return (ARCHIVE_OK);
- default:
- /* Any other return value is an error. */
- goto fatal;
- }
- }
- }
- return (ARCHIVE_OK);
-
- /* Return a fatal error. */
-fatal:
- archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
- "%s decompression failed", a->archive.compression_name);
- return (ARCHIVE_FATAL);
-}
-
-#endif /* HAVE_BZLIB_H */