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.
This commit is contained in:
Con Kolivas 2011-09-15 01:45:10 +10:00
parent a39b57a1e7
commit e1f2138060
4 changed files with 17 additions and 4 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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;