]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: istream-chain - Fix snapshot handling when combining two istreams
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Mon, 4 Oct 2021 15:17:49 +0000 (18:17 +0300)
committertimo.sirainen <timo.sirainen@open-xchange.com>
Fri, 8 Oct 2021 13:14:15 +0000 (13:14 +0000)
Snapshotting wasn't handled correctly when two (or more) istreams' contents
were combined into the same buffer.

src/lib/istream-chain.c
src/lib/test-istream-chain.c

index 543a99a6e7399aaa4f2edb8777517d93462e75d1..ea141f53e25013d8b15f3be6814aa07a66d6eef1 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "lib.h"
 #include "llist.h"
+#include "memarea.h"
 #include "istream-private.h"
 #include "istream-chain.h"
 
@@ -153,6 +154,9 @@ static void i_stream_chain_read_next(struct chain_istream *cstream)
        }
 
        if (data_size > 0) {
+               if (cstream->istream.memarea != NULL &&
+                   memarea_get_refcount(cstream->istream.memarea) > 1)
+                       i_stream_memarea_detach(&cstream->istream);
                memcpy(i_stream_alloc(&cstream->istream, data_size),
                       data, data_size);
                cstream->istream.pos += data_size;
@@ -319,6 +323,5 @@ struct istream *i_stream_create_chain(struct istream_chain **chain_r)
        cstream->istream.istream.seekable = FALSE;
 
        *chain_r = &cstream->chain;
-       return i_stream_create(&cstream->istream, NULL, -1,
-                              ISTREAM_CREATE_FLAG_NOOP_SNAPSHOT);
+       return i_stream_create(&cstream->istream, NULL, -1, 0);
 }
index 0da4d3f9ed40f8a3cb533f66ba36115debc9aee6..162fc6522c4992301791eeb2f8ff34d451d52977 100644 (file)
@@ -112,7 +112,17 @@ static void test_istream_chain_accumulate(void)
 
        /* second stream */
        i_stream_chain_append(chain, test_input2);
+       test_istream_set_size(test_input2, 0);
+       test_assert(i_stream_read_data(input, &data, &size, 10) == 0);
+       test_assert(size == 8);
+       test_istream_set_size(test_input2, 10);
        test_assert(i_stream_read_data(input, &data, &size, 10) == 1);
+       test_assert(size == 18);
+       test_istream_set_allow_eof(test_input2, FALSE);
+       test_assert(i_stream_read(input) == 0);
+       test_istream_set_size(test_input2, 25);
+       test_istream_set_allow_eof(test_input2, TRUE);
+       test_assert(i_stream_read_data(input, &data, &size, 30) == 1);
        test_assert(size == 33);
        test_assert(memcmp(data, "mnopqrst"
                "ABCDEFGHIJKLMNOPQRSTUVWXY", 33) == 0);
@@ -122,10 +132,14 @@ static void test_istream_chain_accumulate(void)
 
        /* third stream */
        i_stream_chain_append(chain, test_input3);
+       test_istream_set_size(test_input3, 0);
+       test_assert(i_stream_read(input) == 0);
+       test_istream_set_size(test_input3, 30);
        test_assert(i_stream_read_data(input, &data, &size, 25) == 1);
        test_assert(size == 51);
        test_assert(memcmp(data, "EFGHIJKLMNOPQRSTUVWXY"
                "!\"#$%&'()*+,-./01234567890:;<=", 51) == 0);
+       test_assert(i_stream_read(input) == 0);
 
        /* partially skip */
        i_stream_skip(input, 12);