changeset 20663:e802abd40812

lib-dcrypt: Fixed partial reads in header and limit header's max size. Also fixes test-stream to actually test nonblocking reads correctly.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Wed, 17 Aug 2016 16:25:12 +0300
parents ff456e22d98b
children 6c2423ded89d
files src/lib-dcrypt/istream-decrypt.c src/lib-dcrypt/test-stream.c
diffstat 2 files changed, 30 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-dcrypt/istream-decrypt.c	Tue Aug 16 14:49:35 2016 +0300
+++ b/src/lib-dcrypt/istream-decrypt.c	Wed Aug 17 16:25:12 2016 +0300
@@ -670,8 +670,8 @@
 		}
 		/* 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 @@
 		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 @@
 
 			if (hret == 0) {
 				/* see if we can get more data */
-				i_stream_skip(stream->parent, size);
 				continue;
 			} else {
 				/* clean up buffer */
--- a/src/lib-dcrypt/test-stream.c	Tue Aug 16 14:49:35 2016 +0300
+++ b/src/lib-dcrypt/test-stream.c	Wed Aug 17 16:25:12 2016 +0300
@@ -202,15 +202,18 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 
 	/* 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 @@
 		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++) {