]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: istream - Fix calling i_stream_nonseekable_try_seek() without intermittent reads.
authorStephan Bosch <stephan.bosch@open-xchange.com>
Sun, 13 Oct 2019 09:01:53 +0000 (11:01 +0200)
committerTimo Sirainen <timo.sirainen@open-xchange.com>
Sun, 13 Oct 2019 14:26:12 +0000 (14:26 +0000)
Calling i_stream_nonseekable_try_seek() sets stream->high_pos when seeking back
within buffer. Once i_stream_read_memarea() is called, the pos is set to
high_pos and the high pos is cleared. However, when no read is performed in the
mean time, another call to i_stream_nonseekable_try_seek() would overwrite the
high_pos value with pos, causing the true value to get lost, leading to all
kinds of issues. This is fixed by checking whether high_pos is already set and
not touching it when it is (first value is the only valid one).

One issue this caused is that the mbox storage would no longer work with
compression, triggering `unexpected EOF' errors.

src/lib/istream.c

index 83b8008495ca2e7e58581100659bbf0321c26c0e..8fd6414022f0fdb5f6a26ef564f4318cd17b0c6e 100644 (file)
@@ -1065,7 +1065,8 @@ bool i_stream_nonseekable_try_seek(struct istream_private *stream,
                /* seeking backwards within what's already cached */
                stream->skip = v_offset - start_offset;
                stream->istream.v_offset = v_offset;
-               stream->high_pos = stream->pos;
+               if (stream->high_pos == 0)
+                       stream->high_pos = stream->pos;
                stream->pos = stream->skip;
        } else {
                /* read forward */