]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: istream-seekable - Fix reading when parent stream's content is larger than max_b...
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 14 Jun 2017 00:21:19 +0000 (03:21 +0300)
committerVille Savolainen <ville.savolainen@dovecot.fi>
Fri, 16 Jun 2017 06:17:57 +0000 (09:17 +0300)
When writing the parent stream to fd and trying to read it back, it would
try to enforce the max_buffer_size and fail with:

istream-seekable: Couldn't read back in-memory input ...: buffer full

But since the data was already in buffer, istream-seekable shouldn't try to
enforce it at this point anymore.

src/lib/istream-seekable.c

index 8639f1447a4c6f5ab8d33fb212e271aa86d5dcde..70e11636ce4dd0ec44b5df1ceae2befd1fdbb634 100644 (file)
@@ -103,8 +103,8 @@ static int copy_to_temp_file(struct seekable_istream *sstream)
        sstream->write_peak = sstream->membuf->used;
 
        sstream->fd = fd;
-       sstream->fd_input =
-               i_stream_create_fd_autoclose(&fd, sstream->istream.max_buffer_size);
+       sstream->fd_input = i_stream_create_fd_autoclose(&fd,
+               I_MAX(stream->pos, sstream->istream.max_buffer_size));
        i_stream_set_name(sstream->fd_input, t_strdup_printf(
                "(seekable temp-istream for: %s)", i_stream_get_name(&stream->istream)));
 
@@ -118,15 +118,20 @@ static int copy_to_temp_file(struct seekable_istream *sstream)
                ssize_t ret;
                if ((ret = i_stream_read(sstream->fd_input)) <= 0) {
                        i_assert(ret != 0);
+                       i_assert(ret != -2);
                        i_error("istream-seekable: Couldn't read back "
                                "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;
                }
        }
+       /* Set the max buffer size only after we've already read everything
+          into memory. For example with istream-data it's possible that
+          more data exists in buffer than max_buffer_size. */
+       i_stream_set_max_buffer_size(sstream->fd_input,
+                                    sstream->istream.max_buffer_size);
        stream->buffer = buffer;
        stream->pos = size;
        buffer_free(&sstream->membuf);