uncompress: fix buffer underrun by corrupted input
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
b1611d9a46
commit
251fc70e97
@ -163,7 +163,8 @@ unpack_Z_stream(int fd_in, int fd_out)
|
|||||||
|
|
||||||
if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) {
|
if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) {
|
||||||
rsize = safe_read(fd_in, inbuf + insize, IBUFSIZ);
|
rsize = safe_read(fd_in, inbuf + insize, IBUFSIZ);
|
||||||
//error check??
|
if (rsize < 0)
|
||||||
|
bb_error_msg(bb_msg_read_error);
|
||||||
insize += rsize;
|
insize += rsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,6 +196,8 @@ unpack_Z_stream(int fd_in, int fd_out)
|
|||||||
|
|
||||||
|
|
||||||
if (oldcode == -1) {
|
if (oldcode == -1) {
|
||||||
|
if (code >= 256)
|
||||||
|
bb_error_msg_and_die("corrupted data"); /* %ld", code); */
|
||||||
oldcode = code;
|
oldcode = code;
|
||||||
finchar = (int) oldcode;
|
finchar = (int) oldcode;
|
||||||
outbuf[outpos++] = (unsigned char) finchar;
|
outbuf[outpos++] = (unsigned char) finchar;
|
||||||
@ -239,6 +242,8 @@ unpack_Z_stream(int fd_in, int fd_out)
|
|||||||
|
|
||||||
/* Generate output characters in reverse order */
|
/* Generate output characters in reverse order */
|
||||||
while ((long) code >= (long) 256) {
|
while ((long) code >= (long) 256) {
|
||||||
|
if (stackp <= &htabof(0))
|
||||||
|
bb_error_msg_and_die("corrupted data");
|
||||||
*--stackp = tab_suffixof(code);
|
*--stackp = tab_suffixof(code);
|
||||||
code = tab_prefixof(code);
|
code = tab_prefixof(code);
|
||||||
}
|
}
|
||||||
@ -263,8 +268,7 @@ unpack_Z_stream(int fd_in, int fd_out)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (outpos >= OBUFSIZ) {
|
if (outpos >= OBUFSIZ) {
|
||||||
full_write(fd_out, outbuf, outpos);
|
xwrite(fd_out, outbuf, outpos);
|
||||||
//error check??
|
|
||||||
IF_DESKTOP(total_written += outpos;)
|
IF_DESKTOP(total_written += outpos;)
|
||||||
outpos = 0;
|
outpos = 0;
|
||||||
}
|
}
|
||||||
@ -292,8 +296,7 @@ unpack_Z_stream(int fd_in, int fd_out)
|
|||||||
} while (rsize > 0);
|
} while (rsize > 0);
|
||||||
|
|
||||||
if (outpos > 0) {
|
if (outpos > 0) {
|
||||||
full_write(fd_out, outbuf, outpos);
|
xwrite(fd_out, outbuf, outpos);
|
||||||
//error check??
|
|
||||||
IF_DESKTOP(total_written += outpos;)
|
IF_DESKTOP(total_written += outpos;)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
20
testsuite/uncompress.tests
Executable file
20
testsuite/uncompress.tests
Executable file
@ -0,0 +1,20 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Copyright 2011 by Denys Vlasenko
|
||||||
|
# Licensed under GPLv2, see file LICENSE in this source tree.
|
||||||
|
|
||||||
|
. ./testing.sh
|
||||||
|
|
||||||
|
# testing "test name" "commands" "expected result" "file input" "stdin"
|
||||||
|
|
||||||
|
testing "uncompress < \x1f\x9d\x90 \x01 x N" \
|
||||||
|
'uncompress 2>&1 1>/dev/null; echo $?' \
|
||||||
|
"\
|
||||||
|
uncompress: corrupted data
|
||||||
|
1
|
||||||
|
" \
|
||||||
|
"" "\
|
||||||
|
\x1f\x9d\x90\
|
||||||
|
\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\
|
||||||
|
"
|
||||||
|
|
||||||
|
exit $FAILCOUNT
|
Loading…
Reference in New Issue
Block a user