From: Timo Sirainen Date: Mon, 4 Oct 2021 15:17:49 +0000 (+0300) Subject: lib: istream-chain - Fix snapshot handling when combining two istreams X-Git-Tag: 2.3.18~217 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=504c0e6424c46a8ad58c98577b2d6d92b6faec91;p=thirdparty%2Fdovecot%2Fcore.git lib: istream-chain - Fix snapshot handling when combining two istreams Snapshotting wasn't handled correctly when two (or more) istreams' contents were combined into the same buffer. --- diff --git a/src/lib/istream-chain.c b/src/lib/istream-chain.c index 543a99a6e7..ea141f53e2 100644 --- a/src/lib/istream-chain.c +++ b/src/lib/istream-chain.c @@ -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); } diff --git a/src/lib/test-istream-chain.c b/src/lib/test-istream-chain.c index 0da4d3f9ed..162fc6522c 100644 --- a/src/lib/test-istream-chain.c +++ b/src/lib/test-istream-chain.c @@ -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);