Fix xz handling for files larger than 32K.

Submitted by:	Stefan Ehmann <shoesoft gmx net>
PR:		bin/186861
MFC after:	2 weeks
This commit is contained in:
Xin LI 2015-01-21 01:11:37 +00:00
parent 5773625048
commit a5e43ff69e

View File

@ -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;
ret = (filebehave == FILE_XZ) ?
lzma_stream_decoder(&lstrm, UINT64_MAX,
LZMA_CONCATENATED) :
lzma_alone_decoder(&lstrm, UINT64_MAX);
if (ret != LZMA_OK)
return (-1);
lstrm.next_out = buffer;
lstrm.avail_out = MAXBUFSIZ;
lstrm.next_in = in_buf;
nr = read(f->fd, in_buf, MAXBUFSIZ);
if (nr < 0)
return (-1);
else if (nr == 0)
action = LZMA_FINISH;
do {
if (lstrm.avail_in == 0) {
lstrm.next_in = lin_buf;
nr = read(f->fd, lin_buf, MAXBUFSIZ);
lstrm.avail_in = nr;
ret = lzma_code(&lstrm, action);
if (nr < 0)
return (-1);
else if (nr == 0)
laction = LZMA_FINISH;
lstrm.avail_in = nr;
}
ret = lzma_code(&lstrm, laction);
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)