ret = -1;
} else
do {
- if ((ret=i_stream_read_memarea(stream->parent)) == -2) {
- return -2; /* input buffer full */
- }
-
- if (ret == 0 || (ret < 0 && !stream->parent->eof))
- break;
-
+ ret = i_stream_read_memarea(stream->parent);
stream->istream.stream_errno =
stream->parent->stream_errno;
stream->buffer =
i_stream_get_data(stream->parent, &pos);
+ if (ret == -2)
+ return -2; /* input buffer full */
+ if (ret == 0 || (ret < 0 && !stream->parent->eof))
+ break;
if (stream->parent->eof) {
/* Check return code at EOF */
if (pos > stream->pos)
ret = 0;
else do {
- if ((ret = i_stream_read_memarea(stream->parent)) == -2)
- return -2;
-
+ ret = i_stream_read_memarea(stream->parent);
stream->istream.stream_errno = stream->parent->stream_errno;
stream->istream.eof = stream->parent->eof;
stream->buffer = i_stream_get_data(stream->parent, &pos);
} while (pos <= stream->pos && ret > 0);
+ if (ret == -2)
+ return -2;
if (lstream->v_size != (uoff_t)-1) {
left = lstream->v_size - stream->istream.v_offset;
if (pos > stream->pos)
ret = 0;
else do {
- if ((ret = i_stream_read_memarea(stream->parent)) == -2)
- return -2;
-
+ ret = i_stream_read_memarea(stream->parent);
stream->istream.stream_errno = stream->parent->stream_errno;
stream->istream.eof = stream->parent->eof;
stream->buffer = i_stream_get_data(stream->parent, &pos);
} while (pos <= stream->pos && ret > 0);
+ if (ret == -2)
+ return -2;
if (pos <= stream->pos)
ret = ret == 0 ? 0 : -1;
ssize_t ret;
do {
- if ((ret = i_stream_read_memarea(stream->parent)) == -2)
- break;
-
+ ret = i_stream_read_memarea(stream->parent);
stream->istream.stream_errno = stream->parent->stream_errno;
stream->istream.eof = stream->parent->eof;
stream->buffer = i_stream_get_data(stream->parent, pos_r);
if (pos > stream->pos)
ret = 0;
else do {
- if ((ret = i_stream_read_memarea(stream->parent)) == -2) {
- i_stream_update(stream);
- return -2;
- }
-
+ ret = i_stream_read_memarea(stream->parent);
stream->istream.stream_errno = stream->parent->stream_errno;
stream->istream.eof = stream->parent->eof;
stream->buffer = i_stream_get_data(stream->parent, &pos);
backwards and the previous read() didn't get us far
enough. */
} while (pos <= stream->pos && ret > 0);
+ if (ret == -2) {
+ i_stream_update(stream);
+ return -2;
+ }
ret = pos > stream->pos ? (ssize_t)(pos - stream->pos) :
(ret == 0 ? 0 : -1);
/* Copyright (c) 2009-2018 Dovecot authors, see the included COPYING file */
#include "test-lib.h"
+#include "sha2.h"
#include "istream-private.h"
+#include "istream-sized.h"
+#include "istream-hash.h"
#include "istream-seekable.h"
#include <fcntl.h>
test_end();
}
+static void test_istream_seekable_invalid_read(void)
+{
+ test_begin("istream seekable + other streams causing invalid read");
+ struct sha256_ctx hash_ctx;
+ sha256_init(&hash_ctx);
+ struct istream *str_input = test_istream_create("123456");
+ str_input->seekable = FALSE;
+ struct istream *seek_inputs[] = { str_input, NULL };
+ struct istream *seek_input = i_stream_create_seekable(seek_inputs, 3, fd_callback, NULL);
+ struct istream *sized_input = i_stream_create_sized(seek_input, 3);
+ struct istream *input = i_stream_create_hash(sized_input, &hash_method_sha256, &hash_ctx);
+ test_assert(i_stream_read(input) == 3);
+ test_assert(i_stream_read(input) == -2);
+ i_stream_skip(input, 3);
+ test_assert(i_stream_read(input) == -1);
+ i_stream_unref(&input);
+ i_stream_unref(&sized_input);
+ i_stream_unref(&seek_input);
+ i_stream_unref(&str_input);
+ test_end();
+}
+
void test_istream_seekable(void)
{
unsigned int i;
test_istream_seekable_eof();
test_istream_seekable_early_end();
+ test_istream_seekable_invalid_read();
}