From 2f20547d7fd97f664d1562819df0bd6de3f37b46 Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan.bosch@open-xchange.com>
Date: Mon, 8 Jun 2020 19:26:50 +0200
Subject: [PATCH] testsuite: testsuite-message - Preserve all allocated mails
 until result is reset.

The actions contained in the result may keep references to the overriden mail
struct, so these need to be preserved.
---
 src/testsuite/cmd-test-result.c   |  1 +
 src/testsuite/testsuite-message.c | 83 ++++++++++++++++++++++++++++---
 src/testsuite/testsuite-message.h |  2 +
 src/testsuite/testsuite-result.c  |  1 +
 src/testsuite/testsuite.c         |  2 +-
 5 files changed, 80 insertions(+), 9 deletions(-)

diff --git a/src/testsuite/cmd-test-result.c b/src/testsuite/cmd-test-result.c
index 385dcd083..230aa62a5 100644
--- a/src/testsuite/cmd-test-result.c
+++ b/src/testsuite/cmd-test-result.c
@@ -14,6 +14,7 @@
 
 #include "testsuite-common.h"
 #include "testsuite-result.h"
+#include "testsuite-message.h"
 #include "testsuite-smtp.h"
 
 /*
diff --git a/src/testsuite/testsuite-message.c b/src/testsuite/testsuite-message.c
index c0105a2d6..68e20ebe6 100644
--- a/src/testsuite/testsuite-message.c
+++ b/src/testsuite/testsuite-message.c
@@ -8,6 +8,7 @@
 #include "message-address.h"
 #include "mail-storage.h"
 #include "master-service.h"
+#include "mail-raw.h"
 
 #include "sieve-common.h"
 #include "sieve-address.h"
@@ -24,10 +25,16 @@
  * Testsuite message environment
  */
 
+struct testsuite_message {
+	struct testsuite_message *next;
+
+	struct mail_raw *mail_raw;
+};
+
 struct sieve_message_data testsuite_msgdata;
 static struct smtp_params_rcpt testsuite_rcpt_params;
 
-static struct mail *testsuite_mail;
+static struct testsuite_message *testsuite_msg;
 
 static const char *_default_message_data =
 "From: sender@example.com\n"
@@ -123,6 +130,68 @@ static void testsuite_message_set_data(struct mail *mail)
 	testsuite_msgdata.envelope.rcpt_params = &testsuite_rcpt_params;
 }
 
