mirror of
https://github.com/ckolivas/lrzip.git
synced 2025-12-06 07:12:00 +01:00
Fix failure to pthread join on corrupt archives calling fill_buffer again at the end of a stream.
This commit is contained in:
parent
399336eba4
commit
cd456aa70e
25
stream.c
25
stream.c
|
|
@ -1506,9 +1506,8 @@ static void *ucompthread(void *data)
|
||||||
{
|
{
|
||||||
stream_thread_struct *s = data;
|
stream_thread_struct *s = data;
|
||||||
rzip_control *control = s->control;
|
rzip_control *control = s->control;
|
||||||
long i = s->i;
|
int waited = 0, ret = 0, i = s->i;
|
||||||
struct uncomp_thread *uci;
|
struct uncomp_thread *uci;
|
||||||
int waited = 0, ret = 0;
|
|
||||||
|
|
||||||
dealloc(data);
|
dealloc(data);
|
||||||
uci = &ucthread[i];
|
uci = &ucthread[i];
|
||||||
|
|
@ -1559,22 +1558,23 @@ retry:
|
||||||
|
|
||||||
print_maxverbose("Thread %ld decompressed %lld bytes from stream %d\n", i, uci->u_len, uci->streamno);
|
print_maxverbose("Thread %ld decompressed %lld bytes from stream %d\n", i, uci->u_len, uci->streamno);
|
||||||
|
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fill a buffer from a stream - return -1 on failure */
|
/* fill a buffer from a stream - return -1 on failure */
|
||||||
static int fill_buffer(rzip_control *control, struct stream_info *sinfo, int streamno)
|
static int fill_buffer(rzip_control *control, struct stream_info *sinfo, struct stream *s, int streamno)
|
||||||
{
|
{
|
||||||
i64 u_len, c_len, last_head, padded_len, header_length, max_len;
|
i64 u_len, c_len, last_head, padded_len, header_length, max_len;
|
||||||
uchar enc_head[25 + SALT_LEN], blocksalt[SALT_LEN];
|
uchar enc_head[25 + SALT_LEN], blocksalt[SALT_LEN];
|
||||||
struct stream *s = &sinfo->s[streamno];
|
|
||||||
stream_thread_struct *st;
|
stream_thread_struct *st;
|
||||||
|
bool new_thread = false;
|
||||||
uchar c_type, *s_buf;
|
uchar c_type, *s_buf;
|
||||||
|
|
||||||
dealloc(s->buf);
|
dealloc(s->buf);
|
||||||
if (s->eos)
|
if (s->eos)
|
||||||
goto out;
|
goto out;
|
||||||
fill_another:
|
fill_another:
|
||||||
|
new_thread = true;
|
||||||
if (unlikely(ucthread[s->uthread_no].busy))
|
if (unlikely(ucthread[s->uthread_no].busy))
|
||||||
failure_return(("Trying to start a busy thread, this shouldn't happen!\n"), -1);
|
failure_return(("Trying to start a busy thread, this shouldn't happen!\n"), -1);
|
||||||
|
|
||||||
|
|
@ -1702,7 +1702,7 @@ out:
|
||||||
unlock_mutex(control, &output_lock);
|
unlock_mutex(control, &output_lock);
|
||||||
|
|
||||||
/* join_pthread here will make it wait till the data is ready */
|
/* join_pthread here will make it wait till the data is ready */
|
||||||
if (unlikely(!join_pthread(control, threads[s->unext_thread], NULL)))
|
if (unlikely(new_thread && !join_pthread(control, threads[s->unext_thread], NULL)))
|
||||||
return -1;
|
return -1;
|
||||||
ucthread[s->unext_thread].busy = 0;
|
ucthread[s->unext_thread].busy = 0;
|
||||||
|
|
||||||
|
|
@ -1744,25 +1744,26 @@ void write_stream(rzip_control *control, void *ss, int streamno, uchar *p, i64 l
|
||||||
i64 read_stream(rzip_control *control, void *ss, int streamno, uchar *p, i64 len)
|
i64 read_stream(rzip_control *control, void *ss, int streamno, uchar *p, i64 len)
|
||||||
{
|
{
|
||||||
struct stream_info *sinfo = ss;
|
struct stream_info *sinfo = ss;
|
||||||
|
struct stream *s = &sinfo->s[streamno];
|
||||||
i64 ret = 0;
|
i64 ret = 0;
|
||||||
|
|
||||||
while (len) {
|
while (len) {
|
||||||
i64 n;
|
i64 n;
|
||||||
|
|
||||||
n = MIN(sinfo->s[streamno].buflen - sinfo->s[streamno].bufp, len);
|
n = MIN(s->buflen - s->bufp, len);
|
||||||
|
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
memcpy(p, sinfo->s[streamno].buf + sinfo->s[streamno].bufp, n);
|
memcpy(p, s->buf + s->bufp, n);
|
||||||
sinfo->s[streamno].bufp += n;
|
s->bufp += n;
|
||||||
p += n;
|
p += n;
|
||||||
len -= n;
|
len -= n;
|
||||||
ret += n;
|
ret += n;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len && sinfo->s[streamno].bufp == sinfo->s[streamno].buflen) {
|
if (len && s->bufp == s->buflen) {
|
||||||
if (unlikely(fill_buffer(control, sinfo, streamno)))
|
if (unlikely(fill_buffer(control, sinfo, s, streamno)))
|
||||||
return -1;
|
return -1;
|
||||||
if (sinfo->s[streamno].bufp == sinfo->s[streamno].buflen)
|
if (s->bufp == s->buflen)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue