]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
global: Make sure i_stream_read() calls handle 0 and -2 return values correctly.
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 6 Oct 2016 10:50:59 +0000 (13:50 +0300)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 13 Oct 2016 08:23:24 +0000 (10:23 +0200)
16 files changed:
src/doveadm/client-connection-http.c
src/doveadm/doveadm-mail-save.c
src/doveadm/doveadm-mail.c
src/doveadm/dsync/dsync-mail.c
src/imap/cmd-append.c
src/lib-compression/istream-bzlib.c
src/lib-compression/istream-lz4.c
src/lib-compression/istream-lzma.c
src/lib-compression/istream-zlib.c
src/lib-dict-extra/dict-fs.c
src/lib-http/http-client-connection.c
src/lib-mail/istream-attachment-extractor.c
src/lib-storage/index/index-attachment.c
src/lib-storage/index/mbox/mbox-save.c
src/lib-storage/mail-copy.c
src/lib/istream-seekable.c

index 63716faff9e8d0b16d87a588d57dce34ecd36cfd..2e28f144d791fe68079431f1ad49756b5d79d235 100644 (file)
@@ -206,8 +206,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;
 
index 2e9169891ddc8385063478220c14fbc5d9ba08cb..6208e8b988d5a7dbfcf8848ac5755c7a7efcb115 100644 (file)
@@ -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) {
index 565967d1ceff9d07de62c506928220b22b415774..b8c14839415f00a92121666878e570e79a7cfb31 100644 (file)
@@ -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;
 
index 9d52d99df73ed8f7852e1cd3aeba9806446c65d6..7bea5e89f1088c3a755a84014bc3a75db8c72173 100644 (file)
@@ -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_data(input, &data, &size, 0) == -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);
index ad72018351b088ac48bb7e6b3f598ee1b6ea5198..c02fcdd39106f5665a61caff042d0ee57b0d27a7 100644 (file)
@@ -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) {
                errno = mpresult.input->stream_errno;
index cb3db16ac8b1f5c4d6e174c301a8ad9addef7311..a834538d90b87d3632b70572f57dde1cf2d0dd8e 100644 (file)
@@ -226,6 +226,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;
 
@@ -237,7 +239,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 */
@@ -280,11 +283,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)
index ded44dc8ce70fd9bec7ff1fdfcf42f55eee6fe5e..ed5efd0214feb694e9af5396243f7f72586cc67b 100644 (file)
@@ -210,6 +210,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;
 
@@ -221,7 +223,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 */
@@ -264,11 +267,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)
index 8ead55128e63dcabbb7e1ac6c8093b3a665182c8..cf7e943832cfef6f4ef4c1a132a071e6af1dcbd2 100644 (file)
@@ -235,6 +235,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;
 
@@ -246,7 +248,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 */
@@ -289,11 +292,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)
index 228095c422b9fca93f2f54730a57ff1acd91b998..ae589c686b0dea97a519244f25bf355bbe00cb4f 100644 (file)
@@ -379,6 +379,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;
 
@@ -390,7 +392,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 */
@@ -433,11 +436,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)
index 3b4b58a79eda683a42a5334ca97d34e50b8d361e..7446d7edd1d9e3149b7e11b5b23cfe335f1a6910 100644 (file)
@@ -93,7 +93,7 @@ static int fs_dict_lookup(struct dict *_dict, pool_t pool,
        file = fs_file_init(dict->fs, fs_dict_get_full_key(dict, key),
                            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_data(input, &data, &size, 0)) > 0) {
index 5333d153f265b59017593b12a95c927a3eceb854..5aeb28456a954c11261f24dab449922b7e39cb38 100644 (file)
@@ -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;
                }
index 09a21ee7cc803dc94427f59b906a20ff06e5429c..250507631e67a9e1455d3568fd63c2a0f4134a4b 100644 (file)
@@ -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: "
index 6735c4fba79a0b35e281827e1a98eda74f86e8ae..a414cc726e04b2903f7ed46f745c2caa0cf5aaf5 100644 (file)
@@ -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);
index 3724c68ffcf1659486dfd8851a0a10ad85831f42..3c8a48e6b3f8a52d8ed5b0de7bd51c9e1bc0686f 100644 (file)
@@ -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') ||
index 91df2613bc08f2f381f662929d7d4e7c37edeb74..3796e2c18f5541263b4e6f51c7e0d78f1f647468 100644 (file)
@@ -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,
index f051fcc25770179767ddf0ec3c6e4294130eb93b..ff1719d8c86dcb4039f7c8c6870750eddfb1b720 100644 (file)
@@ -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;
                }