Mercurial > dovecot > core-2.2
changeset 19946:7ffdbac8e3ae
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.
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Mon, 21 Mar 2016 21:51:49 +0900 |
parents | e8f9cf430e53 |
children | 7b498de3bdba |
files | src/lib/istream-concat.c |
diffstat | 1 files changed, 14 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib/istream-concat.c Mon Mar 21 21:46:47 2016 +0900 +++ b/src/lib/istream-concat.c Mon Mar 21 21:51:49 2016 +0900 @@ -137,10 +137,7 @@ 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 @@ 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