diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2015-10-26 19:33:05 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2015-10-26 19:33:05 +0100 |
commit | 1de25a6e87e0e627aa34298105a3d17c60a1f44e (patch) | |
tree | 9ddba32a47aeef1d5836a7e7229d48463b1a16ca | |
parent | d683c5c2f1493c2b0856a5f8751508836b0988d5 (diff) | |
download | busybox-w32-1de25a6e87e0e627aa34298105a3d17c60a1f44e.tar.gz busybox-w32-1de25a6e87e0e627aa34298105a3d17c60a1f44e.tar.bz2 busybox-w32-1de25a6e87e0e627aa34298105a3d17c60a1f44e.zip |
unzip: test for bad archive SEGVing
function old new delta
huft_build 1296 1300 +4
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | archival/libarchive/decompress_gunzip.c | 11 | ||||
-rwxr-xr-x | testsuite/unzip.tests | 23 |
2 files changed, 29 insertions, 5 deletions
diff --git a/archival/libarchive/decompress_gunzip.c b/archival/libarchive/decompress_gunzip.c index 7b6f45934..30bf45154 100644 --- a/archival/libarchive/decompress_gunzip.c +++ b/archival/libarchive/decompress_gunzip.c | |||
@@ -305,11 +305,12 @@ static int huft_build(const unsigned *b, const unsigned n, | |||
305 | unsigned i; /* counter, current code */ | 305 | unsigned i; /* counter, current code */ |
306 | unsigned j; /* counter */ | 306 | unsigned j; /* counter */ |
307 | int k; /* number of bits in current code */ | 307 | int k; /* number of bits in current code */ |
308 | unsigned *p; /* pointer into c[], b[], or v[] */ | 308 | const unsigned *p; /* pointer into c[], b[], or v[] */ |
309 | huft_t *q; /* points to current table */ | 309 | huft_t *q; /* points to current table */ |
310 | huft_t r; /* table entry for structure assignment */ | 310 | huft_t r; /* table entry for structure assignment */ |
311 | huft_t *u[BMAX]; /* table stack */ | 311 | huft_t *u[BMAX]; /* table stack */ |
312 | unsigned v[N_MAX]; /* values in order of bit length */ | 312 | unsigned v[N_MAX]; /* values in order of bit length */ |
313 | unsigned v_end; | ||
313 | int ws[BMAX + 1]; /* bits decoded stack */ | 314 | int ws[BMAX + 1]; /* bits decoded stack */ |
314 | int w; /* bits decoded */ | 315 | int w; /* bits decoded */ |
315 | unsigned x[BMAX + 1]; /* bit offsets, then code stack */ | 316 | unsigned x[BMAX + 1]; /* bit offsets, then code stack */ |
@@ -324,7 +325,7 @@ static int huft_build(const unsigned *b, const unsigned n, | |||
324 | 325 | ||
325 | /* Generate counts for each bit length */ | 326 | /* Generate counts for each bit length */ |
326 | memset(c, 0, sizeof(c)); | 327 | memset(c, 0, sizeof(c)); |
327 | p = (unsigned *) b; /* cast allows us to reuse p for pointing to b */ | 328 | p = b; |
328 | i = n; | 329 | i = n; |
329 | do { | 330 | do { |
330 | c[*p]++; /* assume all entries <= BMAX */ | 331 | c[*p]++; /* assume all entries <= BMAX */ |
@@ -365,12 +366,14 @@ static int huft_build(const unsigned *b, const unsigned n, | |||
365 | } | 366 | } |
366 | 367 | ||
367 | /* Make a table of values in order of bit lengths */ | 368 | /* Make a table of values in order of bit lengths */ |
368 | p = (unsigned *) b; | 369 | p = b; |
369 | i = 0; | 370 | i = 0; |
371 | v_end = 0; | ||
370 | do { | 372 | do { |
371 | j = *p++; | 373 | j = *p++; |
372 | if (j != 0) { | 374 | if (j != 0) { |
373 | v[x[j]++] = i; | 375 | v[x[j]++] = i; |
376 | v_end = x[j]; | ||
374 | } | 377 | } |
375 | } while (++i < n); | 378 | } while (++i < n); |
376 | 379 | ||
@@ -432,7 +435,7 @@ static int huft_build(const unsigned *b, const unsigned n, | |||
432 | 435 | ||
433 | /* set up table entry in r */ | 436 | /* set up table entry in r */ |
434 | r.b = (unsigned char) (k - w); | 437 | r.b = (unsigned char) (k - w); |
435 | if (p >= v + n) { | 438 | if (p >= v + v_end) { // Was "if (p >= v + n)" but v[] can be shorter! |
436 | r.e = 99; /* out of values--invalid code */ | 439 | r.e = 99; /* out of values--invalid code */ |
437 | } else if (*p < s) { | 440 | } else if (*p < s) { |
438 | r.e = (unsigned char) (*p < 256 ? 16 : 15); /* 256 is EOB code */ | 441 | r.e = (unsigned char) (*p < 256 ? 16 : 15); /* 256 is EOB code */ |
diff --git a/testsuite/unzip.tests b/testsuite/unzip.tests index 8677a0306..ca0a45800 100755 --- a/testsuite/unzip.tests +++ b/testsuite/unzip.tests | |||
@@ -7,7 +7,7 @@ | |||
7 | 7 | ||
8 | . ./testing.sh | 8 | . ./testing.sh |
9 | 9 | ||
10 | # testing "test name" "options" "expected result" "file input" "stdin" | 10 | # testing "test name" "commands" "expected result" "file input" "stdin" |
11 | # file input will be file called "input" | 11 | # file input will be file called "input" |
12 | # test can create a file "actual" instead of writing to stdout | 12 | # test can create a file "actual" instead of writing to stdout |
13 | 13 | ||
@@ -30,6 +30,27 @@ testing "unzip (subdir only)" "unzip -q foo.zip foo/ && test -d foo && test ! -f | |||
30 | rmdir foo | 30 | rmdir foo |
31 | rm foo.zip | 31 | rm foo.zip |
32 | 32 | ||
33 | # File containing some damaged encrypted stream | ||
34 | testing "unzip (bad archive)" "uudecode; unzip bad.zip 2>&1; echo \$?" \ | ||
35 | "Archive: bad.zip | ||
36 | inflating: ]3j½r«IK-%Ix | ||
37 | unzip: inflate error | ||
38 | 1 | ||
39 | " \ | ||
40 | "" "\ | ||
41 | begin-base64 644 bad.zip | ||
42 | UEsDBBQAAgkIAAAAIQA5AAAANwAAADwAAAAQAAcAXTNqwr1ywqtJGxJLLSVJ | ||
43 | eCkBD0AdKBk8JzQsIj01JC0/ORJQSwMEFAECCAAAAAAhADoAAAAPAAAANgAA | ||
44 | AAwAAQASw73Ct1DCokohPXQiNjoUNTUiHRwgLT4WHlBLAQIQABQAAggIAAAA | ||
45 | oQA5AAAANwAAADwAAAAQQAcADAAAACwAMgCAAAAAAABdM2rCvXLCq0kbEkst | ||
46 | JUl4KQEPQB0oGSY4Cz4QNgEnJSYIPVBLAQIAABQAAggAAAAAIQAqAAAADwAA | ||
47 | BDYAAAAMAAEADQAAADIADQAAAEEAAAASw73Ct1DKokohPXQiNzA+FAI1HCcW | ||
48 | NzITNFBLBQUKAC4JAA04Cw0EOhZQSwUGAQAABAIAAgCZAAAAeQAAAAIALhM= | ||
49 | ==== | ||
50 | " | ||
51 | |||
52 | rm * | ||
53 | |||
33 | # Clean up scratch directory. | 54 | # Clean up scratch directory. |
34 | 55 | ||
35 | cd .. | 56 | cd .. |