From 9d2fa4de9400b1daab263cc5712432e3cc66bb4f Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan.bosch@open-xchange.com>
Date: Fri, 4 Dec 2020 03:08:12 +0100
Subject: [PATCH] plugins: imap-filter-sieve: Add support for fatal script
 execute errors.

---
 .../imap-filter-sieve/imap-filter-sieve.c     | 21 +++++++++++++------
 .../imap-filter-sieve/imap-filter-sieve.h     |  3 ++-
 src/plugins/imap-filter-sieve/imap-filter.c   | 11 ++++------
 3 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/src/plugins/imap-filter-sieve/imap-filter-sieve.c b/src/plugins/imap-filter-sieve/imap-filter-sieve.c
index 3b51bcfc2..e84a889dd 100644
--- a/src/plugins/imap-filter-sieve/imap-filter-sieve.c
+++ b/src/plugins/imap-filter-sieve/imap-filter-sieve.c
@@ -680,7 +680,8 @@ imap_filter_sieve_result_amend_log_message(const struct sieve_script_env *senv,
 static int
 imap_sieve_filter_handle_exec_status(struct imap_filter_sieve_context *sctx,
 				     struct sieve_script *script, int status,
-				     struct sieve_exec_status *estatus)
+				     struct sieve_exec_status *estatus,
+				     bool *fatal_r)
 {
 	struct imap_filter_sieve_user *ifsuser =
 		IMAP_FILTER_SIEVE_USER_CONTEXT_REQUIRE(sctx->user);
@@ -689,6 +690,8 @@ imap_sieve_filter_handle_exec_status(struct imap_filter_sieve_context *sctx,
 	enum mail_error mail_error = MAIL_ERROR_NONE;
 	int ret = -1;
 
+	*fatal_r = FALSE;
+
 	log_level = user_log_level = LOG_TYPE_ERROR;
 
 	if (estatus->last_storage != NULL && estatus->store_failed) {
@@ -742,7 +745,8 @@ static int
 imap_sieve_filter_run_scripts(struct imap_filter_sieve_context *sctx,
 			      struct sieve_error_handler *user_ehandler,
 			      const struct sieve_message_data *msgdata,
-			      const struct sieve_script_env *scriptenv)
+			      const struct sieve_script_env *scriptenv,
+			      bool *fatal_r)
 {
 	struct mail_user *user = sctx->user;
 	struct imap_filter_sieve_user *ifsuser =
@@ -760,6 +764,8 @@ imap_sieve_filter_run_scripts(struct imap_filter_sieve_context *sctx,
 	unsigned int i;
 	int ret;
 
+	*fatal_r = FALSE;
+
 	/* Start execution */
 	mscript = sieve_multiscript_start_execute(svinst, msgdata, scriptenv);
 
@@ -852,8 +858,9 @@ imap_sieve_filter_run_scripts(struct imap_filter_sieve_context *sctx,
 	}
 
 	i_assert(last_script != NULL); /* at least one script is executed */
-	return imap_sieve_filter_handle_exec_status(sctx,
-		last_script, ret, scriptenv->exec_status);
+	return imap_sieve_filter_handle_exec_status(sctx, last_script, ret,
+						    scriptenv->exec_status,
+						    fatal_r);
 }
 
 static int
@@ -964,7 +971,8 @@ imap_sieve_filter_get_msgdata(struct imap_filter_sieve_context *sctx,
 
 int imap_sieve_filter_run_mail(struct imap_filter_sieve_context *sctx,
 			       struct mail *mail, string_t **errors_r,
-			       bool *have_warnings_r, bool *have_changes_r)
+			       bool *have_warnings_r, bool *have_changes_r,
+			       bool *fatal_r)
 {
 	struct sieve_error_handler *user_ehandler;
 	struct sieve_message_data msgdata;
@@ -1014,7 +1022,8 @@ int imap_sieve_filter_run_mail(struct imap_filter_sieve_context *sctx,
 		/* Execute script(s) */
 
 		ret = imap_sieve_filter_run_scripts(sctx, user_ehandler,
-						    &msgdata, scriptenv);
+						    &msgdata, scriptenv,
+						    fatal_r);
 	} T_END;
 
 	if (ret < 0 && str_len(sctx->errors) == 0) {
diff --git a/src/plugins/imap-filter-sieve/imap-filter-sieve.h b/src/plugins/imap-filter-sieve/imap-filter-sieve.h
index 169b6335b..c06cbdb9a 100644
--- a/src/plugins/imap-filter-sieve/imap-filter-sieve.h
+++ b/src/plugins/imap-filter-sieve/imap-filter-sieve.h
@@ -82,7 +82,8 @@ int imap_filter_sieve_open_global(struct imap_filter_sieve_context *sctx,
 int imap_sieve_filter_run_init(struct imap_filter_sieve_context *sctx);
 int imap_sieve_filter_run_mail(struct imap_filter_sieve_context *sctx,
 			       struct mail *mail, string_t **errors_r,
-			       bool *have_warnings_r, bool *have_changes_r);
+			       bool *have_warnings_r, bool *have_changes_r,
+			       bool *fatal_r);
 
 /*
  *
diff --git a/src/plugins/imap-filter-sieve/imap-filter.c b/src/plugins/imap-filter-sieve/imap-filter.c
index 2255839d6..fd7d758a0 100644
--- a/src/plugins/imap-filter-sieve/imap-filter.c
+++ b/src/plugins/imap-filter-sieve/imap-filter.c
@@ -37,15 +37,12 @@ imap_filter_mail(struct client_command_context *cmd, struct mail *mail)
 	struct imap_filter_context *ctx = cmd->context;
 	struct client *client = cmd->client;
 	string_t *errors = NULL;
-	bool have_warnings = FALSE;
-	bool have_changes = FALSE;
+	bool have_warnings = FALSE, have_changes = FALSE, fatal = FALSE;
 	string_t *reply = t_str_new(128);
 	int ret;
 
-	// FIXME: return fatal error status when no mail filter activity will
-	// work (e.g. when binary is corrupt)
-	ret = imap_sieve_filter_run_mail(ctx->sieve, mail,
-					 &errors, &have_warnings, &have_changes);
+	ret = imap_sieve_filter_run_mail(ctx->sieve, mail, &errors,
+					 &have_warnings, &have_changes, &fatal);
 
 	str_printfa(reply, "* %u FILTERED (TAG %s) UID %u ",
 		    mail->seq, cmd->tag, mail->uid);
@@ -73,7 +70,7 @@ imap_filter_mail(struct client_command_context *cmd, struct mail *mail)
 		}
 	}
 
-	return TRUE;
+	return !fatal;
 }
 
 static bool imap_filter_more(struct client_command_context *cmd)
-- 
GitLab