+static struct testsuite_message *testsuite_message_new(void)
+{
+	struct testsuite_message *msg;
+
+	msg = i_new(struct testsuite_message, 1);
+	msg->next = testsuite_msg;
+	testsuite_msg = msg;
+
+	return msg;
+}
+
+static void testsuite_message_new_string(string_t *mail_str)
+{
+	struct mail_user *mail_raw_user =
+		sieve_tool_get_mail_raw_user(sieve_tool);
+	struct testsuite_message *msg;
+
+	msg = testsuite_message_new();
+	msg->mail_raw = mail_raw_open_data(mail_raw_user, mail_str);
+
+	testsuite_message_set_data(msg->mail_raw->mail);
+}
+
+static void testsuite_message_new_file(const char *mail_path)
+{
+	struct mail_user *mail_raw_user =
+		sieve_tool_get_mail_raw_user(sieve_tool);
+	struct testsuite_message *msg;
+
+	msg = testsuite_message_new();
+	msg->mail_raw = mail_raw_open_file(mail_raw_user, mail_path);
+
+	testsuite_message_set_data(msg->mail_raw->mail);
+}
+
+static void testsuite_message_free(bool all)
+{
+	struct testsuite_message *msg;
+
+	if (testsuite_msg == NULL)
+		return;
+
+	msg = (all ? testsuite_msg : testsuite_msg->next);
+	while (msg != NULL) {
+		struct testsuite_message *msg_next = msg->next;
+
+		mail_raw_close(&msg->mail_raw);
+		i_free(msg);
+
+		msg = msg_next;
+	}
+	if (all)
+		testsuite_msg = NULL;
+	else
+		testsuite_msg->next = NULL;
+}
+
+void testsuite_message_flush(void)
+{
+	testsuite_message_free(FALSE);
+}
+
 void testsuite_message_init(void)
 {
 	testsuite_msg_pool = pool_alloconly_create("testsuite_message", 6096);
@@ -130,9 +199,7 @@ void testsuite_message_init(void)
 	string_t *default_message = str_new(testsuite_msg_pool, 1024);
 	str_append(default_message, _default_message_data);
 
-	testsuite_mail =
-		sieve_tool_open_data_as_mail(sieve_tool, default_message);
-	testsuite_message_set_data(testsuite_mail);
+	testsuite_message_new_string(default_message);
 }
 
 void testsuite_message_set_string(const struct sieve_runtime_env *renv,
@@ -140,8 +207,7 @@ void testsuite_message_set_string(const struct sieve_runtime_env *renv,
 {
 	sieve_message_context_reset(renv->msgctx);
 
-	testsuite_mail = sieve_tool_open_data_as_mail(sieve_tool, message);
-	testsuite_message_set_data(testsuite_mail);
+	testsuite_message_new_string(message);
 }
 
 void testsuite_message_set_file(const struct sieve_runtime_env *renv,
@@ -149,8 +215,7 @@ void testsuite_message_set_file(const struct sieve_runtime_env *renv,
 {
 	sieve_message_context_reset(renv->msgctx);
 
-	testsuite_mail = sieve_tool_open_file_as_mail(sieve_tool, file_path);
-	testsuite_message_set_data(testsuite_mail);
+	testsuite_message_new_file(file_path);
 }
 
 void testsuite_message_set_mail(const struct sieve_runtime_env *renv,
@@ -163,6 +228,8 @@ void testsuite_message_set_mail(const struct sieve_runtime_env *renv,
 
 void testsuite_message_deinit(void)
 {
+	testsuite_message_free(TRUE);
+
 	i_free(testsuite_env_mail_from);
 	i_free(testsuite_env_rcpt_to);
 	i_free(testsuite_env_orig_rcpt_to);
diff --git a/src/testsuite/testsuite-message.h b/src/testsuite/testsuite-message.h
index 6c8a40034..2a4d3b47c 100644
--- a/src/testsuite/testsuite-message.h
+++ b/src/testsuite/testsuite-message.h
@@ -12,6 +12,8 @@ extern struct sieve_message_data testsuite_msgdata;
 void testsuite_message_init(void);
 void testsuite_message_deinit(void);
 
+void testsuite_message_flush(void);
+
 void testsuite_message_set_string(const struct sieve_runtime_env *renv,
 				  string_t *message);
 void testsuite_message_set_file(const struct sieve_runtime_env *renv,
diff --git a/src/testsuite/testsuite-result.c b/src/testsuite/testsuite-result.c
index f1259cafa..b4e3a6810 100644
--- a/src/testsuite/testsuite-result.c
+++ b/src/testsuite/testsuite-result.c
@@ -54,6 +54,7 @@ void testsuite_result_reset(const struct sieve_runtime_env *renv)
 		pool_unref(&testsuite_execute_pool);
 	}
 
+	testsuite_message_flush();
 	i_zero(testsuite_execute_env.exec_status);
 
 	testsuite_execute_pool = pool_alloconly_create("sieve execution", 4096);
diff --git a/src/testsuite/testsuite.c b/src/testsuite/testsuite.c
index 9552e7119..4cd4ba722 100644
--- a/src/testsuite/testsuite.c
+++ b/src/testsuite/testsuite.c
@@ -227,9 +227,9 @@ int main(int argc, char **argv)
 		sieve_close(&sbin);
 
 		/* De-initialize message environment */
+		testsuite_result_deinit();
 		testsuite_message_deinit();
 		testsuite_mailstore_deinit();
-		testsuite_result_deinit();
 
 		if (trace_log != NULL)
 			sieve_trace_log_free(&trace_log);
-- 
GitLab