changeset 20699:998cb3da81d6

zlib-plugin: Check that UID is assigned When caching, code has to check whether UID is assigned to avoid reusing cache for different email since they all have UID = 0 before they are actually committed.
author Aki Tuomi <aki.tuomi@dovecot.fi>
date Mon, 05 Sep 2016 15:56:05 +0300
parents cc21ec4e56a3
children d974673e577c
files src/plugins/zlib/zlib-plugin.c
diffstat 1 files changed, 19 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/src/plugins/zlib/zlib-plugin.c	Tue Sep 06 16:17:13 2016 +0300
+++ b/src/plugins/zlib/zlib-plugin.c	Mon Sep 05 15:56:05 2016 +0300
@@ -75,13 +75,14 @@
 
 static struct istream *
 zlib_mail_cache_open(struct zlib_user *zuser, struct mail *mail,
-		     struct istream *input)
+		     struct istream *input, bool do_cache)
 {
 	struct zlib_mail_cache *cache = &zuser->cache;
 	struct istream *inputs[2];
 	string_t *temp_prefix = t_str_new(128);
 
-	zlib_mail_cache_close(zuser);
+	if (do_cache)
+		zlib_mail_cache_close(zuser);
 
 	/* zlib istream is seekable, but very slow. create a seekable istream
 	   which we can use to quickly seek around in the stream that's been
@@ -101,15 +102,18 @@
 						 i_stream_get_name(inputs[0])));
 	i_stream_unref(&inputs[0]);
 
-	cache->to = timeout_add(ZLIB_MAIL_CACHE_EXPIRE_MSECS,
-				zlib_mail_cache_close, zuser);
-	cache->box = mail->box;
-	cache->uid = mail->uid;
-	cache->input = input;
-
-	/* index-mail wants the stream to be destroyed at close, so create
-	   a new stream instead of just increasing reference. */
-	return i_stream_create_limit(cache->input, (uoff_t)-1);
+	if (do_cache) {
+		cache->to = timeout_add(ZLIB_MAIL_CACHE_EXPIRE_MSECS,
+					zlib_mail_cache_close, zuser);
+		cache->box = mail->box;
+		cache->uid = mail->uid;
+		cache->input = input;
+		/* index-mail wants the stream to be destroyed at close, so create
+		   a new stream instead of just increasing reference. */
+		return i_stream_create_limit(cache->input, (uoff_t)-1);
+	} else {
+		return input;
+	}
 }
 
 static int zlib_istream_opened(struct mail *_mail, struct istream **stream)
@@ -127,7 +131,7 @@
 		return zmail->module_ctx.super.istream_opened(_mail, stream);
 	}
 
-	if (cache->uid == _mail->uid && cache->box == _mail->box) {
+	if (_mail->uid > 0 && cache->uid == _mail->uid && cache->box == _mail->box) {
 		/* use the cached stream. when doing partial reads it should
 		   already be seeked into the wanted offset. */
 		i_stream_unref(stream);
@@ -148,8 +152,8 @@
 		input = *stream;
 		*stream = handler->create_istream(input, TRUE);
 		i_stream_unref(&input);
-
-		*stream = zlib_mail_cache_open(zuser, _mail, *stream);
+		/* dont cache the stream if _mail->uid is 0 */
+		*stream = zlib_mail_cache_open(zuser, _mail, *stream, (_mail->uid > 0));
 	}
 	return zmail->module_ctx.super.istream_opened(_mail, stream);
 }
@@ -162,7 +166,7 @@
 	struct zlib_mail_cache *cache = &zuser->cache;
 	uoff_t size;
 
-	if (cache->uid == _mail->uid && cache->box == _mail->box) {
+	if (_mail->uid > 0 && cache->uid == _mail->uid && cache->box == _mail->box) {
 		/* make sure we have read the entire email into the seekable
 		   stream (which causes the original input stream to be
 		   unrefed). we can't safely keep the original input stream