From: Aki Tuomi Date: Wed, 10 Jun 2026 11:53:39 +0000 (+0000) Subject: [PATCH 1/4] lib-compression: wrap *_read() in for(;;) loop (reindent only) X-Git-Tag: archive/raspbian/1%2.4.1+dfsg1-6+rpi1+deb13u7^2~86 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=0467d0d8917ffd636f937023618c229d53c3384b;p=dovecot.git [PATCH 1/4] lib-compression: wrap *_read() in for(;;) loop (reindent only) Prepare for the next commit: wrap the body of i_stream_lz4_read(), i_stream_bzlib_read(), and i_stream_zlib_read() in a for(;;) loop. No logic change; all paths still return on the first iteration. Separating the indent churn makes the actual fix easier to review. Gbp-Pq: Name 0001-lib-compression-wrap-_read-in-for-loop-reindent-only.patch --- diff --git a/src/lib-compression/istream-bzlib.c b/src/lib-compression/istream-bzlib.c index aae1027..702450a 100644 --- a/src/lib-compression/istream-bzlib.c +++ b/src/lib-compression/istream-bzlib.c @@ -51,88 +51,90 @@ static ssize_t i_stream_bzlib_read(struct istream_private *stream) size_t size, out_size; int ret; - high_offset = stream->istream.v_offset + (stream->pos - stream->skip); - if (zstream->eof_offset == high_offset) { - stream->istream.eof = TRUE; - return -1; - } - - if (!zstream->marked) { - if (!i_stream_try_alloc(stream, CHUNK_SIZE, &out_size)) - return -2; /* buffer full */ - } else { - /* try to avoid compressing, so we can quickly seek backwards */ - if (!i_stream_try_alloc_avoid_compress(stream, CHUNK_SIZE, &out_size)) - return -2; /* buffer full */ - } + for (;;) { + high_offset = stream->istream.v_offset + (stream->pos - stream->skip); + if (zstream->eof_offset == high_offset) { + stream->istream.eof = TRUE; + return -1; + } - if (i_stream_read_more(stream->parent, &data, &size) < 0) { - if (stream->parent->stream_errno != 0) { - stream->istream.stream_errno = - stream->parent->stream_errno; + if (!zstream->marked) { + if (!i_stream_try_alloc(stream, CHUNK_SIZE, &out_size)) + return -2; /* buffer full */ } else { - i_assert(stream->parent->eof); - bzlib_read_error(zstream, "unexpected EOF"); - if (!zstream->hdr_read) - stream->istream.stream_errno = EINVAL; - else - stream->istream.stream_errno = EPIPE; + /* try to avoid compressing, so we can quickly seek backwards */ + if (!i_stream_try_alloc_avoid_compress(stream, CHUNK_SIZE, &out_size)) + return -2; /* buffer full */ } - return -1; - } - if (size == 0) { - /* no more input */ - i_assert(!stream->istream.blocking); - return 0; - } - zstream->zs.next_in = (char *)data; - zstream->zs.avail_in = size; + if (i_stream_read_more(stream->parent, &data, &size) < 0) { + if (stream->parent->stream_errno != 0) { + stream->istream.stream_errno = + stream->parent->stream_errno; + } else { + i_assert(stream->parent->eof); + bzlib_read_error(zstream, "unexpected EOF"); + if (!zstream->hdr_read) + stream->istream.stream_errno = EINVAL; + else + stream->istream.stream_errno = EPIPE; + } + return -1; + } + if (size == 0) { + /* no more input */ + i_assert(!stream->istream.blocking); + return 0; + } - zstream->zs.next_out = (char *)stream->w_buffer + stream->pos; - zstream->zs.avail_out = out_size; - ret = BZ2_bzDecompress(&zstream->zs); - zstream->hdr_read = TRUE; + zstream->zs.next_in = (char *)data; + zstream->zs.avail_in = size; - out_size -= zstream->zs.avail_out; - stream->pos += out_size; + zstream->zs.next_out = (char *)stream->w_buffer + stream->pos; + zstream->zs.avail_out = out_size; + ret = BZ2_bzDecompress(&zstream->zs); + zstream->hdr_read = TRUE; - i_stream_skip(stream->parent, size - zstream->zs.avail_in); + out_size -= zstream->zs.avail_out; + stream->pos += out_size; - switch (ret) { - case BZ_OK: - break; - case BZ_PARAM_ERROR: - i_unreached(); - case BZ_DATA_ERROR: - bzlib_read_error(zstream, "corrupted data"); - stream->istream.stream_errno = EINVAL; - return -1; - case BZ_DATA_ERROR_MAGIC: - bzlib_read_error(zstream, - "wrong magic in header (not bz2 file?)"); - stream->istream.stream_errno = EINVAL; - return -1; - case BZ_MEM_ERROR: - i_fatal_status(FATAL_OUTOFMEM, "bzlib.read(%s): Out of memory", - i_stream_get_name(&stream->istream)); - case BZ_STREAM_END: - zstream->eof_offset = stream->istream.v_offset + - (stream->pos - stream->skip); - stream->cached_stream_size = zstream->eof_offset; - if (out_size == 0) { - stream->istream.eof = TRUE; + i_stream_skip(stream->parent, size - zstream->zs.avail_in); + + switch (ret) { + case BZ_OK: + break; + case BZ_PARAM_ERROR: + i_unreached(); + case BZ_DATA_ERROR: + bzlib_read_error(zstream, "corrupted data"); + stream->istream.stream_errno = EINVAL; return -1; + case BZ_DATA_ERROR_MAGIC: + bzlib_read_error(zstream, + "wrong magic in header (not bz2 file?)"); + stream->istream.stream_errno = EINVAL; + return -1; + case BZ_MEM_ERROR: + i_fatal_status(FATAL_OUTOFMEM, "bzlib.read(%s): Out of memory", + i_stream_get_name(&stream->istream)); + case BZ_STREAM_END: + zstream->eof_offset = stream->istream.v_offset + + (stream->pos - stream->skip); + stream->cached_stream_size = zstream->eof_offset; + if (out_size == 0) { + stream->istream.eof = TRUE; + return -1; + } + break; + default: + i_fatal("BZ2_bzDecompress() failed with %d", ret); } - break; - default: - i_fatal("BZ2_bzDecompress() failed with %d", ret); - } - if (out_size == 0) { - /* read more input */ - return i_stream_bzlib_read(stream); + if (out_size == 0) { + /* read more input */ + return i_stream_bzlib_read(stream); + } + return out_size; } - return out_size; } static void i_stream_bzlib_init(struct bzlib_istream *zstream) diff --git a/src/lib-compression/istream-lz4.c b/src/lib-compression/istream-lz4.c index ee2ddbb..bb37b85 100644 --- a/src/lib-compression/istream-lz4.c +++ b/src/lib-compression/istream-lz4.c @@ -149,67 +149,69 @@ static ssize_t i_stream_lz4_read(struct istream_private *stream) zstream->header_read = TRUE; } - if (zstream->chunk_left == 0) { - while ((ret = i_stream_lz4_read_chunk_header(zstream)) == 0) { - if (!stream->istream.blocking) - return 0; + for (;;) { + if (zstream->chunk_left == 0) { + while ((ret = i_stream_lz4_read_chunk_header(zstream)) == 0) { + if (!stream->istream.blocking) + return 0; + } + if (ret < 0) + return ret; } - if (ret < 0) - return ret; - } - /* read the whole compressed chunk into memory */ - while (zstream->chunk_left > 0 && - (ret = i_stream_read_more(zstream->istream.parent, &data, &size)) > 0) { - if (size > zstream->chunk_left) - size = zstream->chunk_left; - buffer_append(zstream->chunk_buf, data, size); - i_stream_skip(zstream->istream.parent, size); - zstream->chunk_left -= size; - } - if (zstream->chunk_left > 0) { - if (ret == -1 && zstream->istream.parent->stream_errno == 0) { - lz4_read_error(zstream, "truncated lz4 chunk"); - stream->istream.stream_errno = EPIPE; - return -1; + /* read the whole compressed chunk into memory */ + while (zstream->chunk_left > 0 && + (ret = i_stream_read_more(zstream->istream.parent, &data, &size)) > 0) { + if (size > zstream->chunk_left) + size = zstream->chunk_left; + buffer_append(zstream->chunk_buf, data, size); + i_stream_skip(zstream->istream.parent, size); + zstream->chunk_left -= size; + } + if (zstream->chunk_left > 0) { + if (ret == -1 && zstream->istream.parent->stream_errno == 0) { + lz4_read_error(zstream, "truncated lz4 chunk"); + stream->istream.stream_errno = EPIPE; + return -1; + } + zstream->istream.istream.stream_errno = + zstream->istream.parent->stream_errno; + i_assert(ret != 0 || !stream->istream.blocking); + return ret; } - zstream->istream.istream.stream_errno = - zstream->istream.parent->stream_errno; - i_assert(ret != 0 || !stream->istream.blocking); + /* if we already have max_buffer_size amount of data, fail here */ + if (stream->pos - stream->skip >= i_stream_get_max_buffer_size(&stream->istream)) + return -2; + if (i_stream_get_data_size(zstream->istream.parent) > 0) { + /* Parent stream was only partially consumed. Set the stream's + IO as pending to avoid hangs. */ + i_stream_set_input_pending(&zstream->istream.istream, TRUE); + } + /* allocate enough space for the old data and the new + decompressed chunk. we don't know the original compressed size, + so just allocate the max amount of memory. */ + void *dest = i_stream_alloc(stream, zstream->max_uncompressed_chunk_size); + ret = LZ4_decompress_safe(zstream->chunk_buf->data, dest, + zstream->chunk_buf->used, + zstream->max_uncompressed_chunk_size); + i_assert(ret <= (int)zstream->max_uncompressed_chunk_size); + if (ret < 0) { + lz4_read_error(zstream, "corrupted lz4 chunk"); + stream->istream.stream_errno = EINVAL; + return -1; + } else if (ret == 0) + return i_stream_lz4_read(stream); + i_assert(ret > 0); + stream->pos += ret; + i_assert(stream->pos <= stream->buffer_size); + + /* we are going to get next chunk after this, so reset here + so we can reuse the chunk buf for reading next buffer prefix */ + if (zstream->chunk_left == 0) + buffer_set_used_size(zstream->chunk_buf, 0); + return ret; } - /* if we already have max_buffer_size amount of data, fail here */ - if (stream->pos - stream->skip >= i_stream_get_max_buffer_size(&stream->istream)) - return -2; - if (i_stream_get_data_size(zstream->istream.parent) > 0) { - /* Parent stream was only partially consumed. Set the stream's - IO as pending to avoid hangs. */ - i_stream_set_input_pending(&zstream->istream.istream, TRUE); - } - /* allocate enough space for the old data and the new - decompressed chunk. we don't know the original compressed size, - so just allocate the max amount of memory. */ - void *dest = i_stream_alloc(stream, zstream->max_uncompressed_chunk_size); - ret = LZ4_decompress_safe(zstream->chunk_buf->data, dest, - zstream->chunk_buf->used, - zstream->max_uncompressed_chunk_size); - i_assert(ret <= (int)zstream->max_uncompressed_chunk_size); - if (ret < 0) { - lz4_read_error(zstream, "corrupted lz4 chunk"); - stream->istream.stream_errno = EINVAL; - return -1; - } else if (ret == 0) - return i_stream_lz4_read(stream); - i_assert(ret > 0); - stream->pos += ret; - i_assert(stream->pos <= stream->buffer_size); - - /* we are going to get next chunk after this, so reset here - so we can reuse the chunk buf for reading next buffer prefix */ - if (zstream->chunk_left == 0) - buffer_set_used_size(zstream->chunk_buf, 0); - - return ret; } static void i_stream_lz4_reset(struct lz4_istream *zstream) diff --git a/src/lib-compression/istream-zlib.c b/src/lib-compression/istream-zlib.c index 9b58c86..094a9d2 100644 --- a/src/lib-compression/istream-zlib.c +++ b/src/lib-compression/istream-zlib.c @@ -168,155 +168,157 @@ static ssize_t i_stream_zlib_read(struct istream_private *stream) size_t size, out_size; int ret; - high_offset = stream->istream.v_offset + (stream->pos - stream->skip); - if (zstream->eof_offset == high_offset) { - /* zlib library returned EOF. */ - if (!zstream->gz) { - /* deflate - ignore if there's still more data */ - stream->istream.eof = TRUE; - return -1; + for (;;) { + high_offset = stream->istream.v_offset + (stream->pos - stream->skip); + if (zstream->eof_offset == high_offset) { + /* zlib library returned EOF. */ + if (!zstream->gz) { + /* deflate - ignore if there's still more data */ + stream->istream.eof = TRUE; + return -1; + } + /* gz format - read the trailer */ + if (!zstream->trailer_read) { + do { + ret = i_stream_zlib_read_trailer(zstream); + } while (ret == 0 && stream->istream.blocking); + if (ret <= 0) + return ret; + } + /* See if there's another concatenated gz stream. */ + if (i_stream_read_eof(stream->parent)) { + /* EOF or error */ + stream->istream.stream_errno = + stream->parent->stream_errno; + stream->istream.eof = TRUE; + return -1; + } + /* Multiple gz streams concatenated together */ + zstream->starting_concatenated_output = TRUE; } - /* gz format - read the trailer */ - if (!zstream->trailer_read) { + if (zstream->starting_concatenated_output) { + /* make sure there actually is something in parent stream. + we don't want to reset the stream unless we actually see + some concatenated output. */ + ret = i_stream_read_more(stream->parent, &data, &size); + if (ret <= 0) { + if (ret == 0) + return 0; + if (stream->parent->stream_errno != 0) { + stream->istream.stream_errno = + stream->parent->stream_errno; + } + stream->istream.eof = TRUE; + return -1; + } + + /* gzip file with concatenated content */ + stream->cached_stream_size = UOFF_T_MAX; + zstream->eof_offset = UOFF_T_MAX; + zstream->header_read = FALSE; + zstream->trailer_read = FALSE; + zstream->crc32 = 0; + zstream->starting_concatenated_output = FALSE; + + (void)inflateEnd(&zstream->zs); + i_stream_zlib_init(zstream); + } + + if (!zstream->header_read) { do { - ret = i_stream_zlib_read_trailer(zstream); + ret = i_stream_zlib_read_header(stream); } while (ret == 0 && stream->istream.blocking); if (ret <= 0) return ret; + zstream->header_read = TRUE; } - /* See if there's another concatenated gz stream. */ - if (i_stream_read_eof(stream->parent)) { - /* EOF or error */ - stream->istream.stream_errno = - stream->parent->stream_errno; - stream->istream.eof = TRUE; - return -1; + + if (!zstream->marked) { + if (!i_stream_try_alloc(stream, CHUNK_SIZE, &out_size)) + return -2; /* buffer full */ + } else { + /* try to avoid compressing, so we can quickly seek backwards */ + if (!i_stream_try_alloc_avoid_compress(stream, CHUNK_SIZE, &out_size)) + return -2; /* buffer full */ } - /* Multiple gz streams concatenated together */ - zstream->starting_concatenated_output = TRUE; - } - if (zstream->starting_concatenated_output) { - /* make sure there actually is something in parent stream. - we don't want to reset the stream unless we actually see - some concatenated output. */ - ret = i_stream_read_more(stream->parent, &data, &size); - if (ret <= 0) { - if (ret == 0) - return 0; + + if (i_stream_read_more(stream->parent, &data, &size) < 0) { if (stream->parent->stream_errno != 0) { stream->istream.stream_errno = stream->parent->stream_errno; + } else { + i_assert(stream->parent->eof); + zlib_read_error(zstream, "unexpected EOF"); + stream->istream.stream_errno = EPIPE; } - stream->istream.eof = TRUE; return -1; } - - /* gzip file with concatenated content */ - stream->cached_stream_size = UOFF_T_MAX; - zstream->eof_offset = UOFF_T_MAX; - zstream->header_read = FALSE; - zstream->trailer_read = FALSE; - zstream->crc32 = 0; - zstream->starting_concatenated_output = FALSE; - - (void)inflateEnd(&zstream->zs); - i_stream_zlib_init(zstream); - } - - if (!zstream->header_read) { - do { - ret = i_stream_zlib_read_header(stream); - } while (ret == 0 && stream->istream.blocking); - if (ret <= 0) - return ret; - zstream->header_read = TRUE; - } - - if (!zstream->marked) { - if (!i_stream_try_alloc(stream, CHUNK_SIZE, &out_size)) - return -2; /* buffer full */ - } else { - /* try to avoid compressing, so we can quickly seek backwards */ - if (!i_stream_try_alloc_avoid_compress(stream, CHUNK_SIZE, &out_size)) - return -2; /* buffer full */ - } - - if (i_stream_read_more(stream->parent, &data, &size) < 0) { - if (stream->parent->stream_errno != 0) { - stream->istream.stream_errno = - stream->parent->stream_errno; - } else { - i_assert(stream->parent->eof); - zlib_read_error(zstream, "unexpected EOF"); - stream->istream.stream_errno = EPIPE; + if (size == 0) { + /* no more input */ + i_assert(!stream->istream.blocking); + return 0; } - return -1; - } - if (size == 0) { - /* no more input */ - i_assert(!stream->istream.blocking); - return 0; - } - zstream->zs.next_in = (void *)data; - zstream->zs.avail_in = size; - - zstream->zs.next_out = stream->w_buffer + stream->pos; - zstream->zs.avail_out = out_size; - ret = inflate(&zstream->zs, Z_SYNC_FLUSH); - - out_size -= zstream->zs.avail_out; - /* CRC32 is only needed for GZ trailer. */ - if (zstream->gz) - zstream->crc32 = crc32_data_more(zstream->crc32, - stream->w_buffer + stream->pos, - out_size); - stream->pos += out_size; - - size_t bytes_consumed = size - zstream->zs.avail_in; - i_stream_skip(stream->parent, bytes_consumed); - if (i_stream_get_data_size(stream->parent) > 0 && - (bytes_consumed > 0 || out_size > 0)) { - /* Parent stream was only partially consumed. Set the stream's - IO as pending to avoid hangs. */ - i_stream_set_input_pending(&stream->istream, TRUE); - } + zstream->zs.next_in = (void *)data; + zstream->zs.avail_in = size; + + zstream->zs.next_out = stream->w_buffer + stream->pos; + zstream->zs.avail_out = out_size; + ret = inflate(&zstream->zs, Z_SYNC_FLUSH); + + out_size -= zstream->zs.avail_out; + /* CRC32 is only needed for GZ trailer. */ + if (zstream->gz) + zstream->crc32 = crc32_data_more(zstream->crc32, + stream->w_buffer + stream->pos, + out_size); + stream->pos += out_size; + + size_t bytes_consumed = size - zstream->zs.avail_in; + i_stream_skip(stream->parent, bytes_consumed); + if (i_stream_get_data_size(stream->parent) > 0 && + (bytes_consumed > 0 || out_size > 0)) { + /* Parent stream was only partially consumed. Set the stream's + IO as pending to avoid hangs. */ + i_stream_set_input_pending(&stream->istream, TRUE); + } - switch (ret) { - case Z_OK: - break; - case Z_NEED_DICT: - zlib_read_error(zstream, "can't read file without dict"); - stream->istream.stream_errno = EIO; - return -1; - case Z_DATA_ERROR: - zlib_read_error(zstream, "corrupted data"); - stream->istream.stream_errno = EINVAL; - return -1; - case Z_MEM_ERROR: - i_fatal_status(FATAL_OUTOFMEM, "zlib.read(%s): Out of memory", - i_stream_get_name(&stream->istream)); - case Z_STREAM_END: - zstream->eof_offset = stream->istream.v_offset + - (stream->pos - stream->skip); - stream->cached_stream_size = zstream->eof_offset; - zstream->zs.avail_in = 0; - - if (!zstream->trailer_read) { - /* try to read and verify the trailer, we might not - be called again. */ - if (i_stream_zlib_read_trailer(zstream) < 0) - return -1; + switch (ret) { + case Z_OK: + break; + case Z_NEED_DICT: + zlib_read_error(zstream, "can't read file without dict"); + stream->istream.stream_errno = EIO; + return -1; + case Z_DATA_ERROR: + zlib_read_error(zstream, "corrupted data"); + stream->istream.stream_errno = EINVAL; + return -1; + case Z_MEM_ERROR: + i_fatal_status(FATAL_OUTOFMEM, "zlib.read(%s): Out of memory", + i_stream_get_name(&stream->istream)); + case Z_STREAM_END: + zstream->eof_offset = stream->istream.v_offset + + (stream->pos - stream->skip); + stream->cached_stream_size = zstream->eof_offset; + zstream->zs.avail_in = 0; + + if (!zstream->trailer_read) { + /* try to read and verify the trailer, we might not + be called again. */ + if (i_stream_zlib_read_trailer(zstream) < 0) + return -1; + } + break; + default: + i_fatal("inflate() failed with %d", ret); } - break; - default: - i_fatal("inflate() failed with %d", ret); - } - if (out_size == 0) { - /* read more input */ - return i_stream_zlib_read(stream); + if (out_size == 0) { + /* read more input */ + return i_stream_zlib_read(stream); + } + return out_size; } - return out_size; } static void i_stream_zlib_init(struct zlib_istream *zstream)