dovecot-2.2: istream-[b]zlib: Don't break if parent stream gets ...
dovecot at dovecot.org
dovecot at dovecot.org
Tue Apr 23 20:54:19 EEST 2013
details: http://hg.dovecot.org/dovecot-2.2/rev/ba63c27667ff
changeset: 16315:ba63c27667ff
user: Timo Sirainen <tss at iki.fi>
date: Tue Apr 23 20:53:53 2013 +0300
description:
istream-[b]zlib: Don't break if parent stream gets seeked in the middle of reads.
diffstat:
src/lib-compression/istream-bzlib.c | 65 +++++++++++++++-------------------
src/lib-compression/istream-zlib.c | 68 ++++++++++++++++--------------------
2 files changed, 59 insertions(+), 74 deletions(-)
diffs (243 lines):
diff -r 6d19a0f32a1b -r ba63c27667ff src/lib-compression/istream-bzlib.c
--- a/src/lib-compression/istream-bzlib.c Tue Apr 23 20:51:34 2013 +0300
+++ b/src/lib-compression/istream-bzlib.c Tue Apr 23 20:53:53 2013 +0300
@@ -15,7 +15,7 @@
bz_stream zs;
uoff_t eof_offset, stream_size;
- size_t prev_size, high_pos;
+ size_t high_pos;
struct stat last_parent_statbuf;
unsigned int log_errors:1;
@@ -49,7 +49,7 @@
struct bzlib_istream *zstream = (struct bzlib_istream *)stream;
const unsigned char *data;
uoff_t high_offset;
- size_t size;
+ size_t size, out_size;
int ret;
high_offset = stream->istream.v_offset + (stream->pos - stream->skip);
@@ -98,42 +98,36 @@
}
}
- if (zstream->zs.avail_in == 0) {
- /* need to read more data. try to read a full CHUNK_SIZE */
- i_stream_skip(stream->parent, zstream->prev_size);
- if (i_stream_read_data(stream->parent, &data, &size,
- CHUNK_SIZE-1) == -1 && size == 0) {
- if (stream->parent->stream_errno != 0) {
- stream->istream.stream_errno =
- stream->parent->stream_errno;
- } else {
- i_assert(stream->parent->eof);
- if (zstream->log_errors) {
- bzlib_read_error(zstream,
- "unexpected EOF");
- }
- stream->istream.stream_errno = EINVAL;
- }
- return -1;
+ if (i_stream_read_data(stream->parent, &data, &size, 0) < 0) {
+ if (stream->parent->stream_errno != 0) {
+ stream->istream.stream_errno =
+ stream->parent->stream_errno;
+ } else {
+ i_assert(stream->parent->eof);
+ if (zstream->log_errors)
+ bzlib_read_error(zstream, "unexpected EOF");
+ stream->istream.stream_errno = EINVAL;
}
- zstream->prev_size = size;
- if (size == 0) {
- /* no more input */
- i_assert(!stream->istream.blocking);
- return 0;
- }
-
- zstream->zs.next_in = (char *)data;
- zstream->zs.avail_in = size;
+ return -1;
+ }
+ if (size == 0) {
+ /* no more input */
+ i_assert(!stream->istream.blocking);
+ return 0;
}
- size = stream->buffer_size - stream->pos;
+ zstream->zs.next_in = (char *)data;
+ zstream->zs.avail_in = size;
+
+ out_size = stream->buffer_size - stream->pos;
zstream->zs.next_out = (char *)stream->w_buffer + stream->pos;
- zstream->zs.avail_out = size;
+ zstream->zs.avail_out = out_size;
ret = BZ2_bzDecompress(&zstream->zs);
- size -= zstream->zs.avail_out;
- stream->pos += size;
+ out_size -= zstream->zs.avail_out;
+ stream->pos += out_size;
+
+ i_stream_skip(stream->parent, size - zstream->zs.avail_in);
switch (ret) {
case BZ_OK:
@@ -159,7 +153,7 @@
zstream->eof_offset = stream->istream.v_offset +
(stream->pos - stream->skip);
zstream->stream_size = zstream->eof_offset;
- if (size == 0) {
+ if (out_size == 0) {
stream->istream.eof = TRUE;
return -1;
}
@@ -167,11 +161,11 @@
default:
i_fatal("BZ2_bzDecompress() failed with %d", ret);
}
- if (size == 0) {
+ if (out_size == 0) {
/* read more input */
return i_stream_bzlib_read(stream);
}
- return size;
+ return out_size;
}
static void i_stream_bzlib_init(struct bzlib_istream *zstream)
@@ -206,7 +200,6 @@
stream->skip = stream->pos = 0;
stream->istream.v_offset = 0;
zstream->high_pos = 0;
- zstream->prev_size = 0;
(void)BZ2_bzDecompressEnd(&zstream->zs);
i_stream_bzlib_init(zstream);
diff -r 6d19a0f32a1b -r ba63c27667ff src/lib-compression/istream-zlib.c
--- a/src/lib-compression/istream-zlib.c Tue Apr 23 20:51:34 2013 +0300
+++ b/src/lib-compression/istream-zlib.c Tue Apr 23 20:53:53 2013 +0300
@@ -122,6 +122,7 @@
pos += 2;
}
i_stream_skip(stream->parent, pos);
+ zstream->prev_size = 0;
return 1;
}
@@ -172,7 +173,7 @@
struct zlib_istream *zstream = (struct zlib_istream *)stream;
const unsigned char *data;
uoff_t high_offset;
- size_t size;
+ size_t size, out_size;
int ret;
high_offset = stream->istream.v_offset + (stream->pos - stream->skip);
@@ -208,7 +209,6 @@
if (ret <= 0)
return ret;
zstream->header_read = TRUE;
- zstream->prev_size = 0;
}
if (stream->pos < zstream->high_pos) {
@@ -248,44 +248,39 @@
}
}
- if (zstream->zs.avail_in == 0) {
- /* need to read more data. try to read a full CHUNK_SIZE */
- i_stream_skip(stream->parent, zstream->prev_size);
- if (i_stream_read_data(stream->parent, &data, &size,
- CHUNK_SIZE-1) == -1 && size == 0) {
- if (stream->parent->stream_errno != 0) {
- stream->istream.stream_errno =
- stream->parent->stream_errno;
- } else {
- i_assert(stream->parent->eof);
- if (zstream->log_errors) {
- zlib_read_error(zstream,
- "unexpected EOF");
- }
- stream->istream.stream_errno = EPIPE;
- }
- return -1;
+ if (i_stream_read_data(stream->parent, &data, &size, 0) < 0) {
+ if (stream->parent->stream_errno != 0) {
+ stream->istream.stream_errno =
+ stream->parent->stream_errno;
+ } else {
+ i_assert(stream->parent->eof);
+ if (zstream->log_errors)
+ zlib_read_error(zstream, "unexpected EOF");
+ stream->istream.stream_errno = EPIPE;
}
- zstream->prev_size = size;
- if (size == 0) {
- /* no more input */
- i_assert(!stream->istream.blocking);
- return 0;
- }
-
- zstream->zs.next_in = (void *)data;
- zstream->zs.avail_in = size;
+ return -1;
+ }
+ if (size == 0) {
+ /* no more input */
+ i_assert(!stream->istream.blocking);
+ return 0;
}
- size = stream->buffer_size - stream->pos;
+ zstream->zs.next_in = (void *)data;
+ zstream->zs.avail_in = size;
+
+ out_size = stream->buffer_size - stream->pos;
zstream->zs.next_out = stream->w_buffer + stream->pos;
- zstream->zs.avail_out = size;
+ zstream->zs.avail_out = out_size;
ret = inflate(&zstream->zs, Z_SYNC_FLUSH);
- size -= zstream->zs.avail_out;
+ out_size -= zstream->zs.avail_out;
zstream->crc32 = crc32_data_more(zstream->crc32,
- stream->w_buffer + stream->pos, size);
- stream->pos += size;
+ stream->w_buffer + stream->pos,
+ out_size);
+ stream->pos += out_size;
+
+ i_stream_skip(stream->parent, size - zstream->zs.avail_in);
switch (ret) {
case Z_OK:
@@ -307,10 +302,7 @@
zstream->eof_offset = stream->istream.v_offset +
(stream->pos - stream->skip);
zstream->stream_size = zstream->eof_offset;
- i_stream_skip(stream->parent,
- zstream->prev_size - zstream->zs.avail_in);
zstream->zs.avail_in = 0;
- zstream->prev_size = 0;
if (!zstream->trailer_read) {
/* try to read and verify the trailer, we might not
@@ -322,11 +314,11 @@
default:
i_fatal("inflate() failed with %d", ret);
}
- if (size == 0) {
+ if (out_size == 0) {
/* read more input */
return i_stream_zlib_read(stream);
}
- return size;
+ return out_size;
}
static void i_stream_zlib_init(struct zlib_istream *zstream)
More information about the dovecot-cvs
mailing list