diff options
Diffstat (limited to 'packages/busybox/busybox-1.00/unzip-enhancement-and-fixes.patch')
-rw-r--r-- | packages/busybox/busybox-1.00/unzip-enhancement-and-fixes.patch | 878 |
1 files changed, 0 insertions, 878 deletions
diff --git a/packages/busybox/busybox-1.00/unzip-enhancement-and-fixes.patch b/packages/busybox/busybox-1.00/unzip-enhancement-and-fixes.patch deleted file mode 100644 index 49542cab1d..0000000000 --- a/packages/busybox/busybox-1.00/unzip-enhancement-and-fixes.patch +++ /dev/null @@ -1,878 +0,0 @@ - -Index: archival/unzip.c -=================================================================== -RCS file: /var/cvs/busybox/archival/unzip.c,v -retrieving revision 1.8 -diff -u -r1.8 unzip.c ---- archival/unzip.c 6 Jun 2004 10:22:43 -0000 1.8 -+++ archival/unzip.c 18 Oct 2004 01:32:25 -0000 -@@ -2,7 +2,10 @@ - /* - * Mini unzip implementation for busybox - * -- * Copyright (C) 2001 by Laurence Anderson -+ * Copyright (C) 2004 by Ed Clark -+ * -+ * Loosely based on original busybox unzip applet by Laurence Anderson. -+ * All options and features should work in this version. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by -@@ -21,17 +24,25 @@ - */ - - /* For reference see -- * http://www.pkware.com/products/enterprise/white_papers/appnote.txt -+ * http://www.pkware.com/company/standards/appnote/ - * http://www.info-zip.org/pub/infozip/doc/appnote-iz-latest.zip - */ - --/* TODO Endian issues, exclude, should we accept input from stdin ? */ -+/* TODO -+ * Endian issues -+ * Zip64 + other methods -+ * Improve handling of zip format, ie. -+ * - deferred CRC, comp. & uncomp. lengths (zip header flags bit 3) -+ * - unix file permissions, etc. -+ * - central directory -+ */ - - #include <fcntl.h> - #include <getopt.h> - #include <stdlib.h> - #include <string.h> - #include <unistd.h> -+#include <errno.h> - #include "unarchive.h" - #include "busybox.h" - -@@ -43,205 +54,353 @@ - extern unsigned int gunzip_crc; - extern unsigned int gunzip_bytes_out; - --static void header_list_unzip(const file_header_t *file_header) -+typedef union { -+ unsigned char raw[26]; -+ struct { -+ unsigned short version; /* 0-1 */ -+ unsigned short flags; /* 2-3 */ -+ unsigned short method; /* 4-5 */ -+ unsigned short modtime; /* 6-7 */ -+ unsigned short moddate; /* 8-9 */ -+ unsigned int crc32 __attribute__ ((packed)); /* 10-13 */ -+ unsigned int cmpsize __attribute__ ((packed)); /* 14-17 */ -+ unsigned int ucmpsize __attribute__ ((packed)); /* 18-21 */ -+ unsigned short filename_len; /* 22-23 */ -+ unsigned short extra_len; /* 24-25 */ -+ } formated __attribute__ ((packed)); -+} zip_header_t; -+ -+static void unzip_skip(int fd, off_t skip) - { -- printf(" inflating: %s\n", file_header->name); -+ if (lseek(fd, skip, SEEK_CUR) == (off_t)-1) { -+ if ((errno != ESPIPE) || (bb_copyfd_size(fd, -1, skip) != skip)) { -+ bb_error_msg_and_die("Seek failure"); -+ } -+ } - } - --static void header_verbose_list_unzip(const file_header_t *file_header) -+static void unzip_read(int fd, void *buf, size_t count) - { -- unsigned int dostime = (unsigned int) file_header->mtime; -+ if (bb_xread(fd, buf, count) != count) { -+ bb_error_msg_and_die("Read failure"); -+ } -+} - -- /* can printf arguments cut of the decade component ? */ -- unsigned short year = 1980 + ((dostime & 0xfe000000) >> 25); -- while (year >= 100) { -- year -= 100; -- } -- -- printf("%9u %02u-%02u-%02u %02u:%02u %s\n", -- (unsigned int) file_header->size, -- (dostime & 0x01e00000) >> 21, -- (dostime & 0x001f0000) >> 16, -- year, -- (dostime & 0x0000f800) >> 11, -- (dostime & 0x000007e0) >> 5, -- file_header->name); -+static void unzip_create_leading_dirs(char *fn) -+{ -+ /* Create all leading directories */ -+ char *name = bb_xstrdup(fn); -+ if (bb_make_directory(dirname(name), 0777, FILEUTILS_RECUR)) { -+ bb_error_msg_and_die("Failed to create directory"); -+ } -+ free(name); - } - --extern int unzip_main(int argc, char **argv) -+static void unzip_extract(zip_header_t *zip_header, int src_fd, int dst_fd) - { -- union { -- unsigned char raw[26]; -- struct { -- unsigned short version; /* 0-1 */ -- unsigned short flags; /* 2-3 */ -- unsigned short method; /* 4-5 */ -- unsigned short modtime; /* 6-7 */ -- unsigned short moddate; /* 8-9 */ -- unsigned int crc32 __attribute__ ((packed)); /* 10-13 */ -- unsigned int cmpsize __attribute__ ((packed));; /* 14-17 */ -- unsigned int ucmpsize __attribute__ ((packed));; /* 18-21 */ -- unsigned short filename_len; /* 22-23 */ -- unsigned short extra_len; /* 24-25 */ -- } formated __attribute__ ((packed)); -- } zip_header; -+ if (zip_header->formated.method == 0) { -+ /* Method 0 - stored (not compressed) */ -+ int size = zip_header->formated.ucmpsize; -+ if (size && (bb_copyfd_size(src_fd, dst_fd, size) != size)) { -+ bb_error_msg_and_die("Cannot complete extraction"); -+ } -+ -+ } else { -+ /* Method 8 - inflate */ -+ inflate_init(zip_header->formated.cmpsize); -+ inflate_unzip(src_fd, dst_fd); -+ inflate_cleanup(); -+ /* Validate decompression - crc */ -+ if (zip_header->formated.crc32 != (gunzip_crc ^ 0xffffffffL)) { -+ bb_error_msg("Invalid compressed data--crc error"); -+ } -+ /* Validate decompression - size */ -+ if (zip_header->formated.ucmpsize != gunzip_bytes_out) { -+ bb_error_msg("Invalid compressed data--length error"); -+ } -+ } -+} - -- archive_handle_t *archive_handle; -+extern int unzip_main(int argc, char **argv) -+{ -+ zip_header_t zip_header; -+ enum {v_silent, v_normal, v_list} verbosity = v_normal; -+ enum {o_prompt, o_never, o_always} overwrite = o_prompt; - unsigned int total_size = 0; - unsigned int total_entries = 0; -+ int src_fd = -1, dst_fd = -1; -+ char *src_fn = NULL, *dst_fn = NULL; -+ llist_t *accept = NULL; -+ llist_t *reject = NULL; - char *base_dir = NULL; -- int opt = 0; -- -- /* Initialise */ -- archive_handle = init_handle(); -- archive_handle->action_data = NULL; -- archive_handle->action_header = header_list_unzip; -- -- while ((opt = getopt(argc, argv, "lnopqd:")) != -1) { -- switch (opt) { -- case 'l': /* list */ -- archive_handle->action_header = header_verbose_list_unzip; -- archive_handle->action_data = data_skip; -- break; -- case 'n': /* never overwright existing files */ -+ int i, opt, opt_range = 0, list_header_done = 0; -+ char key_buf[512]; -+ struct stat stat_buf; -+ -+ while((opt = getopt(argc, argv, "-d:lnopqx")) != -1) { -+ switch(opt_range) { -+ case 0: /* Options */ -+ switch(opt) { -+ case 'l': /* List */ -+ verbosity = v_list; - break; -- case 'o': -- archive_handle->flags = ARCHIVE_EXTRACT_UNCONDITIONAL; -+ -+ case 'n': /* Never overwrite existing files */ -+ overwrite = o_never; - break; -- case 'p': /* extract files to stdout */ -- archive_handle->action_data = data_extract_to_stdout; -+ -+ case 'o': /* Always overwrite existing files */ -+ overwrite = o_always; - break; -- case 'q': /* Extract files quietly */ -- archive_handle->action_header = header_skip; -+ -+ case 'p': /* Extract files to stdout and fall through to set verbosity */ -+ dst_fd = STDOUT_FILENO; -+ -+ case 'q': /* Be quiet */ -+ verbosity = (verbosity == v_normal) ? v_silent : verbosity; - break; -- case 'd': /* Extract files to specified base directory*/ -- base_dir = optarg; -- break; --#if 0 -- case 'x': /* Exclude the specified files */ -- archive_handle->filter = filter_accept_reject_list; -+ -+ case 1 : /* The zip file */ -+ src_fn = bb_xstrndup(optarg, strlen(optarg)+4); -+ opt_range++; - break; --#endif -+ - default: - bb_show_usage(); -+ -+ } -+ break; -+ -+ case 1: /* Include files */ -+ if (opt == 1) { -+ accept = llist_add_to(accept, optarg); -+ -+ } else if (opt == 'd') { -+ base_dir = optarg; -+ opt_range += 2; -+ -+ } else if (opt == 'x') { -+ opt_range++; -+ -+ } else { -+ bb_show_usage(); -+ } -+ break; -+ -+ case 2 : /* Exclude files */ -+ if (opt == 1) { -+ reject = llist_add_to(reject, optarg); -+ -+ } else if (opt == 'd') { /* Extract to base directory */ -+ base_dir = optarg; -+ opt_range++; -+ -+ } else { -+ bb_show_usage(); -+ } -+ break; -+ -+ default: -+ bb_show_usage(); - } - } -- -- if (argc == optind) { -+ -+ if (src_fn == NULL) { - bb_show_usage(); - } - -- printf("Archive: %s\n", argv[optind]); -- if (archive_handle->action_header == header_verbose_list_unzip) { -- printf(" Length Date Time Name\n"); -- printf(" -------- ---- ---- ----\n"); -- } -- -- if (*argv[optind] == '-') { -- archive_handle->src_fd = STDIN_FILENO; -- archive_handle->seek = seek_by_char; -+ /* Open input file */ -+ if (strcmp("-", src_fn) == 0) { -+ src_fd = STDIN_FILENO; -+ /* Cannot use prompt mode since zip data is arriving on STDIN */ -+ overwrite = (overwrite == o_prompt) ? o_never : overwrite; -+ - } else { -- archive_handle->src_fd = bb_xopen(argv[optind++], O_RDONLY); -+ char *extn[] = {"", ".zip", ".ZIP"}; -+ int orig_src_fn_len = strlen(src_fn); -+ for(i = 0; (i < 3) && (src_fd == -1); i++) { -+ strcpy(src_fn + orig_src_fn_len, extn[i]); -+ src_fd = open(src_fn, O_RDONLY); -+ } -+ if (src_fd == -1) { -+ src_fn[orig_src_fn_len] = 0; -+ bb_error_msg_and_die("Cannot open %s, %s.zip, %s.ZIP", src_fn, src_fn, src_fn); -+ } - } - -- if ((base_dir) && (chdir(base_dir))) { -- bb_perror_msg_and_die("Couldnt chdir"); -+ /* Change dir if necessary */ -+ if (base_dir && chdir(base_dir)) { -+ bb_perror_msg_and_die("Cannot chdir"); - } - -- while (optind < argc) { -- archive_handle->filter = filter_accept_list; -- archive_handle->accept = llist_add_to(archive_handle->accept, argv[optind]); -- optind++; -- } -+ if (verbosity != v_silent) -+ printf("Archive: %s\n", src_fn); - - while (1) { - unsigned int magic; -- int dst_fd; -- -- /* TODO Endian issues */ -- archive_xread_all(archive_handle, &magic, 4); -- archive_handle->offset += 4; - -+ /* Check magic number */ -+ unzip_read(src_fd, &magic, 4); - if (magic == ZIP_CDS_MAGIC) { - break; -+ } else if (magic != ZIP_FILEHEADER_MAGIC) { -+ bb_error_msg_and_die("Invalid zip magic %08X", magic); - } -- else if (magic != ZIP_FILEHEADER_MAGIC) { -- bb_error_msg_and_die("Invlaide zip magic"); -- } -- -+ - /* Read the file header */ -- archive_xread_all(archive_handle, zip_header.raw, 26); -- archive_handle->offset += 26; -- archive_handle->file_header->mode = S_IFREG | 0777; -- -- if (zip_header.formated.method != 8) { -- bb_error_msg_and_die("Unsupported compression method %d\n", zip_header.formated.method); -+ unzip_read(src_fd, zip_header.raw, 26); -+ if ((zip_header.formated.method != 0) && (zip_header.formated.method != 8)) { -+ bb_error_msg_and_die("Unsupported compression method %d", zip_header.formated.method); - } - - /* Read filename */ -- archive_handle->file_header->name = xmalloc(zip_header.formated.filename_len + 1); -- archive_xread_all(archive_handle, archive_handle->file_header->name, zip_header.formated.filename_len); -- archive_handle->offset += zip_header.formated.filename_len; -- archive_handle->file_header->name[zip_header.formated.filename_len] = '\0'; -- -- /* Skip extra header bits */ -- archive_handle->file_header->size = zip_header.formated.extra_len; -- data_skip(archive_handle); -- archive_handle->offset += zip_header.formated.extra_len; -- -- /* Handle directories */ -- archive_handle->file_header->mode = S_IFREG | 0777; -- if (last_char_is(archive_handle->file_header->name, '/')) { -- archive_handle->file_header->mode ^= S_IFREG; -- archive_handle->file_header->mode |= S_IFDIR; -- } -- -- /* Data section */ -- archive_handle->file_header->size = zip_header.formated.cmpsize; -- if (archive_handle->action_data) { -- archive_handle->action_data(archive_handle); -- } else { -- dst_fd = bb_xopen(archive_handle->file_header->name, O_WRONLY | O_CREAT); -- inflate_init(zip_header.formated.cmpsize); -- inflate_unzip(archive_handle->src_fd, dst_fd); -- close(dst_fd); -- chmod(archive_handle->file_header->name, archive_handle->file_header->mode); -- -- /* Validate decompression - crc */ -- if (zip_header.formated.crc32 != (gunzip_crc ^ 0xffffffffL)) { -- bb_error_msg("Invalid compressed data--crc error"); -- } -- -- /* Validate decompression - size */ -- if (gunzip_bytes_out != zip_header.formated.ucmpsize) { -- bb_error_msg("Invalid compressed data--length error"); -- } -+ free(dst_fn); -+ dst_fn = xmalloc(zip_header.formated.filename_len + 1); -+ unzip_read(src_fd, dst_fn, zip_header.formated.filename_len); -+ dst_fn[zip_header.formated.filename_len] = 0; -+ -+ /* Skip extra header bytes */ -+ unzip_skip(src_fd, zip_header.formated.extra_len); -+ -+ if ((verbosity == v_list) && !list_header_done){ -+ printf(" Length Date Time Name\n"); -+ printf(" -------- ---- ---- ----\n"); -+ list_header_done = 1; - } - -- /* local file descriptor section */ -- archive_handle->offset += zip_header.formated.cmpsize; -- /* This ISNT unix time */ -- archive_handle->file_header->mtime = zip_header.formated.modtime | (zip_header.formated.moddate << 16); -- archive_handle->file_header->size = zip_header.formated.ucmpsize; -- total_size += archive_handle->file_header->size; -- total_entries++; -+ /* Filter zip entries */ -+ if (find_list_entry(reject, dst_fn) || -+ (accept && !find_list_entry(accept, dst_fn))) { /* Skip entry */ -+ i = 'n'; -+ -+ } else { /* Extract entry */ -+ total_size += zip_header.formated.ucmpsize; -+ -+ if (verbosity == v_list) { /* List entry */ -+ unsigned int dostime = zip_header.formated.modtime | (zip_header.formated.moddate << 16); -+ printf("%9u %02u-%02u-%02u %02u:%02u %s\n", -+ zip_header.formated.ucmpsize, -+ (dostime & 0x01e00000) >> 21, -+ (dostime & 0x001f0000) >> 16, -+ (((dostime & 0xfe000000) >> 25) + 1980) % 100, -+ (dostime & 0x0000f800) >> 11, -+ (dostime & 0x000007e0) >> 5, -+ dst_fn); -+ total_entries++; -+ i = 'n'; -+ -+ } else if (dst_fd == STDOUT_FILENO) { /* Extracting to STDOUT */ -+ i = -1; -+ -+ } else if (last_char_is(dst_fn, '/')) { /* Extract directory */ -+ if (stat(dst_fn, &stat_buf) == -1) { -+ if (errno != ENOENT) { -+ bb_perror_msg_and_die("Cannot stat '%s'",dst_fn); -+ } -+ if (verbosity == v_normal) { -+ printf(" creating: %s\n", dst_fn); -+ } -+ unzip_create_leading_dirs(dst_fn); -+ if (bb_make_directory(dst_fn, 0777, 0)) { -+ bb_error_msg_and_die("Failed to create directory"); -+ } -+ } else { -+ if (!S_ISDIR(stat_buf.st_mode)) { -+ bb_error_msg_and_die("'%s' exists but is not directory", dst_fn); -+ } -+ } -+ i = 'n'; -+ -+ } else { /* Extract file */ -+ _check_file: -+ if (stat(dst_fn, &stat_buf) == -1) { /* File does not exist */ -+ if (errno != ENOENT) { -+ bb_perror_msg_and_die("Cannot stat '%s'",dst_fn); -+ } -+ i = 'y'; -+ -+ } else { /* File already exists */ -+ if (overwrite == o_never) { -+ i = 'n'; -+ -+ } else if (S_ISREG(stat_buf.st_mode)) { /* File is regular file */ -+ if (overwrite == o_always) { -+ i = 'y'; -+ } else { -+ printf("replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ", dst_fn); -+ if (!fgets(key_buf, 512, stdin)) { -+ bb_perror_msg_and_die("Cannot read input"); -+ } -+ i = key_buf[0]; -+ } -+ -+ } else { /* File is not regular file */ -+ bb_error_msg_and_die("'%s' exists but is not regular file",dst_fn); -+ } -+ } -+ } -+ } - -- archive_handle->action_header(archive_handle->file_header); -+ switch (i) { -+ case 'A': -+ overwrite = o_always; -+ case 'y': /* Open file and fall into unzip */ -+ unzip_create_leading_dirs(dst_fn); -+ dst_fd = bb_xopen(dst_fn, O_WRONLY | O_CREAT); -+ case -1: /* Unzip */ -+ if (verbosity == v_normal) { -+ printf(" inflating: %s\n", dst_fn); -+ } -+ unzip_extract(&zip_header, src_fd, dst_fd); -+ if (dst_fd != STDOUT_FILENO) { -+ /* closing STDOUT is potentially bad for future business */ -+ close(dst_fd); -+ } -+ break; - -+ case 'N': -+ overwrite = o_never; -+ case 'n': -+ /* Skip entry data */ -+ unzip_skip(src_fd, zip_header.formated.cmpsize); -+ break; -+ -+ case 'r': -+ /* Prompt for new name */ -+ printf("new name: "); -+ if (!fgets(key_buf, 512, stdin)) { -+ bb_perror_msg_and_die("Cannot read input"); -+ } -+ free(dst_fn); -+ dst_fn = bb_xstrdup(key_buf); -+ chomp(dst_fn); -+ goto _check_file; -+ -+ default: -+ printf("error: invalid response [%c]\n",(char)i); -+ goto _check_file; -+ } -+ - /* Data descriptor section */ - if (zip_header.formated.flags & 4) { - /* skip over duplicate crc, compressed size and uncompressed size */ -- unsigned char data_description[12]; -- archive_xread_all(archive_handle, data_description, 12); -- archive_handle->offset += 12; -+ unzip_skip(src_fd, 12); - } - } -- /* Central directory section */ - -- if (archive_handle->action_header == header_verbose_list_unzip) { -+ if (verbosity == v_list) { - printf(" -------- -------\n"); - printf("%9d %d files\n", total_size, total_entries); - } -- -+ - return(EXIT_SUCCESS); - } -+ -+/* END CODE */ -+/* -+Local Variables: -+c-file-style: "linux" -+c-basic-offset: 4 -+tab-width: 4 -+End: -+*/ -Index: archival/libunarchive/decompress_unzip.c -=================================================================== -RCS file: /var/cvs/busybox/archival/libunarchive/decompress_unzip.c,v -retrieving revision 1.35 -diff -u -r1.35 decompress_unzip.c ---- archival/libunarchive/decompress_unzip.c 25 Apr 2004 05:11:13 -0000 1.35 -+++ archival/libunarchive/decompress_unzip.c 18 Oct 2004 01:32:29 -0000 -@@ -16,6 +16,11 @@ - * - * read_gz interface + associated hacking by Laurence Anderson - * -+ * Fixed huft_build() so decoding end-of-block code does not grab more bits -+ * than necessary (this is required by unzip applet), added inflate_cleanup() -+ * to free leaked bytebuffer memory (used in unzip.c), and some minor style -+ * guide cleanups by Ed Clark -+ * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or -@@ -116,26 +121,26 @@ - /* Copy lengths for literal codes 257..285 */ - static const unsigned short cplens[] = { - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, -- 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 -+ 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 - }; - - /* note: see note #13 above about the 258 in this list. */ - /* Extra bits for literal codes 257..285 */ - static const unsigned char cplext[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, -- 5, 5, 5, 0, 99, 99 -+ 5, 5, 5, 0, 99, 99 - }; /* 99==invalid */ - - /* Copy offsets for distance codes 0..29 */ - static const unsigned short cpdist[] = { - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, -- 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 -+ 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 - }; - - /* Extra bits for distance codes */ - static const unsigned char cpdext[] = { - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, -- 11, 11, 12, 12, 13, 13 -+ 11, 11, 12, 12, 13, 13 - }; - - /* Tables for deflate from PKZIP's appnote.txt. */ -@@ -184,8 +189,8 @@ - table_entry = (table_entry >> 1) ^ poly; - } else { - table_entry >>= 1; -- } -- } -+ } -+ } - gunzip_crc_table[i] = table_entry; - } - } -@@ -225,70 +230,59 @@ - * t: result: starting table - * m: maximum lookup bits, returns actual - */ --static int huft_build(unsigned int *b, const unsigned int n, -- const unsigned int s, const unsigned short *d, -- const unsigned char *e, huft_t ** t, int *m) -+int huft_build(unsigned int *b, const unsigned int n, -+ const unsigned int s, const unsigned short *d, -+ const unsigned char *e, huft_t ** t, int *m) - { -- unsigned a; /* counter for codes of length k */ -+ unsigned a; /* counter for codes of length k */ - unsigned c[BMAX + 1]; /* bit length count table */ -- unsigned f; /* i repeats in table every f entries */ -- int g; /* maximum code length */ -- int h; /* table level */ -+ unsigned eob_len; /* length of end-of-block code (value 256) */ -+ unsigned f; /* i repeats in table every f entries */ -+ int g; /* maximum code length */ -+ int h; /* table level */ - register unsigned i; /* counter, current code */ - register unsigned j; /* counter */ -- register int k; /* number of bits in current code */ -- int l; /* bits per table (returned in m) */ -+ register int k; /* number of bits in current code */ - register unsigned *p; /* pointer into c[], b[], or v[] */ -- register huft_t *q; /* points to current table */ -- huft_t r; /* table entry for structure assignment */ -- huft_t *u[BMAX]; /* table stack */ -- unsigned v[N_MAX]; /* values in order of bit length */ -- register int w; /* bits before this table == (l * h) */ -+ register huft_t *q; /* points to current table */ -+ huft_t r; /* table entry for structure assignment */ -+ huft_t *u[BMAX]; /* table stack */ -+ unsigned v[N_MAX]; /* values in order of bit length */ -+ int ws[BMAX+1]; /* bits decoded stack */ -+ register int w; /* bits decoded */ - unsigned x[BMAX + 1]; /* bit offsets, then code stack */ -- unsigned *xp; /* pointer into x */ -- int y; /* number of dummy codes added */ -- unsigned z; /* number of entries in current table */ -+ unsigned *xp; /* pointer into x */ -+ int y; /* number of dummy codes added */ -+ unsigned z; /* number of entries in current table */ -+ -+ /* Length of EOB code, if any */ -+ eob_len = n > 256 ? b[256] : BMAX; - - /* Generate counts for each bit length */ -- memset((void *) (c), 0, sizeof(c)); -+ memset((void *)c, 0, sizeof(c)); - p = b; - i = n; - do { -- c[*p]++; /* assume all entries <= BMAX */ -- p++; /* Can't combine with above line (Solaris bug) */ -+ c[*p]++; /* assume all entries <= BMAX */ -+ p++; /* Can't combine with above line (Solaris bug) */ - } while (--i); -- if (c[0] == n) { /* null input--all zero length codes */ -+ if (c[0] == n) { /* null input--all zero length codes */ - *t = (huft_t *) NULL; - *m = 0; - return 0; - } - - /* Find minimum and maximum length, bound *m by those */ -- l = *m; -- for (j = 1; j <= BMAX; j++) { -- if (c[j]) { -- break; -- } -- } -- k = j; /* minimum code length */ -- if ((unsigned) l < j) { -- l = j; -- } -- for (i = BMAX; i; i--) { -- if (c[i]) { -- break; -- } -- } -- g = i; /* maximum code length */ -- if ((unsigned) l > i) { -- l = i; -- } -- *m = l; -+ for (j = 1; (c[j] == 0) && (j <= BMAX); j++); -+ k = j; /* minimum code length */ -+ for (i = BMAX; (c[i] == 0) && i; i--); -+ g = i; /* maximum code length */ -+ *m = (*m < j) ? j : ((*m > i) ? i : *m); - - /* Adjust last length count to fill out codes, if needed */ - for (y = 1 << j; j < i; j++, y <<= 1) { - if ((y -= c[j]) < 0) { -- return 2; /* bad input: more codes than bits */ -+ return 2; /* bad input: more codes than bits */ - } - } - if ((y -= c[i]) < 0) { -@@ -300,7 +294,7 @@ - x[1] = j = 0; - p = c + 1; - xp = x + 2; -- while (--i) { /* note that i == g from above */ -+ while (--i) { /* note that i == g from above */ - *xp++ = (j += *p++); - } - -@@ -314,13 +308,13 @@ - } while (++i < n); - - /* Generate the Huffman codes and for each, make the table entries */ -- x[0] = i = 0; /* first Huffman code is zero */ -- p = v; /* grab values in bit order */ -- h = -1; /* no tables yet--level -1 */ -- w = -l; /* bits decoded == (l * h) */ -+ x[0] = i = 0; /* first Huffman code is zero */ -+ p = v; /* grab values in bit order */ -+ h = -1; /* no tables yet--level -1 */ -+ w = ws[0] = 0; /* bits decoded */ - u[0] = (huft_t *) NULL; /* just to keep compilers happy */ - q = (huft_t *) NULL; /* ditto */ -- z = 0; /* ditto */ -+ z = 0; /* ditto */ - - /* go through the bit lengths (k already is bits in shortest code) */ - for (; k <= g; k++) { -@@ -328,52 +322,52 @@ - while (a--) { - /* here i is the Huffman code of length k bits for value *p */ - /* make tables up to required level */ -- while (k > w + l) { -- h++; -- w += l; /* previous table always l bits */ -- -- /* compute minimum size table less than or equal to l bits */ -- z = (z = g - w) > (unsigned) l ? l : z; /* upper limit on table size */ -- if ((f = 1 << (j = k - w)) > a + 1) { /* try a k-w bit table *//* too few codes for k-w bit table */ -- f -= a + 1; /* deduct codes from patterns left */ -+ while (k > ws[h + 1]) { -+ w = ws[++h]; -+ -+ /* compute minimum size table less than or equal to *m bits */ -+ z = (z = g - w) > *m ? *m : z; /* upper limit on table size */ -+ if ((f = 1 << (j = k - w)) > a + 1) { /* try a k-w bit table */ -+ /* too few codes for k-w bit table */ -+ f -= a + 1; /* deduct codes from patterns left */ - xp = c + k; -- while (++j < z) { /* try smaller tables up to z bits */ -+ while (++j < z) { /* try smaller tables up to z bits */ - if ((f <<= 1) <= *++xp) { -- break; /* enough codes to use up j bits */ -+ break; /* enough codes to use up j bits */ - } -- f -= *xp; /* else deduct codes from patterns */ -+ f -= *xp; /* else deduct codes from patterns */ - } - } -+ j = (w + j > eob_len && w < eob_len) ? eob_len - w : j; /* make EOB code end at table */ - z = 1 << j; /* table entries for j-bit table */ -+ ws[h+1] = w + j; /* set bits decoded in stack */ - - /* allocate and link in new table */ - q = (huft_t *) xmalloc((z + 1) * sizeof(huft_t)); -- - *t = q + 1; /* link to list for huft_free() */ - *(t = &(q->v.t)) = NULL; - u[h] = ++q; /* table starts after link */ - - /* connect to last table, if there is one */ - if (h) { -- x[h] = i; /* save pattern for backing up */ -- r.b = (unsigned char) l; /* bits to dump before this table */ -- r.e = (unsigned char) (16 + j); /* bits in this table */ -- r.v.t = q; /* pointer to this table */ -- j = i >> (w - l); /* (get around Turbo C bug) */ -- u[h - 1][j] = r; /* connect to last table */ -+ x[h] = i; /* save pattern for backing up */ -+ r.b = (unsigned char) (w - ws[h - 1]); /* bits to dump before this table */ -+ r.e = (unsigned char) (16 + j); /* bits in this table */ -+ r.v.t = q; /* pointer to this table */ -+ j = (i & ((1 << w) - 1)) >> ws[h - 1]; -+ u[h - 1][j] = r; /* connect to last table */ - } - } -- -+ - /* set up table entry in r */ - r.b = (unsigned char) (k - w); - if (p >= v + n) { -- r.e = 99; /* out of values--invalid code */ -+ r.e = 99; /* out of values--invalid code */ - } else if (*p < s) { -- r.e = (unsigned char) (*p < 256 ? 16 : 15); /* 256 is end-of-block code */ -- r.v.n = (unsigned short) (*p); /* simple code is just the value */ -- p++; /* one compiler does not like *p++ */ -+ r.e = (unsigned char) (*p < 256 ? 16 : 15); /* 256 is EOB code */ -+ r.v.n = (unsigned short) (*p++); /* simple code is just the value */ - } else { -- r.e = (unsigned char) e[*p - s]; /* non-simple--look up in lists */ -+ r.e = (unsigned char) e[*p - s]; /* non-simple--look up in lists */ - r.v.n = d[*p++ - s]; - } - -@@ -391,11 +385,14 @@ - - /* backup over finished tables */ - while ((i & ((1 << w) - 1)) != x[h]) { -- h--; /* don't need to update q */ -- w -= l; -+ w = ws[--h]; - } - } - } -+ -+ /* return actual size of base table */ -+ *m = ws[1]; -+ - /* Return true (1) if we were given an incomplete table */ - return y != 0 && g != 1; - } -@@ -901,6 +898,11 @@ - bytebuffer_size = 0; - } - -+extern void inflate_cleanup(void) -+{ -+ free(bytebuffer); -+} -+ - extern int inflate_unzip(int in, int out) - { - ssize_t nwrote; -Index: include/unarchive.h -=================================================================== -RCS file: /var/cvs/busybox/include/unarchive.h,v -retrieving revision 1.23 -diff -u -r1.23 unarchive.h ---- include/unarchive.h 15 Mar 2004 08:28:38 -0000 1.23 -+++ include/unarchive.h 18 Oct 2004 01:32:30 -0000 -@@ -98,6 +98,7 @@ - - extern int uncompressStream(int src_fd, int dst_fd); - extern void inflate_init(unsigned int bufsize); -+extern void inflate_cleanup(void); - extern int inflate_unzip(int in, int out); - extern int inflate_gunzip(int in, int out); - -_________________________________________________________________ -Express yourself instantly with MSN Messenger! Download today it's FREE! -http://messenger.msn.com/ - - ---===============0046497949== -Content-Type: text/plain; charset="iso-8859-1" -MIME-Version: 1.0 -Content-Transfer-Encoding: quoted-printable -Content-Disposition: inline - -_______________________________________________ -busybox mailing list -busybox@mail.busybox.net -http://codepoet.org/mailman/listinfo/busybox - ---===============0046497949==-- |