diff options
author | delphij <delphij@FreeBSD.org> | 2015-01-21 01:11:37 +0000 |
---|---|---|
committer | delphij <delphij@FreeBSD.org> | 2015-01-21 01:11:37 +0000 |
commit | 637c00643a781090c43bf4f50d21be4ea591b939 (patch) | |
tree | deb96525d32448fabccc9001306cdfa990508164 /usr.bin/grep | |
parent | b0c7bd39a20a4d8cfcb56c20be0428c1a6474ae8 (diff) | |
download | FreeBSD-src-637c00643a781090c43bf4f50d21be4ea591b939.zip FreeBSD-src-637c00643a781090c43bf4f50d21be4ea591b939.tar.gz |
Fix xz handling for files larger than 32K.
Submitted by: Stefan Ehmann <shoesoft gmx net>
PR: bin/186861
MFC after: 2 weeks
Diffstat (limited to 'usr.bin/grep')
-rw-r--r-- | usr.bin/grep/file.c | 61 |
1 files changed, 40 insertions, 21 deletions
diff --git a/usr.bin/grep/file.c b/usr.bin/grep/file.c index 6bcaa52..81f227d 100644 --- a/usr.bin/grep/file.c +++ b/usr.bin/grep/file.c @@ -65,6 +65,8 @@ __FBSDID("$FreeBSD$"); static gzFile gzbufdesc; #ifndef WITHOUT_LZMA static lzma_stream lstrm = LZMA_STREAM_INIT; +static lzma_action laction; +static uint8_t lin_buf[MAXBUFSIZ]; #endif #ifndef WITHOUT_BZIP2 static BZFILE* bzbufdesc; @@ -123,34 +125,34 @@ grep_refill(struct file *f) #endif #ifndef WITHOUT_LZMA } else if ((filebehave == FILE_XZ) || (filebehave == FILE_LZMA)) { - lzma_action action = LZMA_RUN; - uint8_t in_buf[MAXBUFSIZ]; lzma_ret ret; + lstrm.next_out = buffer; - ret = (filebehave == FILE_XZ) ? - lzma_stream_decoder(&lstrm, UINT64_MAX, - LZMA_CONCATENATED) : - lzma_alone_decoder(&lstrm, UINT64_MAX); + do { + if (lstrm.avail_in == 0) { + lstrm.next_in = lin_buf; + nr = read(f->fd, lin_buf, MAXBUFSIZ); - if (ret != LZMA_OK) - return (-1); + if (nr < 0) + return (-1); + else if (nr == 0) + laction = LZMA_FINISH; - lstrm.next_out = buffer; - lstrm.avail_out = MAXBUFSIZ; - lstrm.next_in = in_buf; - nr = read(f->fd, in_buf, MAXBUFSIZ); + lstrm.avail_in = nr; + } - if (nr < 0) - return (-1); - else if (nr == 0) - action = LZMA_FINISH; + ret = lzma_code(&lstrm, laction); - lstrm.avail_in = nr; - ret = lzma_code(&lstrm, action); + if (ret != LZMA_OK && ret != LZMA_STREAM_END) + return (-1); + + if (lstrm.avail_out == 0 || ret == LZMA_STREAM_END) { + bufrem = MAXBUFSIZ - lstrm.avail_out; + lstrm.next_out = buffer; + lstrm.avail_out = MAXBUFSIZ; + } + } while (bufrem == 0 && ret != LZMA_STREAM_END); - if (ret != LZMA_OK && ret != LZMA_STREAM_END) - return (-1); - bufrem = MAXBUFSIZ - lstrm.avail_out; return (0); #endif /* WIHTOUT_LZMA */ } else @@ -291,6 +293,23 @@ grep_open(const char *path) (bzbufdesc = BZ2_bzdopen(f->fd, "r")) == NULL) goto error2; #endif +#ifndef WITHOUT_LZMA + else if ((filebehave == FILE_XZ) || (filebehave == FILE_LZMA)) { + lzma_ret ret; + + ret = (filebehave == FILE_XZ) ? + lzma_stream_decoder(&lstrm, UINT64_MAX, + LZMA_CONCATENATED) : + lzma_alone_decoder(&lstrm, UINT64_MAX); + + if (ret != LZMA_OK) + goto error2; + + lstrm.avail_in = 0; + lstrm.avail_out = MAXBUFSIZ; + laction = LZMA_RUN; + } +#endif /* Fill read buffer, also catches errors early */ if (bufrem == 0 && grep_refill(f) != 0) |