diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-04-10 21:40:19 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-04-10 21:40:19 +0000 |
commit | c6758a07c68033627a692cda27aebc8f6a662e7f (patch) | |
tree | 51bc0b498a5e16f8041604d913e25708cc76058f /archival | |
parent | 335b63d8d1876ce4e172ebcc9d64544785682244 (diff) | |
download | busybox-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.c | 2 | ||||
-rw-r--r-- | archival/libunarchive/decompress_bunzip2.c | 58 | ||||
-rw-r--r-- | archival/libunarchive/decompress_unzip.c | 2 | ||||
-rw-r--r-- | archival/libunarchive/get_header_tar_gz.c | 2 |
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 | ||
65 | typedef struct { | 65 | struct 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 | ||
522 | static int read_bunzip(bunzip_data *bd, char *outbuf, int len) | 520 | int 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 | ||
634 | static 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 | |||
637 | int 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, | 693 | void 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 | ||
687 | USE_DESKTOP(long long) int | 702 | USE_DESKTOP(long long) int |
688 | uncompressStream(int src_fd, int dst_fd) | 703 | uncompressStream(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 | ||