]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-dcrypt: Fixed partial reads in header and limit header's max size.
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 17 Aug 2016 13:25:12 +0000 (16:25 +0300)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Wed, 17 Aug 2016 15:24:17 +0000 (18:24 +0300)
Also fixes test-stream to actually test nonblocking reads correctly.

src/lib-dcrypt/istream-decrypt.c
src/lib-dcrypt/test-stream.c

index 3f60d9c7f32ce6e4c1d58a559f9f068fad4d1759..a514b24d7d9c977975fca825c68fc03594f2844d 100644 (file)
@@ -670,8 +670,8 @@ i_stream_decrypt_read(struct istream_private *stream)
                }
                /* need to read more input */
                ret = i_stream_read(stream->parent);
-               if (ret == 0)
-                       return 0;
+               if (ret == 0 || ret == -2)
+                       return ret;
                data = i_stream_get_data(stream->parent, &size);
 
                if (ret == -1 && (size == 0 || stream->parent->stream_errno != 0)) {
@@ -709,11 +709,7 @@ i_stream_decrypt_read(struct istream_private *stream)
                if (!dstream->initialized) {
                        ssize_t hret;
 
-                       /* put the data in buffer */
-                       buffer_append(dstream->buf, data, size);
-
-                       if ((hret=i_stream_decrypt_read_header
-                               (dstream, dstream->buf->data, dstream->buf->used)) <= 0) {
+                       if ((hret=i_stream_decrypt_read_header(dstream, data, size)) <= 0) {
                                if (hret < 0) {
                                        if (stream->istream.stream_errno == 0)
                                                /* assume temporary failure */
@@ -732,7 +728,6 @@ i_stream_decrypt_read(struct istream_private *stream)
 
                        if (hret == 0) {
                                /* see if we can get more data */
-                               i_stream_skip(stream->parent, size);
                                continue;
                        } else {
                                /* clean up buffer */
index 06c5d3775975f0a439d637749257cd90f8a34b27..4fac0874b063aacae94885e1d3adb347cc1235bf 100644 (file)
@@ -202,15 +202,18 @@ void test_write_read_v1(void)
        struct istream *is_2 = i_stream_create_decrypt(is, test_v2_kp.priv);
 
        size_t offset = 0;
+       test_istream_set_allow_eof(is, FALSE);
+       test_istream_set_size(is, 0);
        while(i_stream_read_data(is_2, &ptr, &siz, 0)>=0) {
                if (offset == buf->used)
                        test_istream_set_allow_eof(is, TRUE);
-               test_istream_set_size(is, offset);
+               else
+                       test_istream_set_size(is, ++offset);
 
                test_assert_idx(pos + siz <= sizeof(payload), pos);
                if (pos + siz > sizeof(payload)) break;
                test_assert_idx(memcmp(ptr, payload + pos, siz) == 0, pos);
-               i_stream_skip(is_2, siz);
+               i_stream_skip(is_2, siz); pos += siz;
        }
 
        test_assert(is_2->stream_errno == 0);
@@ -250,15 +253,18 @@ void test_write_read_v1_short(void)
        struct istream *is_2 = i_stream_create_decrypt(is, test_v2_kp.priv);
 
        size_t offset = 0;
+       test_istream_set_allow_eof(is, FALSE);
+       test_istream_set_size(is, 0);
        while(i_stream_read_data(is_2, &ptr, &siz, 0)>=0) {
                if (offset == buf->used)
                        test_istream_set_allow_eof(is, TRUE);
-               test_istream_set_size(is, offset);
+               else
+                       test_istream_set_size(is, ++offset);
 
                test_assert_idx(pos + siz <= sizeof(payload), pos);
                if (pos + siz > sizeof(payload)) break;
                test_assert_idx(memcmp(ptr, payload + pos, siz) == 0, pos);
-               i_stream_skip(is_2, siz);
+               i_stream_skip(is_2, siz); pos += siz;
        }
 
        test_assert(is_2->stream_errno == 0);
@@ -291,13 +297,16 @@ void test_write_read_v1_empty(void)
        struct istream *is_2 = i_stream_create_decrypt(is, test_v1_kp.priv);
 
        /* read should not fail */
+       test_istream_set_allow_eof(is, FALSE);
+       test_istream_set_size(is, 0);
        size_t offset = 0;
        ssize_t ret;
        while ((ret = i_stream_read_data(is_2, &ptr, &siz, 0)) >= 0) {
                test_assert(ret == 0);
                if (offset == buf->used)
                        test_istream_set_allow_eof(is, TRUE);
-               test_istream_set_size(is, offset);
+               else
+                       test_istream_set_size(is, ++offset);
        };
 
        test_assert(is_2->stream_errno == 0);
@@ -333,15 +342,18 @@ void test_write_read_v2(void)
        struct istream *is_2 = i_stream_create_decrypt(is, test_v1_kp.priv);
 
        size_t offset = 0;
+       test_istream_set_size(is, 0);
+       test_istream_set_allow_eof(is, FALSE);
        while(i_stream_read_data(is_2, &ptr, &siz, 0)>=0) {
                if (offset == buf->used)
                        test_istream_set_allow_eof(is, TRUE);
-               test_istream_set_size(is, offset);
+               else
+                       test_istream_set_size(is, ++offset);
 
                test_assert_idx(pos + siz <= sizeof(payload), pos);
                if (pos + siz > sizeof(payload)) break;
                test_assert_idx(memcmp(ptr, payload + pos, siz) == 0, pos);
-               i_stream_skip(is_2, siz);
+               i_stream_skip(is_2, siz); pos += siz;
        }
 
        test_assert(is_2->stream_errno == 0);
@@ -379,15 +391,17 @@ void test_write_read_v2_short(void)
        struct istream *is_2 = i_stream_create_decrypt(is, test_v1_kp.priv);
 
        size_t offset = 0;
+       test_istream_set_allow_eof(is, FALSE);
+       test_istream_set_size(is, 0);
        while(i_stream_read_data(is_2, &ptr, &siz, 0)>=0) {
                if (offset == buf->used)
                        test_istream_set_allow_eof(is, TRUE);
-               test_istream_set_size(is, offset);
+               test_istream_set_size(is, ++offset);
 
                test_assert_idx(pos + siz <= sizeof(payload), pos);
                if (pos + siz > sizeof(payload)) break;
                test_assert_idx(memcmp(ptr, payload + pos, siz) == 0, pos);
-               i_stream_skip(is_2, siz);
+               i_stream_skip(is_2, siz); pos += siz;
        }
 
        test_assert(is_2->stream_errno == 0);
@@ -423,12 +437,14 @@ void test_write_read_v2_empty(void)
 
        /* read should not fail */
        size_t offset = 0;
+       test_istream_set_allow_eof(is, FALSE);
+       test_istream_set_size(is, 0);
        ssize_t ret;
        while ((ret = i_stream_read_data(is_2, &ptr, &siz, 0)) >= 0) {
                test_assert(ret == 0);
                if (offset == buf->used)
                        test_istream_set_allow_eof(is, TRUE);
-               test_istream_set_size(is, offset);
+               test_istream_set_size(is, ++offset);
        };
 
        test_assert(is_2->stream_errno == 0);
@@ -459,6 +475,7 @@ static void test_read_0_to_400_byte_garbage(void)
                struct istream *is = test_istream_create_data(data, s);
                struct istream *ds = i_stream_create_decrypt_callback(is,
                                no_op_cb, NULL);
+               test_istream_set_size(is, 0);
                test_istream_set_allow_eof(is, FALSE);
                ssize_t siz = 0;
                for (size_t offset = 0; offset <= s && siz == 0; offset++) {