changeset 22224:dc1996f95c89

lib: istream-seekable - Fix reading when parent stream's content is larger than max_buffer_size 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.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Wed, 14 Jun 2017 03:21:19 +0300
parents 7fa4ccc9a738
children e3ebc1be3d49
files src/lib/istream-seekable.c
diffstat 1 files changed, 8 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib/istream-seekable.c	Mon Jun 12 23:45:05 2017 +0300
+++ b/src/lib/istream-seekable.c	Wed Jun 14 03:21:19 2017 +0300
@@ -103,8 +103,8 @@
 	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 @@
 		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);