changeset 16726:fe8ac44541ae

istream-hash: Data was hashed multiple times in some situations
author Timo Sirainen <tss@iki.fi>
date Thu, 12 Sep 2013 02:58:51 +0300
parents 262fbb878ed4
children 1db5ede2a1cd
files src/lib/istream-hash.c
diffstat 1 files changed, 10 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib/istream-hash.c	Thu Sep 12 02:33:01 2013 +0300
+++ b/src/lib/istream-hash.c	Thu Sep 12 02:58:51 2013 +0300
@@ -10,6 +10,7 @@
 
 	const struct hash_method *method;
 	void *hash_context;
+	uoff_t high_offset;
 };
 
 static ssize_t
@@ -18,6 +19,7 @@
 	struct hash_istream *hstream = (struct hash_istream *)stream;
 	const unsigned char *data;
 	size_t size;
+	uoff_t skip;
 	ssize_t ret;
 
 	i_stream_seek(stream->parent, stream->parent_start_offset +
@@ -27,8 +29,14 @@
 	if (ret > 0 && hstream->hash_context != NULL) {
 		data = i_stream_get_data(&stream->istream, &size);
 		i_assert((size_t)ret <= size);
-		hstream->method->loop(hstream->hash_context,
-				      data+(size-ret), ret);
+
+		i_assert(stream->istream.v_offset <= hstream->high_offset);
+		skip = hstream->high_offset - stream->istream.v_offset;
+		if (skip < (size_t)size) {
+			hstream->high_offset += (size-skip);
+			hstream->method->loop(hstream->hash_context,
+					      data+skip, size-skip);
+		}
 	} else if (ret < 0) {
 		/* we finished hashing it. don't access it anymore, because
 		   the memory pointed by the hash may be freed before the