aboutsummaryrefslogtreecommitdiff
path: root/archival
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-04-10 21:40:19 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-04-10 21:40:19 +0000
commitc6758a07c68033627a692cda27aebc8f6a662e7f (patch)
tree51bc0b498a5e16f8041604d913e25708cc76058f /archival
parent335b63d8d1876ce4e172ebcc9d64544785682244 (diff)
downloadbusybox-w32-c6758a07c68033627a692cda27aebc8f6a662e7f.tar.gz
busybox-w32-c6758a07c68033627a692cda27aebc8f6a662e7f.tar.bz2
busybox-w32-c6758a07c68033627a692cda27aebc8f6a662e7f.zip
make compressed help code NOMMU- and NOFORK-friendly -
no forking anymore, bunzip2 unpack routine now does all it in memory.
Diffstat (limited to 'archival')
-rw-r--r--archival/gzip.c2
-rw-r--r--archival/libunarchive/decompress_bunzip2.c58
-rw-r--r--archival/libunarchive/decompress_unzip.c2
-rw-r--r--archival/libunarchive/get_header_tar_gz.c2
4 files changed, 38 insertions, 26 deletions
diff --git a/archival/gzip.c b/archival/gzip.c
index 39391dfda..561f1088c 100644
--- a/archival/gzip.c
+++ b/archival/gzip.c
@@ -2079,7 +2079,7 @@ int gzip_main(int argc, char **argv)
2079 ALLOC(ush, G1.prev, 1L << BITS); 2079 ALLOC(ush, G1.prev, 1L << BITS);
2080 2080
2081 /* Initialise the CRC32 table */ 2081 /* Initialise the CRC32 table */
2082 G1.crc_32_tab = crc32_filltable(0); 2082 G1.crc_32_tab = crc32_filltable(NULL, 0);
2083 2083
2084 return bbunpack(argv, make_new_name_gzip, pack_gzip); 2084 return bbunpack(argv, make_new_name_gzip, pack_gzip);
2085} 2085}
diff --git a/archival/libunarchive/decompress_bunzip2.c b/archival/libunarchive/decompress_bunzip2.c
index d4db40ece..3f0b0f6f2 100644
--- a/archival/libunarchive/decompress_bunzip2.c
+++ b/archival/libunarchive/decompress_bunzip2.c
@@ -62,34 +62,31 @@ struct group_data {
62/* Structure holding all the housekeeping data, including IO buffers and 62/* Structure holding all the housekeeping data, including IO buffers and
63 memory that persists between calls to bunzip */ 63 memory that persists between calls to bunzip */
64 64
65typedef struct { 65struct bunzip_data {
66 /* State for interrupting output loop */ 66 /* State for interrupting output loop */
67
68 int writeCopies, writePos, writeRunCountdown, writeCount, writeCurrent; 67 int writeCopies, writePos, writeRunCountdown, writeCount, writeCurrent;
69 68
70 /* I/O tracking data (file handles, buffers, positions, etc.) */ 69 /* I/O tracking data (file handles, buffers, positions, etc.) */
71
72 int in_fd, out_fd, inbufCount, inbufPos /*, outbufPos*/; 70 int in_fd, out_fd, inbufCount, inbufPos /*, outbufPos*/;
73 unsigned char *inbuf /*,*outbuf*/; 71 unsigned char *inbuf /*,*outbuf*/;
74 unsigned inbufBitCount, inbufBits; 72 unsigned inbufBitCount, inbufBits;
75 73
76 /* The CRC values stored in the block header and calculated from the data */ 74 /* The CRC values stored in the block header and calculated from the data */
77
78 uint32_t headerCRC, totalCRC, writeCRC; 75 uint32_t headerCRC, totalCRC, writeCRC;
79 uint32_t *crc32Table;
80 /* Intermediate buffer and its size (in bytes) */
81 76
77 /* Intermediate buffer and its size (in bytes) */
82 unsigned *dbuf, dbufSize; 78 unsigned *dbuf, dbufSize;
83 79
84 /* These things are a bit too big to go on the stack */ 80 /* For I/O error handling */
81 jmp_buf jmpbuf;
85 82
83 /* Big things go last (register-relative addressing can be larger for big offsets */
84 uint32_t crc32Table[256];
86 unsigned char selectors[32768]; /* nSelectors=15 bits */ 85 unsigned char selectors[32768]; /* nSelectors=15 bits */
87 struct group_data groups[MAX_GROUPS]; /* Huffman coding tables */ 86 struct group_data groups[MAX_GROUPS]; /* Huffman coding tables */
87};
88/* typedef struct bunzip_data bunzip_data; -- done in .h file */
88 89
89 /* For I/O error handling */
90
91 jmp_buf jmpbuf;
92} bunzip_data;
93 90
94/* Return the next nnn bits of input. All reads from the compressed input 91/* Return the next nnn bits of input. All reads from the compressed input
95 are done through this function. All reads are big endian */ 92 are done through this function. All reads are big endian */
@@ -106,6 +103,7 @@ static unsigned get_bits(bunzip_data *bd, char bits_wanted)
106 /* If we need to read more data from file into byte buffer, do so */ 103 /* If we need to read more data from file into byte buffer, do so */
107 104
108 if (bd->inbufPos == bd->inbufCount) { 105 if (bd->inbufPos == bd->inbufCount) {
106 /* if "no input fd" case: in_fd == -1, read fails, we jump */
109 bd->inbufCount = read(bd->in_fd, bd->inbuf, IOBUF_SIZE); 107 bd->inbufCount = read(bd->in_fd, bd->inbuf, IOBUF_SIZE);
110 if (bd->inbufCount <= 0) 108 if (bd->inbufCount <= 0)
111 longjmp(bd->jmpbuf, RETVAL_UNEXPECTED_INPUT_EOF); 109 longjmp(bd->jmpbuf, RETVAL_UNEXPECTED_INPUT_EOF);
@@ -519,7 +517,7 @@ static int get_next_block(bunzip_data *bd)
519 are ignored, data is written to out_fd and return is RETVAL_OK or error. 517 are ignored, data is written to out_fd and return is RETVAL_OK or error.
520*/ 518*/
521 519
522static int read_bunzip(bunzip_data *bd, char *outbuf, int len) 520int read_bunzip(bunzip_data *bd, char *outbuf, int len)
523{ 521{
524 const unsigned *dbuf; 522 const unsigned *dbuf;
525 int pos, current, previous, gotcount; 523 int pos, current, previous, gotcount;
@@ -627,11 +625,16 @@ static int read_bunzip(bunzip_data *bd, char *outbuf, int len)
627 goto decode_next_byte; 625 goto decode_next_byte;
628} 626}
629 627
628
630/* Allocate the structure, read file header. If in_fd==-1, inbuf must contain 629/* Allocate the structure, read file header. If in_fd==-1, inbuf must contain
631 a complete bunzip file (len bytes long). If in_fd!=-1, inbuf and len are 630 a complete bunzip file (len bytes long). If in_fd!=-1, inbuf and len are
632 ignored, and data is read from file handle into temporary buffer. */ 631 ignored, and data is read from file handle into temporary buffer. */
633 632
634static int start_bunzip(bunzip_data **bdp, int in_fd, unsigned char *inbuf, 633/* Because bunzip2 is used for help text unpacking, and because bb_show_usage()
634 should work for NOFORK applets too, we must be extremely careful to not leak
635 any allocations! */
636
637int start_bunzip(bunzip_data **bdp, int in_fd, const unsigned char *inbuf,
635 int len) 638 int len)
636{ 639{
637 bunzip_data *bd; 640 bunzip_data *bd;
@@ -653,14 +656,15 @@ static int start_bunzip(bunzip_data **bdp, int in_fd, unsigned char *inbuf,
653 656
654 bd->in_fd = in_fd; 657 bd->in_fd = in_fd;
655 if (-1 == in_fd) { 658 if (-1 == in_fd) {
656 bd->inbuf = inbuf; 659 /* in this case, bd->inbuf is read-only */
660 bd->inbuf = (void*)inbuf; /* cast away const-ness */
657 bd->inbufCount = len; 661 bd->inbufCount = len;
658 } else 662 } else
659 bd->inbuf = (unsigned char *)(bd + 1); 663 bd->inbuf = (unsigned char *)(bd + 1);
660 664
661 /* Init the CRC32 table (big endian) */ 665 /* Init the CRC32 table (big endian) */
662 666
663 bd->crc32Table = crc32_filltable(1); 667 crc32_filltable(bd->crc32Table, 1);
664 668
665 /* Setup for I/O error handling via longjmp */ 669 /* Setup for I/O error handling via longjmp */
666 670
@@ -670,19 +674,30 @@ static int start_bunzip(bunzip_data **bdp, int in_fd, unsigned char *inbuf,
670 /* Ensure that file starts with "BZh['1'-'9']." */ 674 /* Ensure that file starts with "BZh['1'-'9']." */
671 675
672 i = get_bits(bd, 32); 676 i = get_bits(bd, 32);
673 if (((unsigned)(i - BZh0 - 1)) >= 9) return RETVAL_NOT_BZIP_DATA; 677 if ((unsigned)(i - BZh0 - 1) >= 9) return RETVAL_NOT_BZIP_DATA;
674 678
675 /* Fourth byte (ascii '1'-'9'), indicates block size in units of 100k of 679 /* Fourth byte (ascii '1'-'9'), indicates block size in units of 100k of
676 uncompressed data. Allocate intermediate buffer for block. */ 680 uncompressed data. Allocate intermediate buffer for block. */
677 681
678 bd->dbufSize = 100000 * (i - BZh0); 682 bd->dbufSize = 100000 * (i - BZh0);
679 683
680 bd->dbuf = xmalloc(bd->dbufSize * sizeof(int)); 684 /* Cannot use xmalloc - may leak bd in NOFORK case! */
685 bd->dbuf = malloc_or_warn(bd->dbufSize * sizeof(int));
686 if (!bd->dbuf) {
687 free(bd);
688 xfunc_die();
689 }
681 return RETVAL_OK; 690 return RETVAL_OK;
682} 691}
683 692
684/* Example usage: decompress src_fd to dst_fd. (Stops at end of bzip data, 693void dealloc_bunzip(bunzip_data *bd)
685 not end of file.) */ 694{
695 free(bd->dbuf);
696 free(bd);
697}
698
699
700/* Decompress src_fd to dst_fd. Stops at end of bzip data, not end of file. */
686 701
687USE_DESKTOP(long long) int 702USE_DESKTOP(long long) int
688uncompressStream(int src_fd, int dst_fd) 703uncompressStream(int src_fd, int dst_fd)
@@ -693,7 +708,7 @@ uncompressStream(int src_fd, int dst_fd)
693 int i; 708 int i;
694 709
695 outbuf = xmalloc(IOBUF_SIZE); 710 outbuf = xmalloc(IOBUF_SIZE);
696 i = start_bunzip(&bd, src_fd, 0, 0); 711 i = start_bunzip(&bd, src_fd, NULL, 0);
697 if (!i) { 712 if (!i) {
698 for (;;) { 713 for (;;) {
699 i = read_bunzip(bd, outbuf, IOBUF_SIZE); 714 i = read_bunzip(bd, outbuf, IOBUF_SIZE);
@@ -719,8 +734,7 @@ uncompressStream(int src_fd, int dst_fd)
719 } else { 734 } else {
720 bb_error_msg("decompression failed"); 735 bb_error_msg("decompression failed");
721 } 736 }
722 free(bd->dbuf); 737 dealloc_bunzip(bd);
723 free(bd);
724 free(outbuf); 738 free(outbuf);
725 739
726 return i ? i : USE_DESKTOP(total_written) + 0; 740 return i ? i : USE_DESKTOP(total_written) + 0;
diff --git a/archival/libunarchive/decompress_unzip.c b/archival/libunarchive/decompress_unzip.c
index 331fe34d8..19ce5097a 100644
--- a/archival/libunarchive/decompress_unzip.c
+++ b/archival/libunarchive/decompress_unzip.c
@@ -1000,7 +1000,7 @@ inflate_unzip_internal(STATE_PARAM int in, int out)
1000 gunzip_bb = 0; 1000 gunzip_bb = 0;
1001 1001
1002 /* Create the crc table */ 1002 /* Create the crc table */
1003 gunzip_crc_table = crc32_filltable(0); 1003 gunzip_crc_table = crc32_filltable(NULL, 0);
1004 gunzip_crc = ~0; 1004 gunzip_crc = ~0;
1005 1005
1006 /* Allocate space for buffer */ 1006 /* Allocate space for buffer */
diff --git a/archival/libunarchive/get_header_tar_gz.c b/archival/libunarchive/get_header_tar_gz.c
index 1f07e4e64..69126e0ba 100644
--- a/archival/libunarchive/get_header_tar_gz.c
+++ b/archival/libunarchive/get_header_tar_gz.c
@@ -3,8 +3,6 @@
3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
4 */ 4 */
5 5
6#include <stdlib.h>
7
8#include "libbb.h" 6#include "libbb.h"
9#include "unarchive.h" 7#include "unarchive.h"
10 8