diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-04-08 20:02:01 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-04-08 20:05:04 +0200 |
commit | 38ccd6af8abbafff98d458a1c62909acfc09a514 (patch) | |
tree | 1a4158db5c7e5e98111ff99d4a9078d93b4ccfcc | |
parent | 8e2174e9bd836e53c8b9c6e00d1bc6e2a718686e (diff) | |
download | busybox-w32-38ccd6af8abbafff98d458a1c62909acfc09a514.tar.gz busybox-w32-38ccd6af8abbafff98d458a1c62909acfc09a514.tar.bz2 busybox-w32-38ccd6af8abbafff98d458a1c62909acfc09a514.zip |
bzip2: fix two crashes on corrupted archives
As it turns out, longjmp'ing into freed stack is not healthy...
function old new delta
unpack_usage_messages - 97 +97
unpack_bz2_stream 369 409 +40
get_next_block 1667 1677 +10
get_bits 156 155 -1
start_bunzip 212 183 -29
bb_show_usage 181 120 -61
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 2/3 up/down: 147/-91) Total: 56 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | archival/libarchive/decompress_bunzip2.c | 78 | ||||
-rw-r--r-- | archival/libarchive/decompress_gunzip.c | 1 | ||||
-rw-r--r-- | coreutils/test.c | 1 | ||||
-rw-r--r-- | include/bb_archive.h | 2 | ||||
-rw-r--r-- | libbb/appletlib.c | 17 | ||||
-rw-r--r-- | miscutils/bbconfig.c | 19 | ||||
-rw-r--r-- | shell/ash.c | 1 | ||||
-rwxr-xr-x | testsuite/bunzip2.tests | 16 | ||||
-rw-r--r-- | testsuite/bz2_issue_11.bz2 | bin | 0 -> 12000 bytes | |||
-rw-r--r-- | testsuite/bz2_issue_12.bz2 | bin | 0 -> 11000 bytes |
10 files changed, 99 insertions, 36 deletions
diff --git a/archival/libarchive/decompress_bunzip2.c b/archival/libarchive/decompress_bunzip2.c index bec89edd3..7ef4e035f 100644 --- a/archival/libarchive/decompress_bunzip2.c +++ b/archival/libarchive/decompress_bunzip2.c | |||
@@ -100,7 +100,7 @@ struct bunzip_data { | |||
100 | unsigned dbufSize; | 100 | unsigned dbufSize; |
101 | 101 | ||
102 | /* For I/O error handling */ | 102 | /* For I/O error handling */ |
103 | jmp_buf jmpbuf; | 103 | jmp_buf *jmpbuf; |
104 | 104 | ||
105 | /* Big things go last (register-relative addressing can be larger for big offsets) */ | 105 | /* Big things go last (register-relative addressing can be larger for big offsets) */ |
106 | uint32_t crc32Table[256]; | 106 | uint32_t crc32Table[256]; |
@@ -127,7 +127,7 @@ static unsigned get_bits(bunzip_data *bd, int bits_wanted) | |||
127 | /* if "no input fd" case: in_fd == -1, read fails, we jump */ | 127 | /* if "no input fd" case: in_fd == -1, read fails, we jump */ |
128 | bd->inbufCount = read(bd->in_fd, bd->inbuf, IOBUF_SIZE); | 128 | bd->inbufCount = read(bd->in_fd, bd->inbuf, IOBUF_SIZE); |
129 | if (bd->inbufCount <= 0) | 129 | if (bd->inbufCount <= 0) |
130 | longjmp(bd->jmpbuf, RETVAL_UNEXPECTED_INPUT_EOF); | 130 | longjmp(*bd->jmpbuf, RETVAL_UNEXPECTED_INPUT_EOF); |
131 | bd->inbufPos = 0; | 131 | bd->inbufPos = 0; |
132 | } | 132 | } |
133 | 133 | ||
@@ -151,12 +151,12 @@ static unsigned get_bits(bunzip_data *bd, int bits_wanted) | |||
151 | 151 | ||
152 | return bits; | 152 | return bits; |
153 | } | 153 | } |
154 | //#define get_bits(bd, n) (dbg("%d:get_bits()", __LINE__), get_bits(bd, n)) | ||
154 | 155 | ||
155 | /* Unpacks the next block and sets up for the inverse Burrows-Wheeler step. */ | 156 | /* Unpacks the next block and sets up for the inverse Burrows-Wheeler step. */ |
156 | static int get_next_block(bunzip_data *bd) | 157 | static int get_next_block(bunzip_data *bd) |
157 | { | 158 | { |
158 | struct group_data *hufGroup; | 159 | int groupCount, selector, |
159 | int groupCount, *base, *limit, selector, | ||
160 | i, j, symCount, symTotal, nSelectors, byteCount[256]; | 160 | i, j, symCount, symTotal, nSelectors, byteCount[256]; |
161 | uint8_t uc, symToByte[256], mtfSymbol[256], *selectors; | 161 | uint8_t uc, symToByte[256], mtfSymbol[256], *selectors; |
162 | uint32_t *dbuf; | 162 | uint32_t *dbuf; |
@@ -179,15 +179,19 @@ static int get_next_block(bunzip_data *bd) | |||
179 | i = get_bits(bd, 24); | 179 | i = get_bits(bd, 24); |
180 | j = get_bits(bd, 24); | 180 | j = get_bits(bd, 24); |
181 | bd->headerCRC = get_bits(bd, 32); | 181 | bd->headerCRC = get_bits(bd, 32); |
182 | if ((i == 0x177245) && (j == 0x385090)) return RETVAL_LAST_BLOCK; | 182 | if ((i == 0x177245) && (j == 0x385090)) |
183 | if ((i != 0x314159) || (j != 0x265359)) return RETVAL_NOT_BZIP_DATA; | 183 | return RETVAL_LAST_BLOCK; |
184 | if ((i != 0x314159) || (j != 0x265359)) | ||
185 | return RETVAL_NOT_BZIP_DATA; | ||
184 | 186 | ||
185 | /* We can add support for blockRandomised if anybody complains. There was | 187 | /* We can add support for blockRandomised if anybody complains. There was |
186 | some code for this in busybox 1.0.0-pre3, but nobody ever noticed that | 188 | some code for this in busybox 1.0.0-pre3, but nobody ever noticed that |
187 | it didn't actually work. */ | 189 | it didn't actually work. */ |
188 | if (get_bits(bd, 1)) return RETVAL_OBSOLETE_INPUT; | 190 | if (get_bits(bd, 1)) |
191 | return RETVAL_OBSOLETE_INPUT; | ||
189 | origPtr = get_bits(bd, 24); | 192 | origPtr = get_bits(bd, 24); |
190 | if (origPtr > bd->dbufSize) return RETVAL_DATA_ERROR; | 193 | if (origPtr > bd->dbufSize) |
194 | return RETVAL_DATA_ERROR; | ||
191 | 195 | ||
192 | /* mapping table: if some byte values are never used (encoding things | 196 | /* mapping table: if some byte values are never used (encoding things |
193 | like ascii text), the compression code removes the gaps to have fewer | 197 | like ascii text), the compression code removes the gaps to have fewer |
@@ -231,13 +235,21 @@ static int get_next_block(bunzip_data *bd) | |||
231 | /* Get next value */ | 235 | /* Get next value */ |
232 | int n = 0; | 236 | int n = 0; |
233 | while (get_bits(bd, 1)) { | 237 | while (get_bits(bd, 1)) { |
234 | if (n >= groupCount) return RETVAL_DATA_ERROR; | 238 | if (n >= groupCount) |
239 | return RETVAL_DATA_ERROR; | ||
235 | n++; | 240 | n++; |
236 | } | 241 | } |
237 | /* Decode MTF to get the next selector */ | 242 | /* Decode MTF to get the next selector */ |
238 | tmp_byte = mtfSymbol[n]; | 243 | tmp_byte = mtfSymbol[n]; |
239 | while (--n >= 0) | 244 | while (--n >= 0) |
240 | mtfSymbol[n + 1] = mtfSymbol[n]; | 245 | mtfSymbol[n + 1] = mtfSymbol[n]; |
246 | //We catch it later, in the second loop where we use selectors[i]. | ||
247 | //Maybe this is a better place, though? | ||
248 | // if (tmp_byte >= groupCount) { | ||
249 | // dbg("%d: selectors[%d]:%d groupCount:%d", | ||
250 | // __LINE__, i, tmp_byte, groupCount); | ||
251 | // return RETVAL_DATA_ERROR; | ||
252 | // } | ||
241 | mtfSymbol[0] = selectors[i] = tmp_byte; | 253 | mtfSymbol[0] = selectors[i] = tmp_byte; |
242 | } | 254 | } |
243 | 255 | ||
@@ -248,6 +260,8 @@ static int get_next_block(bunzip_data *bd) | |||
248 | uint8_t length[MAX_SYMBOLS]; | 260 | uint8_t length[MAX_SYMBOLS]; |
249 | /* 8 bits is ALMOST enough for temp[], see below */ | 261 | /* 8 bits is ALMOST enough for temp[], see below */ |
250 | unsigned temp[MAX_HUFCODE_BITS+1]; | 262 | unsigned temp[MAX_HUFCODE_BITS+1]; |
263 | struct group_data *hufGroup; | ||
264 | int *base, *limit; | ||
251 | int minLen, maxLen, pp, len_m1; | 265 | int minLen, maxLen, pp, len_m1; |
252 | 266 | ||
253 | /* Read Huffman code lengths for each symbol. They're stored in | 267 | /* Read Huffman code lengths for each symbol. They're stored in |
@@ -283,8 +297,10 @@ static int get_next_block(bunzip_data *bd) | |||
283 | /* Find largest and smallest lengths in this group */ | 297 | /* Find largest and smallest lengths in this group */ |
284 | minLen = maxLen = length[0]; | 298 | minLen = maxLen = length[0]; |
285 | for (i = 1; i < symCount; i++) { | 299 | for (i = 1; i < symCount; i++) { |
286 | if (length[i] > maxLen) maxLen = length[i]; | 300 | if (length[i] > maxLen) |
287 | else if (length[i] < minLen) minLen = length[i]; | 301 | maxLen = length[i]; |
302 | else if (length[i] < minLen) | ||
303 | minLen = length[i]; | ||
288 | } | 304 | } |
289 | 305 | ||
290 | /* Calculate permute[], base[], and limit[] tables from length[]. | 306 | /* Calculate permute[], base[], and limit[] tables from length[]. |
@@ -320,7 +336,8 @@ static int get_next_block(bunzip_data *bd) | |||
320 | /* Count symbols coded for at each bit length */ | 336 | /* Count symbols coded for at each bit length */ |
321 | /* NB: in pathological cases, temp[8] can end ip being 256. | 337 | /* NB: in pathological cases, temp[8] can end ip being 256. |
322 | * That's why uint8_t is too small for temp[]. */ | 338 | * That's why uint8_t is too small for temp[]. */ |
323 | for (i = 0; i < symCount; i++) temp[length[i]]++; | 339 | for (i = 0; i < symCount; i++) |
340 | temp[length[i]]++; | ||
324 | 341 | ||
325 | /* Calculate limit[] (the largest symbol-coding value at each bit | 342 | /* Calculate limit[] (the largest symbol-coding value at each bit |
326 | * length, which is (previous limit<<1)+symbols at this level), and | 343 | * length, which is (previous limit<<1)+symbols at this level), and |
@@ -363,12 +380,22 @@ static int get_next_block(bunzip_data *bd) | |||
363 | 380 | ||
364 | runPos = dbufCount = selector = 0; | 381 | runPos = dbufCount = selector = 0; |
365 | for (;;) { | 382 | for (;;) { |
383 | struct group_data *hufGroup; | ||
384 | int *base, *limit; | ||
366 | int nextSym; | 385 | int nextSym; |
386 | uint8_t ngrp; | ||
367 | 387 | ||
368 | /* Fetch next Huffman coding group from list. */ | 388 | /* Fetch next Huffman coding group from list. */ |
369 | symCount = GROUP_SIZE - 1; | 389 | symCount = GROUP_SIZE - 1; |
370 | if (selector >= nSelectors) return RETVAL_DATA_ERROR; | 390 | if (selector >= nSelectors) |
371 | hufGroup = bd->groups + selectors[selector++]; | 391 | return RETVAL_DATA_ERROR; |
392 | ngrp = selectors[selector++]; | ||
393 | if (ngrp >= groupCount) { | ||
394 | dbg("%d selectors[%d]:%d groupCount:%d", | ||
395 | __LINE__, selector-1, ngrp, groupCount); | ||
396 | return RETVAL_DATA_ERROR; | ||
397 | } | ||
398 | hufGroup = bd->groups + ngrp; | ||
372 | base = hufGroup->base - 1; | 399 | base = hufGroup->base - 1; |
373 | limit = hufGroup->limit - 1; | 400 | limit = hufGroup->limit - 1; |
374 | 401 | ||
@@ -403,7 +430,8 @@ static int get_next_block(bunzip_data *bd) | |||
403 | } | 430 | } |
404 | /* Figure how many bits are in next symbol and unget extras */ | 431 | /* Figure how many bits are in next symbol and unget extras */ |
405 | i = hufGroup->minLen; | 432 | i = hufGroup->minLen; |
406 | while (nextSym > limit[i]) ++i; | 433 | while (nextSym > limit[i]) |
434 | ++i; | ||
407 | j = hufGroup->maxLen - i; | 435 | j = hufGroup->maxLen - i; |
408 | if (j < 0) | 436 | if (j < 0) |
409 | return RETVAL_DATA_ERROR; | 437 | return RETVAL_DATA_ERROR; |
@@ -671,7 +699,10 @@ int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len) | |||
671 | /* Because bunzip2 is used for help text unpacking, and because bb_show_usage() | 699 | /* Because bunzip2 is used for help text unpacking, and because bb_show_usage() |
672 | should work for NOFORK applets too, we must be extremely careful to not leak | 700 | should work for NOFORK applets too, we must be extremely careful to not leak |
673 | any allocations! */ | 701 | any allocations! */ |
674 | int FAST_FUNC start_bunzip(bunzip_data **bdp, int in_fd, | 702 | int FAST_FUNC start_bunzip( |
703 | void *jmpbuf, | ||
704 | bunzip_data **bdp, | ||
705 | int in_fd, | ||
675 | const void *inbuf, int len) | 706 | const void *inbuf, int len) |
676 | { | 707 | { |
677 | bunzip_data *bd; | 708 | bunzip_data *bd; |
@@ -683,11 +714,14 @@ int FAST_FUNC start_bunzip(bunzip_data **bdp, int in_fd, | |||
683 | 714 | ||
684 | /* Figure out how much data to allocate */ | 715 | /* Figure out how much data to allocate */ |
685 | i = sizeof(bunzip_data); | 716 | i = sizeof(bunzip_data); |
686 | if (in_fd != -1) i += IOBUF_SIZE; | 717 | if (in_fd != -1) |
718 | i += IOBUF_SIZE; | ||
687 | 719 | ||
688 | /* Allocate bunzip_data. Most fields initialize to zero. */ | 720 | /* Allocate bunzip_data. Most fields initialize to zero. */ |
689 | bd = *bdp = xzalloc(i); | 721 | bd = *bdp = xzalloc(i); |
690 | 722 | ||
723 | bd->jmpbuf = jmpbuf; | ||
724 | |||
691 | /* Setup input buffer */ | 725 | /* Setup input buffer */ |
692 | bd->in_fd = in_fd; | 726 | bd->in_fd = in_fd; |
693 | if (-1 == in_fd) { | 727 | if (-1 == in_fd) { |
@@ -702,10 +736,6 @@ int FAST_FUNC start_bunzip(bunzip_data **bdp, int in_fd, | |||
702 | /* Init the CRC32 table (big endian) */ | 736 | /* Init the CRC32 table (big endian) */ |
703 | crc32_filltable(bd->crc32Table, 1); | 737 | crc32_filltable(bd->crc32Table, 1); |
704 | 738 | ||
705 | /* Setup for I/O error handling via longjmp */ | ||
706 | i = setjmp(bd->jmpbuf); | ||
707 | if (i) return i; | ||
708 | |||
709 | /* Ensure that file starts with "BZh['1'-'9']." */ | 739 | /* Ensure that file starts with "BZh['1'-'9']." */ |
710 | /* Update: now caller verifies 1st two bytes, makes .gz/.bz2 | 740 | /* Update: now caller verifies 1st two bytes, makes .gz/.bz2 |
711 | * integration easier */ | 741 | * integration easier */ |
@@ -752,8 +782,12 @@ unpack_bz2_stream(transformer_state_t *xstate) | |||
752 | outbuf = xmalloc(IOBUF_SIZE); | 782 | outbuf = xmalloc(IOBUF_SIZE); |
753 | len = 0; | 783 | len = 0; |
754 | while (1) { /* "Process one BZ... stream" loop */ | 784 | while (1) { /* "Process one BZ... stream" loop */ |
785 | jmp_buf jmpbuf; | ||
755 | 786 | ||
756 | i = start_bunzip(&bd, xstate->src_fd, outbuf + 2, len); | 787 | /* Setup for I/O error handling via longjmp */ |
788 | i = setjmp(jmpbuf); | ||
789 | if (i == 0) | ||
790 | i = start_bunzip(&jmpbuf, &bd, xstate->src_fd, outbuf + 2, len); | ||
757 | 791 | ||
758 | if (i == 0) { | 792 | if (i == 0) { |
759 | while (1) { /* "Produce some output bytes" loop */ | 793 | while (1) { /* "Produce some output bytes" loop */ |
diff --git a/archival/libarchive/decompress_gunzip.c b/archival/libarchive/decompress_gunzip.c index 9a58d10d4..7f9046b82 100644 --- a/archival/libarchive/decompress_gunzip.c +++ b/archival/libarchive/decompress_gunzip.c | |||
@@ -32,7 +32,6 @@ | |||
32 | * | 32 | * |
33 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | 33 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
34 | */ | 34 | */ |
35 | #include <setjmp.h> | ||
36 | #include "libbb.h" | 35 | #include "libbb.h" |
37 | #include "bb_archive.h" | 36 | #include "bb_archive.h" |
38 | 37 | ||
diff --git a/coreutils/test.c b/coreutils/test.c index a8286525a..824ce3b5a 100644 --- a/coreutils/test.c +++ b/coreutils/test.c | |||
@@ -76,7 +76,6 @@ | |||
76 | //usage: "1\n" | 76 | //usage: "1\n" |
77 | 77 | ||
78 | #include "libbb.h" | 78 | #include "libbb.h" |
79 | #include <setjmp.h> | ||
80 | 79 | ||
81 | /* This is a NOFORK applet. Be very careful! */ | 80 | /* This is a NOFORK applet. Be very careful! */ |
82 | 81 | ||
diff --git a/include/bb_archive.h b/include/bb_archive.h index a5c61e95b..b437f1920 100644 --- a/include/bb_archive.h +++ b/include/bb_archive.h | |||
@@ -210,7 +210,7 @@ const llist_t *find_list_entry2(const llist_t *list, const char *filename) FAST_ | |||
210 | 210 | ||
211 | /* A bit of bunzip2 internals are exposed for compressed help support: */ | 211 | /* A bit of bunzip2 internals are exposed for compressed help support: */ |
212 | typedef struct bunzip_data bunzip_data; | 212 | typedef struct bunzip_data bunzip_data; |
213 | int start_bunzip(bunzip_data **bdp, int in_fd, const void *inbuf, int len) FAST_FUNC; | 213 | int start_bunzip(void *, bunzip_data **bdp, int in_fd, const void *inbuf, int len) FAST_FUNC; |
214 | /* NB: read_bunzip returns < 0 on error, or the number of *unfilled* bytes | 214 | /* NB: read_bunzip returns < 0 on error, or the number of *unfilled* bytes |
215 | * in outbuf. IOW: on EOF returns len ("all bytes are not filled"), not 0: */ | 215 | * in outbuf. IOW: on EOF returns len ("all bytes are not filled"), not 0: */ |
216 | int read_bunzip(bunzip_data *bd, char *outbuf, int len) FAST_FUNC; | 216 | int read_bunzip(bunzip_data *bd, char *outbuf, int len) FAST_FUNC; |
diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 022455da4..769b7881c 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c | |||
@@ -102,14 +102,21 @@ static const char *unpack_usage_messages(void) | |||
102 | char *outbuf = NULL; | 102 | char *outbuf = NULL; |
103 | bunzip_data *bd; | 103 | bunzip_data *bd; |
104 | int i; | 104 | int i; |
105 | jmp_buf jmpbuf; | ||
105 | 106 | ||
106 | i = start_bunzip(&bd, | 107 | /* Setup for I/O error handling via longjmp */ |
108 | i = setjmp(jmpbuf); | ||
109 | if (i == 0) { | ||
110 | i = start_bunzip(&jmpbuf, | ||
111 | &bd, | ||
107 | /* src_fd: */ -1, | 112 | /* src_fd: */ -1, |
108 | /* inbuf: */ packed_usage, | 113 | /* inbuf: */ packed_usage, |
109 | /* len: */ sizeof(packed_usage)); | 114 | /* len: */ sizeof(packed_usage) |
110 | /* read_bunzip can longjmp to start_bunzip, and ultimately | 115 | ); |
111 | * end up here with i != 0 on read data errors! Not trivial */ | 116 | } |
112 | if (!i) { | 117 | /* read_bunzip can longjmp and end up here with i != 0 |
118 | * on read data errors! Not trivial */ | ||
119 | if (i == 0) { | ||
113 | /* Cannot use xmalloc: will leak bd in NOFORK case! */ | 120 | /* Cannot use xmalloc: will leak bd in NOFORK case! */ |
114 | outbuf = malloc_or_warn(sizeof(UNPACKED_USAGE)); | 121 | outbuf = malloc_or_warn(sizeof(UNPACKED_USAGE)); |
115 | if (outbuf) | 122 | if (outbuf) |
diff --git a/miscutils/bbconfig.c b/miscutils/bbconfig.c index 9ab57876e..501349548 100644 --- a/miscutils/bbconfig.c +++ b/miscutils/bbconfig.c | |||
@@ -44,13 +44,22 @@ int bbconfig_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
44 | { | 44 | { |
45 | #if ENABLE_FEATURE_COMPRESS_BBCONFIG | 45 | #if ENABLE_FEATURE_COMPRESS_BBCONFIG |
46 | bunzip_data *bd; | 46 | bunzip_data *bd; |
47 | int i = start_bunzip(&bd, | 47 | int i; |
48 | jmp_buf jmpbuf; | ||
49 | |||
50 | /* Setup for I/O error handling via longjmp */ | ||
51 | i = setjmp(jmpbuf); | ||
52 | if (i == 0) { | ||
53 | i = start_bunzip(&jmpbuf, | ||
54 | &bd, | ||
48 | /* src_fd: */ -1, | 55 | /* src_fd: */ -1, |
49 | /* inbuf: */ bbconfig_config_bz2, | 56 | /* inbuf: */ bbconfig_config_bz2, |
50 | /* len: */ sizeof(bbconfig_config_bz2)); | 57 | /* len: */ sizeof(bbconfig_config_bz2) |
51 | /* read_bunzip can longjmp to start_bunzip, and ultimately | 58 | ); |
52 | * end up here with i != 0 on read data errors! Not trivial */ | 59 | } |
53 | if (!i) { | 60 | /* read_bunzip can longjmp and end up here with i != 0 |
61 | * on read data errors! Not trivial */ | ||
62 | if (i == 0) { | ||
54 | /* Cannot use xmalloc: will leak bd in NOFORK case! */ | 63 | /* Cannot use xmalloc: will leak bd in NOFORK case! */ |
55 | char *outbuf = malloc_or_warn(sizeof(bbconfig_config)); | 64 | char *outbuf = malloc_or_warn(sizeof(bbconfig_config)); |
56 | if (outbuf) { | 65 | if (outbuf) { |
diff --git a/shell/ash.c b/shell/ash.c index 56fba4a57..24958c0fc 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -177,7 +177,6 @@ | |||
177 | 177 | ||
178 | #define JOBS ENABLE_ASH_JOB_CONTROL | 178 | #define JOBS ENABLE_ASH_JOB_CONTROL |
179 | 179 | ||
180 | #include <setjmp.h> | ||
181 | #include <fnmatch.h> | 180 | #include <fnmatch.h> |
182 | #include <sys/times.h> | 181 | #include <sys/times.h> |
183 | #include <sys/utsname.h> /* for setting $HOSTNAME */ | 182 | #include <sys/utsname.h> /* for setting $HOSTNAME */ |
diff --git a/testsuite/bunzip2.tests b/testsuite/bunzip2.tests index fcfce1a31..edb332748 100755 --- a/testsuite/bunzip2.tests +++ b/testsuite/bunzip2.tests | |||
@@ -552,6 +552,22 @@ if test "${0##*/}" = "bunzip2.tests"; then | |||
552 | echo "FAIL: $unpack: pbzip_4m_zeros file" | 552 | echo "FAIL: $unpack: pbzip_4m_zeros file" |
553 | FAILCOUNT=$((FAILCOUNT + 1)) | 553 | FAILCOUNT=$((FAILCOUNT + 1)) |
554 | fi | 554 | fi |
555 | |||
556 | errout="`${bb}bunzip2 <bz2_issue_11.bz2 2>&1 >/dev/null`" | ||
557 | if test x"$errout:$?" = x"bunzip2: bunzip error -5:1"; then | ||
558 | echo "PASS: $unpack: bz2_issue_11.bz2 corrupted example" | ||
559 | else | ||
560 | echo "FAIL: $unpack: bz2_issue_11.bz2 corrupted example" | ||
561 | FAILCOUNT=$((FAILCOUNT + 1)) | ||
562 | fi | ||
563 | |||
564 | errout="`${bb}bunzip2 <bz2_issue_12.bz2 2>&1 >/dev/null`" | ||
565 | if test x"$errout:$?" = x"bunzip2: bunzip error -3:1"; then | ||
566 | echo "PASS: $unpack: bz2_issue_12.bz2 corrupted example" | ||
567 | else | ||
568 | echo "FAIL: $unpack: bz2_issue_12.bz2 corrupted example" | ||
569 | FAILCOUNT=$((FAILCOUNT + 1)) | ||
570 | fi | ||
555 | fi | 571 | fi |
556 | 572 | ||
557 | exit $((FAILCOUNT <= 255 ? FAILCOUNT : 255)) | 573 | exit $((FAILCOUNT <= 255 ? FAILCOUNT : 255)) |
diff --git a/testsuite/bz2_issue_11.bz2 b/testsuite/bz2_issue_11.bz2 new file mode 100644 index 000000000..62b252046 --- /dev/null +++ b/testsuite/bz2_issue_11.bz2 | |||
Binary files differ | |||
diff --git a/testsuite/bz2_issue_12.bz2 b/testsuite/bz2_issue_12.bz2 new file mode 100644 index 000000000..4215f08d6 --- /dev/null +++ b/testsuite/bz2_issue_12.bz2 | |||
Binary files differ | |||