From: Timo Sirainen Date: Thu, 6 Oct 2016 10:50:59 +0000 (+0300) Subject: global: Make sure i_stream_read() calls handle 0 and -2 return values correctly. X-Git-Tag: 2.3.0.rc1~2943 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7f74811b7;p=thirdparty%2Fdovecot%2Fcore.git global: Make sure i_stream_read() calls handle 0 and -2 return values correctly. --- diff --git a/src/doveadm/client-connection-http.c b/src/doveadm/client-connection-http.c index cf273963a6..f383fb525a 100644 --- a/src/doveadm/client-connection-http.c +++ b/src/doveadm/client-connection-http.c @@ -200,8 +200,11 @@ static void doveadm_http_server_json_success(void *context, struct istream *resu static int doveadm_http_server_istream_read(struct client_connection_http *conn) { - while (i_stream_read(conn->cmd_param->value.v_istream) > 0) - i_stream_skip(conn->cmd_param->value.v_istream, i_stream_get_data_size(conn->cmd_param->value.v_istream)); + const unsigned char *data; + size_t size; + + while (i_stream_read_more(conn->cmd_param->value.v_istream, &data, &size) > 0) + i_stream_skip(conn->cmd_param->value.v_istream, size); if (!conn->cmd_param->value.v_istream->eof) return 0; diff --git a/src/doveadm/doveadm-mail-save.c b/src/doveadm/doveadm-mail-save.c index 2e9169891d..6208e8b988 100644 --- a/src/doveadm/doveadm-mail-save.c +++ b/src/doveadm/doveadm-mail-save.c @@ -35,13 +35,13 @@ cmd_save_to_mailbox(struct save_cmd_context *ctx, struct mailbox *box, mailbox_transaction_rollback(&trans); return -1; } - while ((ret = i_stream_read(input)) > 0 || ret == -2) { + do { if (mailbox_save_continue(save_ctx) < 0) { save_failed = TRUE; ret = -1; break; } - } + } while ((ret = i_stream_read(input)) > 0); i_assert(ret == -1); if (input->stream_errno != 0) { diff --git a/src/doveadm/doveadm-mail.c b/src/doveadm/doveadm-mail.c index 03c8e65eca..703fb23d99 100644 --- a/src/doveadm/doveadm-mail.c +++ b/src/doveadm/doveadm-mail.c @@ -163,8 +163,11 @@ static struct doveadm_mail_cmd_context *cmd_purge_alloc(void) static void doveadm_mail_cmd_input_input(struct doveadm_mail_cmd_context *ctx) { - while (i_stream_read(ctx->cmd_input) > 0) - i_stream_skip(ctx->cmd_input, i_stream_get_data_size(ctx->cmd_input)); + const unsigned char *data; + size_t size; + + while (i_stream_read_more(ctx->cmd_input, &data, &size) > 0) + i_stream_skip(ctx->cmd_input, size); if (!ctx->cmd_input->eof) return; diff --git a/src/doveadm/dsync/dsync-mail.c b/src/doveadm/dsync/dsync-mail.c index 19b22c1db6..7bea5e89f1 100644 --- a/src/doveadm/dsync/dsync-mail.c +++ b/src/doveadm/dsync/dsync-mail.c @@ -35,6 +35,7 @@ int dsync_mail_get_hdr_hash(struct mail *mail, unsigned int version, unsigned char md5_result[MD5_RESULTLEN]; const unsigned char *data; size_t size; + ssize_t sret; int ret = 0; hdr_ctx = mailbox_header_lookup_init(mail->box, hashed_headers); @@ -47,15 +48,12 @@ int dsync_mail_get_hdr_hash(struct mail *mail, unsigned int version, md5_init(&md5_ctx); memset(&hash_ctx, 0, sizeof(hash_ctx)); - while (!i_stream_is_eof(input)) { - if (i_stream_read_more(input, &data, &size) == -1) - break; - if (size == 0) - break; + while ((sret = i_stream_read_more(input, &data, &size)) > 0) { message_header_hash_more(&hash_ctx, &hash_method_md5, &md5_ctx, version, data, size); i_stream_skip(input, size); } + i_assert(sret == -1); if (input->stream_errno != 0) ret = -1; i_stream_unref(&input); diff --git a/src/imap/cmd-append.c b/src/imap/cmd-append.c index f0093113db..fc6e1a9da2 100644 --- a/src/imap/cmd-append.c +++ b/src/imap/cmd-append.c @@ -205,12 +205,10 @@ cmd_append_catenate_mpurl(struct client_command_context *cmd, /* add this input stream to chain */ i_stream_chain_append(ctx->catchain, mpresult.input); /* save by reading the chain stream */ - while (!i_stream_is_eof(mpresult.input)) { + do { ret = i_stream_read(mpresult.input); i_assert(ret != 0); /* we can handle only blocking input here */ - if (mailbox_save_continue(ctx->save_ctx) < 0 || ret == -1) - break; - } + } while (mailbox_save_continue(ctx->save_ctx) == 0 && ret != -1); if (mpresult.input->stream_errno != 0) { mail_storage_set_critical(ctx->box->storage, diff --git a/src/lib-compression/istream-bzlib.c b/src/lib-compression/istream-bzlib.c index c17d66fcd5..16cb1f606c 100644 --- a/src/lib-compression/istream-bzlib.c +++ b/src/lib-compression/istream-bzlib.c @@ -225,6 +225,8 @@ i_stream_bzlib_seek(struct istream_private *stream, uoff_t v_offset, bool mark) stream->pos = stream->skip; } else { /* read and cache forward */ + ssize_t ret; + do { size_t avail = stream->pos - stream->skip; @@ -236,7 +238,8 @@ i_stream_bzlib_seek(struct istream_private *stream, uoff_t v_offset, bool mark) } i_stream_skip(&stream->istream, avail); - } while (i_stream_read(&stream->istream) >= 0); + } while ((ret = i_stream_read(&stream->istream)) > 0); + i_assert(ret == -1); if (stream->istream.v_offset != v_offset) { /* some failure, we've broken it */ @@ -279,11 +282,13 @@ i_stream_bzlib_stat(struct istream_private *stream, bool exact) if (zstream->stream_size == (uoff_t)-1) { uoff_t old_offset = stream->istream.v_offset; + ssize_t ret; do { size = i_stream_get_data_size(&stream->istream); i_stream_skip(&stream->istream, size); - } while (i_stream_read(&stream->istream) > 0); + } while ((ret = i_stream_read(&stream->istream)) > 0); + i_assert(ret == -1); i_stream_seek(&stream->istream, old_offset); if (zstream->stream_size == (uoff_t)-1) diff --git a/src/lib-compression/istream-lz4.c b/src/lib-compression/istream-lz4.c index e4ac44a85b..389cfe8f3d 100644 --- a/src/lib-compression/istream-lz4.c +++ b/src/lib-compression/istream-lz4.c @@ -208,6 +208,8 @@ i_stream_lz4_seek(struct istream_private *stream, uoff_t v_offset, bool mark) stream->pos = stream->skip; } else { /* read and cache forward */ + ssize_t ret; + do { size_t avail = stream->pos - stream->skip; @@ -219,7 +221,8 @@ i_stream_lz4_seek(struct istream_private *stream, uoff_t v_offset, bool mark) } i_stream_skip(&stream->istream, avail); - } while (i_stream_read(&stream->istream) >= 0); + } while ((ret = i_stream_read(&stream->istream)) > 0); + i_assert(ret == -1); if (stream->istream.v_offset != v_offset) { /* some failure, we've broken it */ @@ -262,11 +265,13 @@ i_stream_lz4_stat(struct istream_private *stream, bool exact) if (zstream->stream_size == (uoff_t)-1) { uoff_t old_offset = stream->istream.v_offset; + ssize_t ret; do { size = i_stream_get_data_size(&stream->istream); i_stream_skip(&stream->istream, size); - } while (i_stream_read(&stream->istream) > 0); + } while ((ret = i_stream_read(&stream->istream)) > 0); + i_assert(ret == -1); i_stream_seek(&stream->istream, old_offset); if (zstream->stream_size == (uoff_t)-1) diff --git a/src/lib-compression/istream-lzma.c b/src/lib-compression/istream-lzma.c index 9c24a00832..2cb3969e7b 100644 --- a/src/lib-compression/istream-lzma.c +++ b/src/lib-compression/istream-lzma.c @@ -234,6 +234,8 @@ i_stream_lzma_seek(struct istream_private *stream, uoff_t v_offset, bool mark) stream->pos = stream->skip; } else { /* read and cache forward */ + ssize_t ret; + do { size_t avail = stream->pos - stream->skip; @@ -245,7 +247,8 @@ i_stream_lzma_seek(struct istream_private *stream, uoff_t v_offset, bool mark) } i_stream_skip(&stream->istream, avail); - } while (i_stream_read(&stream->istream) >= 0); + } while ((ret = i_stream_read(&stream->istream)) > 0); + i_assert(ret == -1); if (stream->istream.v_offset != v_offset) { /* some failure, we've broken it */ @@ -288,11 +291,13 @@ i_stream_lzma_stat(struct istream_private *stream, bool exact) if (zstream->stream_size == (uoff_t)-1) { uoff_t old_offset = stream->istream.v_offset; + ssize_t ret; do { size = i_stream_get_data_size(&stream->istream); i_stream_skip(&stream->istream, size); - } while (i_stream_read(&stream->istream) > 0); + } while ((ret = i_stream_read(&stream->istream)) > 0); + i_assert(ret == -1); i_stream_seek(&stream->istream, old_offset); if (zstream->stream_size == (uoff_t)-1) diff --git a/src/lib-compression/istream-zlib.c b/src/lib-compression/istream-zlib.c index 4366ab330a..1dad3e480f 100644 --- a/src/lib-compression/istream-zlib.c +++ b/src/lib-compression/istream-zlib.c @@ -378,6 +378,8 @@ i_stream_zlib_seek(struct istream_private *stream, uoff_t v_offset, bool mark) stream->pos = stream->skip; } else { /* read and cache forward */ + ssize_t ret; + do { size_t avail = stream->pos - stream->skip; @@ -389,7 +391,8 @@ i_stream_zlib_seek(struct istream_private *stream, uoff_t v_offset, bool mark) } i_stream_skip(&stream->istream, avail); - } while (i_stream_read(&stream->istream) >= 0); + } while ((ret = i_stream_read(&stream->istream)) > 0); + i_assert(ret == -1); if (stream->istream.v_offset != v_offset) { /* some failure, we've broken it */ @@ -432,11 +435,13 @@ i_stream_zlib_stat(struct istream_private *stream, bool exact) if (zstream->stream_size == (uoff_t)-1) { uoff_t old_offset = stream->istream.v_offset; + ssize_t ret; do { size = i_stream_get_data_size(&stream->istream); i_stream_skip(&stream->istream, size); - } while (i_stream_read(&stream->istream) > 0); + } while ((ret = i_stream_read(&stream->istream)) > 0); + i_assert(ret == -1); i_stream_seek(&stream->istream, old_offset); if (zstream->stream_size == (uoff_t)-1) diff --git a/src/lib-dict-extra/dict-fs.c b/src/lib-dict-extra/dict-fs.c index f7554e6190..cc07472983 100644 --- a/src/lib-dict-extra/dict-fs.c +++ b/src/lib-dict-extra/dict-fs.c @@ -94,7 +94,7 @@ static int fs_dict_lookup(struct dict *_dict, pool_t pool, const char *key, path = fs_dict_get_full_key(dict, key); file = fs_file_init(dict->fs, path, FS_OPEN_MODE_READONLY); input = fs_read_stream(file, IO_BLOCK_SIZE); - i_stream_read(input); + (void)i_stream_read(input); str = str_new(pool, i_stream_get_data_size(input)+1); while ((ret = i_stream_read_more(input, &data, &size)) > 0) { diff --git a/src/lib-http/http-client-connection.c b/src/lib-http/http-client-connection.c index 05a866a61f..50386b0bff 100644 --- a/src/lib-http/http-client-connection.c +++ b/src/lib-http/http-client-connection.c @@ -703,7 +703,7 @@ static void http_client_connection_input(struct connection *_conn) if (conn->ssl_iostream != NULL && !ssl_iostream_is_handshaked(conn->ssl_iostream)) { /* finish SSL negotiation by reading from input stream */ - while ((ret=i_stream_read(conn->conn.input)) > 0) { + while ((ret=i_stream_read(conn->conn.input)) > 0 || ret == -2) { if (ssl_iostream_is_handshaked(conn->ssl_iostream)) break; } diff --git a/src/lib-mail/istream-attachment-extractor.c b/src/lib-mail/istream-attachment-extractor.c index 7bdd2b8767..90cdfd96c2 100644 --- a/src/lib-mail/istream-attachment-extractor.c +++ b/src/lib-mail/istream-attachment-extractor.c @@ -375,8 +375,7 @@ static int astream_decode_base64(struct attachment_istream *astream) o_stream_cork(output); hash_format_reset(astream->set.hash_format); - while ((ret = i_stream_read(base64_input)) > 0) { - data = i_stream_get_data(base64_input, &size); + while ((ret = i_stream_read_more(base64_input, &data, &size)) > 0) { buffer_set_used_size(buf, 0); if (base64_decode(data, size, &size, buf) < 0) { i_error("istream-attachment: BUG: " diff --git a/src/lib-storage/index/index-attachment.c b/src/lib-storage/index/index-attachment.c index b77a034df0..39516a928f 100644 --- a/src/lib-storage/index/index-attachment.c +++ b/src/lib-storage/index/index-attachment.c @@ -216,7 +216,7 @@ int index_attachment_save_continue(struct mail_save_context *ctx) do { ret = i_stream_read(attach->input); - if (ret > 0) { + if (ret > 0 || ret == -2) { data = i_stream_get_data(attach->input, &size); o_stream_nsend(ctx->data.output, data, size); i_stream_skip(attach->input, size); diff --git a/src/lib-storage/index/mbox/mbox-save.c b/src/lib-storage/index/mbox/mbox-save.c index d19612773f..1437a6ec18 100644 --- a/src/lib-storage/index/mbox/mbox-save.c +++ b/src/lib-storage/index/mbox/mbox-save.c @@ -598,8 +598,7 @@ int mbox_save_continue(struct mail_save_context *_ctx) return mbox_save_body(ctx); } - while ((ret = i_stream_read(ctx->input)) > 0) { - data = i_stream_get_data(ctx->input, &size); + while ((ret = i_stream_read_more(ctx->input, &data, &size)) > 0) { for (i = 0; i < size; i++) { if (data[i] == '\n' && ((i == 0 && ctx->last_char == '\n') || diff --git a/src/lib-storage/mail-copy.c b/src/lib-storage/mail-copy.c index 91df2613bc..3796e2c18f 100644 --- a/src/lib-storage/mail-copy.c +++ b/src/lib-storage/mail-copy.c @@ -76,10 +76,13 @@ mail_storage_try_copy(struct mail_save_context **_ctx, struct mail *mail) if (mailbox_save_begin(_ctx, input) < 0) return -1; + ssize_t ret; do { if (mailbox_save_continue(ctx) < 0) break; - } while (i_stream_read(input) != -1); + ret = i_stream_read(input); + i_assert(ret != 0); + } while (ret != -1); if (input->stream_errno != 0) { mail_storage_set_critical(ctx->transaction->box->storage, diff --git a/src/lib/istream-seekable.c b/src/lib/istream-seekable.c index f051fcc257..ff1719d8c8 100644 --- a/src/lib/istream-seekable.c +++ b/src/lib/istream-seekable.c @@ -115,10 +115,14 @@ static int copy_to_temp_file(struct seekable_istream *sstream) if (size >= stream->pos) break; - if (i_stream_read(sstream->fd_input) <= 0) { + ssize_t ret; + if ((ret = i_stream_read(sstream->fd_input)) <= 0) { + i_assert(ret != 0); i_error("istream-seekable: Couldn't read back " - "in-memory input %s", - i_stream_get_name(&stream->istream)); + "in-memory input %s: %s", + i_stream_get_name(&stream->istream), + ret == -2 ? "buffer full" : + i_stream_get_error(sstream->fd_input)); i_stream_destroy(&sstream->fd_input); return -1; }