From aea44e1dc4f2d1f8a2dbe05af839c220ae79aeba Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Mon, 21 Mar 2016 21:51:49 +0900 Subject: [PATCH] lib: Avoid assert-crash in istream-concat at close. If stream was seeked to EOF, cur_input=NULL and closing the stream would cause i_stream_concat_skip() to crash. Fixed this by making sure cur_input is never NULL. This also adds a check to not allow seeking past EOF, but this shouldn't happen anyway. --- src/lib/istream-concat.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/lib/istream-concat.c b/src/lib/istream-concat.c index 91c936f1a9..f490ec3171 100644 --- a/src/lib/istream-concat.c +++ b/src/lib/istream-concat.c @@ -137,10 +137,7 @@ static ssize_t i_stream_concat_read(struct istream_private *stream) ssize_t ret; bool last_stream; - if (cstream->cur_input == NULL) { - stream->istream.stream_errno = EINVAL; - return -1; - } + i_assert(cstream->cur_input != NULL); i_stream_concat_skip(cstream); i_assert(stream->pos >= stream->skip + cstream->prev_stream_left); @@ -274,13 +271,23 @@ static void i_stream_concat_seek(struct istream_private *stream, if (find_v_offset(cstream, &v_offset, &cstream->cur_idx) < 0) { /* failed */ - cstream->cur_input = NULL; stream->istream.stream_errno = EINVAL; return; } cstream->cur_input = cstream->input[cstream->cur_idx]; - if (cstream->cur_input != NULL) - i_stream_seek(cstream->cur_input, v_offset); + if (cstream->cur_input == NULL) { + /* we allow seeking to EOF, but not past it. */ + if (v_offset != 0) { + io_stream_set_error(&cstream->istream.iostream, + "Seeking past EOF by %"PRIuUOFF_T" bytes", v_offset); + cstream->istream.istream.stream_errno = EINVAL; + return; + } + i_assert(cstream->cur_idx > 0); + cstream->cur_input = cstream->input[cstream->cur_idx-1]; + v_offset = cstream->input_size[cstream->cur_idx-1]; + } + i_stream_seek(cstream->cur_input, v_offset); } static int