From e1f21380603d16f24b08b666831e1cd0427fa5de Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Thu, 15 Sep 2011 01:45:10 +1000 Subject: [PATCH] Make sure to read to the end of all streams when closing down an rzip stream. This would have made lrzip unable to decompress some rare archives if they ended up stream 0. --- lrzip_private.h | 1 + runzip.c | 2 +- stream.c | 16 ++++++++++++++-- stream.h | 2 +- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/lrzip_private.h b/lrzip_private.h index fda47d2..4439621 100644 --- a/lrzip_private.h +++ b/lrzip_private.h @@ -264,6 +264,7 @@ struct stream_info { i64 bufsize; i64 cur_pos; i64 initial_pos; + i64 total_read; i64 ram_alloced; i64 size; long thread_no; diff --git a/runzip.c b/runzip.c index 58b5012..6be36ab 100644 --- a/runzip.c +++ b/runzip.c @@ -321,7 +321,7 @@ static i64 runzip_chunk(rzip_control *control, int fd_in, i64 expected_size, i64 print_maxverbose("Checksum for block: 0x%08x\n", cksum); } - if (unlikely(close_stream_in(ss))) + if (unlikely(close_stream_in(control, ss))) fatal("Failed to close stream!\n"); return total; diff --git a/stream.c b/stream.c index 531383a..5c3aab7 100644 --- a/stream.c +++ b/stream.c @@ -1182,6 +1182,8 @@ again: goto failed; header_length = 1 + (read_len * 3); } + sinfo->total_read += header_length; + if (ENCRYPT) decrypt_header(control, enc_head, &c, &v1, &v2, &sinfo->s[i].last_head); @@ -1543,7 +1545,7 @@ retry: /* fill a buffer from a stream - return -1 on failure */ static int fill_buffer(rzip_control *control, struct stream_info *sinfo, int streamno) { - i64 u_len, c_len, last_head, padded_len; + i64 u_len, c_len, last_head, padded_len, header_length; uchar enc_head[25 + SALT_LEN], blocksalt[SALT_LEN]; struct stream *s = &sinfo->s[streamno]; stream_thread_struct *st; @@ -1579,6 +1581,7 @@ fill_another: c_len = c_len32; u_len = u_len32; last_head = last_head32; + header_length = 13; } else { int read_len; @@ -1593,7 +1596,9 @@ fill_another: return -1; if (unlikely(read_val(control, sinfo->fd, &last_head, read_len))) return -1; + header_length = 1 + (read_len * 3); } + sinfo->total_read += header_length; if (ENCRYPT) { decrypt_header(control, enc_head, &c_type, &c_len, &u_len, &last_head); @@ -1605,6 +1610,7 @@ fill_another: last_head = le64toh(last_head); padded_len = MAX(c_len, MIN_SIZE); + sinfo->total_read += padded_len; fsync(control->fd_out); s_buf = malloc(MAX(u_len, MIN_SIZE)); @@ -1762,11 +1768,17 @@ int close_stream_out(rzip_control *control, void *ss) } /* close down an input stream */ -int close_stream_in(void *ss) +int close_stream_in(rzip_control *control, void *ss) { struct stream_info *sinfo = ss; int i; + print_maxverbose("Closing stream at %lld, want to seek to %lld\n", + get_readseek(control, control->fd_in), + sinfo->initial_pos + sinfo->total_read); + if (unlikely(read_seekto(control, sinfo, sinfo->total_read))) + return -1; + for (i = 0; i < sinfo->num_streams; i++) free(sinfo->s[i].buf); diff --git a/stream.h b/stream.h index a958f11..c9fbc7f 100644 --- a/stream.h +++ b/stream.h @@ -37,7 +37,7 @@ void flush_buffer(rzip_control *control, struct stream_info *sinfo, int stream); int write_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); int close_stream_out(rzip_control *control, void *ss); -int close_stream_in(void *ss); +int close_stream_in(rzip_control *control, void *ss); ssize_t put_fdout(rzip_control *control, void *offset_buf, ssize_t ret); i64 one_g;