diff options
author | delphij <delphij@FreeBSD.org> | 2009-11-16 22:52:52 +0000 |
---|---|---|
committer | delphij <delphij@FreeBSD.org> | 2009-11-16 22:52:52 +0000 |
commit | adba2f7336363ee570a3b0f7ba8ceb121b1c7914 (patch) | |
tree | 1268931b27cdd158dcfc13501d8b27e9753ce989 /usr.bin/gzip | |
parent | 4e38e56b0dfeaed938cd590c779b2a4f57d94399 (diff) | |
download | FreeBSD-src-adba2f7336363ee570a3b0f7ba8ceb121b1c7914.zip FreeBSD-src-adba2f7336363ee570a3b0f7ba8ceb121b1c7914.tar.gz |
We should distinguish between a real truncated case and EOF after
BZ_STREAM_END triggered re-init. Do it by introducing a new flag
to represent the 'cold' case after bzip2 state is reinitialized.
This fixes regression reported on -current@ as well as another one
I found during twiddling with gzip.
Reported by: swell.k gmail.com
MFC after: 1 week
Diffstat (limited to 'usr.bin/gzip')
-rw-r--r-- | usr.bin/gzip/unbzip2.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/usr.bin/gzip/unbzip2.c b/usr.bin/gzip/unbzip2.c index 4835325..c744e56 100644 --- a/usr.bin/gzip/unbzip2.c +++ b/usr.bin/gzip/unbzip2.c @@ -36,7 +36,7 @@ static off_t unbzip2(int in, int out, char *pre, size_t prelen, off_t *bytes_in) { - int ret, end_of_file; + int ret, end_of_file, cold = 0; off_t bytes_out = 0; bz_stream bzs; static char *inbuf, *outbuf; @@ -86,8 +86,18 @@ unbzip2(int in, int out, char *pre, size_t prelen, off_t *bytes_in) switch (ret) { case BZ_STREAM_END: case BZ_OK: - if (ret == BZ_OK && end_of_file) - maybe_err("read"); + if (ret == BZ_OK && end_of_file) { + /* + * If we hit this after a stream end, consider + * it as the end of the whole file and don't + * bail out. + */ + if (cold == 1) + ret = BZ_STREAM_END; + else + maybe_errx("truncated file"); + } + cold = 0; if (!tflag && bzs.avail_out != BUFLEN) { ssize_t n; @@ -100,6 +110,7 @@ unbzip2(int in, int out, char *pre, size_t prelen, off_t *bytes_in) if (BZ2_bzDecompressEnd(&bzs) != BZ_OK || BZ2_bzDecompressInit(&bzs, 0, 0) != BZ_OK) maybe_errx("bzip2 re-init"); + cold = 1; ret = BZ_OK; } break; |