diff options
Diffstat (limited to 'lib/libarchive/archive_read_support_compression_uu.c')
-rw-r--r-- | lib/libarchive/archive_read_support_compression_uu.c | 637 |
1 files changed, 0 insertions, 637 deletions
diff --git a/lib/libarchive/archive_read_support_compression_uu.c b/lib/libarchive/archive_read_support_compression_uu.c deleted file mode 100644 index cb1dae5..0000000 --- a/lib/libarchive/archive_read_support_compression_uu.c +++ /dev/null @@ -1,637 +0,0 @@ -/*- - * Copyright (c) 2009 Michihiro NAKAJIMA - * 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$"); - -#ifdef HAVE_ERRNO_H -#include <errno.h> -#endif -#ifdef HAVE_STDLIB_H -#include <stdlib.h> -#endif -#ifdef HAVE_STRING_H -#include <string.h> -#endif - -#include "archive.h" -#include "archive_private.h" -#include "archive_read_private.h" - -struct uudecode { - int64_t total; - unsigned char *in_buff; -#define IN_BUFF_SIZE (1024) - int in_cnt; - size_t in_allocated; - unsigned char *out_buff; -#define OUT_BUFF_SIZE (64 * 1024) - int state; -#define ST_FIND_HEAD 0 -#define ST_READ_UU 1 -#define ST_UUEND 2 -#define ST_READ_BASE64 3 -}; - -static int uudecode_bidder_bid(struct archive_read_filter_bidder *, - struct archive_read_filter *filter); -static int uudecode_bidder_init(struct archive_read_filter *); - -static ssize_t uudecode_filter_read(struct archive_read_filter *, - const void **); -static int uudecode_filter_close(struct archive_read_filter *); - -int -archive_read_support_compression_uu(struct archive *_a) -{ - struct archive_read *a = (struct archive_read *)_a; - struct archive_read_filter_bidder *bidder; - - bidder = __archive_read_get_bidder(a); - archive_clear_error(_a); - if (bidder == NULL) - return (ARCHIVE_FATAL); - - bidder->data = NULL; - bidder->bid = uudecode_bidder_bid; - bidder->init = uudecode_bidder_init; - bidder->options = NULL; - bidder->free = NULL; - return (ARCHIVE_OK); -} - -static const unsigned char ascii[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\n', 0, 0, '\r', 0, 0, /* 00 - 0F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 - 2F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 30 - 3F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 50 - 5F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 - 6F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* 70 - 7F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F0 - FF */ -}; - -static const unsigned char uuchar[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 0F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 - 2F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 30 - 3F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 50 - 5F */ - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60 - 6F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 70 - 7F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F0 - FF */ -}; - -static const unsigned char base64[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 0F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, /* 20 - 2F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, /* 30 - 3F */ - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 50 - 5F */ - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 - 6F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 70 - 7F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F0 - FF */ -}; - -static const int base64num[128] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 0F */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1F */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 62, 0, 0, 0, 63, /* 20 - 2F */ - 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 0, 0, 0, 0, 0, 0, /* 30 - 3F */ - 0, 0, 1, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, /* 40 - 4F */ - 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 0, 0, 0, 0, 0, /* 50 - 5F */ - 0, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, /* 60 - 6F */ - 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 0, 0, 0, 0, 0, /* 70 - 7F */ -}; - -static ssize_t -get_line(const unsigned char *b, ssize_t avail, ssize_t *nlsize) -{ - ssize_t len; - - len = 0; - while (len < avail) { - switch (ascii[*b]) { - case 0: /* Non-ascii character or control character. */ - if (nlsize != NULL) - *nlsize = 0; - return (-1); - case '\r': - if (avail-len > 1 && b[1] == '\n') { - if (nlsize != NULL) - *nlsize = 2; - return (len+2); - } - /* FALL THROUGH */ - case '\n': - if (nlsize != NULL) - *nlsize = 1; - return (len+1); - case 1: - b++; - len++; - break; - } - } - if (nlsize != NULL) - *nlsize = 0; - return (avail); -} - -static ssize_t -bid_get_line(struct archive_read_filter *filter, - const unsigned char **b, ssize_t *avail, ssize_t *ravail, ssize_t *nl) -{ - ssize_t len; - int quit; - - quit = 0; - if (*avail == 0) { - *nl = 0; - len = 0; - } else - len = get_line(*b, *avail, nl); - /* - * Read bytes more while it does not reach the end of line. - */ - while (*nl == 0 && len == *avail && !quit) { - ssize_t diff = *ravail - *avail; - - *b = __archive_read_filter_ahead(filter, 160 + *ravail, avail); - if (*b == NULL) { - if (*ravail >= *avail) - return (0); - /* Reading bytes reaches the end of file. */ - *b = __archive_read_filter_ahead(filter, *avail, avail); - quit = 1; - } - *ravail = *avail; - *b += diff; - *avail -= diff; - len = get_line(*b, *avail, nl); - } - return (len); -} - -#define UUDECODE(c) (((c) - 0x20) & 0x3f) - -static int -uudecode_bidder_bid(struct archive_read_filter_bidder *self, - struct archive_read_filter *filter) -{ - const unsigned char *b; - ssize_t avail, ravail; - ssize_t len, nl; - int l; - int firstline; - - (void)self; /* UNUSED */ - - b = __archive_read_filter_ahead(filter, 1, &avail); - if (b == NULL) - return (0); - - firstline = 20; - ravail = avail; - for (;;) { - len = bid_get_line(filter, &b, &avail, &ravail, &nl); - if (len < 0 || nl == 0) - return (0);/* Binary data. */ - if (memcmp(b, "begin ", 6) == 0 && len - nl >= 11) - l = 6; - else if (memcmp(b, "begin-base64 ", 13) == 0 && len - nl >= 18) - l = 13; - else - l = 0; - - if (l > 0 && (b[l] < '0' || b[l] > '7' || - b[l+1] < '0' || b[l+1] > '7' || - b[l+2] < '0' || b[l+2] > '7' || b[l+3] != ' ')) - l = 0; - - b += len; - avail -= len; - if (l) - break; - firstline = 0; - } - if (!avail) - return (0); - len = bid_get_line(filter, &b, &avail, &ravail, &nl); - if (len < 0 || nl == 0) - return (0);/* There are non-ascii characters. */ - avail -= len; - - if (l == 6) { - if (!uuchar[*b]) - return (0); - /* Get a length of decoded bytes. */ - l = UUDECODE(*b++); len--; - if (l > 45) - /* Normally, maximum length is 45(character 'M'). */ - return (0); - while (l && len-nl > 0) { - if (l > 0) { - if (!uuchar[*b++]) - return (0); - if (!uuchar[*b++]) - return (0); - len -= 2; - --l; - } - if (l > 0) { - if (!uuchar[*b++]) - return (0); - --len; - --l; - } - if (l > 0) { - if (!uuchar[*b++]) - return (0); - --len; - --l; - } - } - if (len-nl < 0) - return (0); - if (len-nl == 1 && - (uuchar[*b] || /* Check sum. */ - (*b >= 'a' && *b <= 'z'))) {/* Padding data(MINIX). */ - ++b; - --len; - } - b += nl; - if (avail && uuchar[*b]) - return (firstline+30); - } - if (l == 13) { - while (len-nl > 0) { - if (!base64[*b++]) - return (0); - --len; - } - b += nl; - - if (avail >= 5 && memcmp(b, "====\n", 5) == 0) - return (firstline+40); - if (avail >= 6 && memcmp(b, "====\r\n", 6) == 0) - return (firstline+40); - if (avail > 0 && base64[*b]) - return (firstline+30); - } - - return (0); -} - -static int -uudecode_bidder_init(struct archive_read_filter *self) -{ - struct uudecode *uudecode; - void *out_buff; - void *in_buff; - - self->code = ARCHIVE_COMPRESSION_UU; - self->name = "uu"; - self->read = uudecode_filter_read; - self->skip = NULL; /* not supported */ - self->close = uudecode_filter_close; - - uudecode = (struct uudecode *)calloc(sizeof(*uudecode), 1); - out_buff = malloc(OUT_BUFF_SIZE); - in_buff = malloc(IN_BUFF_SIZE); - if (uudecode == NULL || out_buff == NULL || in_buff == NULL) { - archive_set_error(&self->archive->archive, ENOMEM, - "Can't allocate data for uudecode"); - free(uudecode); - free(out_buff); - free(in_buff); - return (ARCHIVE_FATAL); - } - - self->data = uudecode; - uudecode->in_buff = in_buff; - uudecode->in_cnt = 0; - uudecode->in_allocated = IN_BUFF_SIZE; - uudecode->out_buff = out_buff; - uudecode->state = ST_FIND_HEAD; - - return (ARCHIVE_OK); -} - -static int -ensure_in_buff_size(struct archive_read_filter *self, - struct uudecode *uudecode, size_t size) -{ - - if (size > uudecode->in_allocated) { - unsigned char *ptr; - size_t newsize; - - /* - * Calculate a new buffer size for in_buff. - * Increase its value until it has enough size we need. - */ - newsize = uudecode->in_allocated; - do { - if (newsize < IN_BUFF_SIZE*32) - newsize <<= 1; - else - newsize += IN_BUFF_SIZE; - } while (size > newsize); - ptr = malloc(newsize); - if (ptr == NULL || - newsize < uudecode->in_allocated) { - free(ptr); - archive_set_error(&self->archive->archive, - ENOMEM, - "Can't allocate data for uudecode"); - return (ARCHIVE_FATAL); - } - if (uudecode->in_cnt) - memmove(ptr, uudecode->in_buff, - uudecode->in_cnt); - free(uudecode->in_buff); - uudecode->in_buff = ptr; - uudecode->in_allocated = newsize; - } - return (ARCHIVE_OK); -} - -static ssize_t -uudecode_filter_read(struct archive_read_filter *self, const void **buff) -{ - struct uudecode *uudecode; - const unsigned char *b, *d; - unsigned char *out; - ssize_t avail_in, ravail; - ssize_t used; - ssize_t total; - ssize_t len, llen, nl; - - uudecode = (struct uudecode *)self->data; - -read_more: - d = __archive_read_filter_ahead(self->upstream, 1, &avail_in); - if (d == NULL && avail_in < 0) - return (ARCHIVE_FATAL); - /* Quiet a code analyzer; make sure avail_in must be zero - * when d is NULL. */ - if (d == NULL) - avail_in = 0; - used = 0; - total = 0; - out = uudecode->out_buff; - ravail = avail_in; - if (uudecode->in_cnt) { - /* - * If there is remaining data which is saved by - * previous calling, use it first. - */ - if (ensure_in_buff_size(self, uudecode, - avail_in + uudecode->in_cnt) != ARCHIVE_OK) - return (ARCHIVE_FATAL); - memcpy(uudecode->in_buff + uudecode->in_cnt, - d, avail_in); - d = uudecode->in_buff; - avail_in += uudecode->in_cnt; - uudecode->in_cnt = 0; - } - for (;used < avail_in; d += llen, used += llen) { - int l, body; - - b = d; - len = get_line(b, avail_in - used, &nl); - if (len < 0) { - /* Non-ascii character is found. */ - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "Insufficient compressed data"); - return (ARCHIVE_FATAL); - } - llen = len; - if (nl == 0) { - /* - * Save remaining data which does not contain - * NL('\n','\r'). - */ - if (ensure_in_buff_size(self, uudecode, len) - != ARCHIVE_OK) - return (ARCHIVE_FATAL); - if (uudecode->in_buff != b) - memmove(uudecode->in_buff, b, len); - uudecode->in_cnt = len; - if (total == 0) { - /* Do not return 0; it means end-of-file. - * We should try to read bytes more. */ - __archive_read_filter_consume( - self->upstream, ravail); - goto read_more; - } - break; - } - if (total + len * 2 > OUT_BUFF_SIZE) - break; - switch (uudecode->state) { - default: - case ST_FIND_HEAD: - if (len - nl > 13 && memcmp(b, "begin ", 6) == 0) - l = 6; - else if (len - nl > 18 && - memcmp(b, "begin-base64 ", 13) == 0) - l = 13; - else - l = 0; - if (l != 0 && b[l] >= '0' && b[l] <= '7' && - b[l+1] >= '0' && b[l+1] <= '7' && - b[l+2] >= '0' && b[l+2] <= '7' && b[l+3] == ' ') { - if (l == 6) - uudecode->state = ST_READ_UU; - else - uudecode->state = ST_READ_BASE64; - } - break; - case ST_READ_UU: - body = len - nl; - if (!uuchar[*b] || body <= 0) { - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "Insufficient compressed data"); - return (ARCHIVE_FATAL); - } - /* Get length of undecoded bytes of curent line. */ - l = UUDECODE(*b++); - body--; - if (l > body) { - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "Insufficient compressed data"); - return (ARCHIVE_FATAL); - } - if (l == 0) { - uudecode->state = ST_UUEND; - break; - } - while (l > 0) { - int n = 0; - - if (l > 0) { - if (!uuchar[b[0]] || !uuchar[b[1]]) - break; - n = UUDECODE(*b++) << 18; - n |= UUDECODE(*b++) << 12; - *out++ = n >> 16; total++; - --l; - } - if (l > 0) { - if (!uuchar[b[0]]) - break; - n |= UUDECODE(*b++) << 6; - *out++ = (n >> 8) & 0xFF; total++; - --l; - } - if (l > 0) { - if (!uuchar[b[0]]) - break; - n |= UUDECODE(*b++); - *out++ = n & 0xFF; total++; - --l; - } - } - if (l) { - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "Insufficient compressed data"); - return (ARCHIVE_FATAL); - } - break; - case ST_UUEND: - if (len - nl == 3 && memcmp(b, "end ", 3) == 0) - uudecode->state = ST_FIND_HEAD; - else { - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "Insufficient compressed data"); - return (ARCHIVE_FATAL); - } - break; - case ST_READ_BASE64: - l = len - nl; - if (l >= 3 && b[0] == '=' && b[1] == '=' && - b[2] == '=') { - uudecode->state = ST_FIND_HEAD; - break; - } - while (l > 0) { - int n = 0; - - if (l > 0) { - if (!base64[b[0]] || !base64[b[1]]) - break; - n = base64num[*b++] << 18; - n |= base64num[*b++] << 12; - *out++ = n >> 16; total++; - l -= 2; - } - if (l > 0) { - if (*b == '=') - break; - if (!base64[*b]) - break; - n |= base64num[*b++] << 6; - *out++ = (n >> 8) & 0xFF; total++; - --l; - } - if (l > 0) { - if (*b == '=') - break; - if (!base64[*b]) - break; - n |= base64num[*b++]; - *out++ = n & 0xFF; total++; - --l; - } - } - if (l && *b != '=') { - archive_set_error(&self->archive->archive, - ARCHIVE_ERRNO_MISC, - "Insufficient compressed data"); - return (ARCHIVE_FATAL); - } - break; - } - } - - __archive_read_filter_consume(self->upstream, ravail); - - *buff = uudecode->out_buff; - uudecode->total += total; - return (total); -} - -static int -uudecode_filter_close(struct archive_read_filter *self) -{ - struct uudecode *uudecode; - - uudecode = (struct uudecode *)self->data; - free(uudecode->in_buff); - free(uudecode->out_buff); - free(uudecode); - - return (ARCHIVE_OK); -} - |