From 16362ac8fbe4b2a62018f93991dd51e98c03997d Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan@rename-it.nl>
Date: Sat, 16 Jan 2016 00:07:05 +0100
Subject: [PATCH] lib-sieve: multiscript: Fixed bug in handling of (implicit)
 keep; final keep action was executed as though there was a failure. Among
 other things, this caused the keep action to revert back to the initial
 message, causing editheader actions to be ignored.

---
 Makefile.am                                   |  1 +
 src/lib-sieve/sieve-result.c                  |  4 +-
 src/lib-sieve/sieve-result.h                  |  5 ++-
 src/lib-sieve/sieve.c                         |  9 ++--
 tests/extensions/editheader/execute.svtest    | 45 +++++++++++++++++++
 .../execute/multiscript-after.sieve           |  4 ++
 .../execute/multiscript-before.sieve          |  4 ++
 .../execute/multiscript-personal.sieve        |  4 ++
 8 files changed, 68 insertions(+), 8 deletions(-)
 create mode 100644 tests/extensions/editheader/execute.svtest
 create mode 100644 tests/extensions/editheader/execute/multiscript-after.sieve
 create mode 100644 tests/extensions/editheader/execute/multiscript-before.sieve
 create mode 100644 tests/extensions/editheader/execute/multiscript-personal.sieve

diff --git a/Makefile.am b/Makefile.am
index a20839e4e..dc3cc95f6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -160,6 +160,7 @@ test_cases = \
 	tests/extensions/editheader/utf8.svtest \
 	tests/extensions/editheader/protected.svtest \
 	tests/extensions/editheader/errors.svtest \
+	tests/extensions/editheader/execute.svtest \
 	tests/extensions/duplicate/errors.svtest \
 	tests/extensions/duplicate/execute.svtest \
 	tests/extensions/duplicate/execute-vnd.svtest \
diff --git a/src/lib-sieve/sieve-result.c b/src/lib-sieve/sieve-result.c
index e075a7364..7a95cd28b 100644
--- a/src/lib-sieve/sieve-result.c
+++ b/src/lib-sieve/sieve-result.c
@@ -1031,13 +1031,13 @@ static int _sieve_result_implicit_keep
 
 int sieve_result_implicit_keep
 (struct sieve_result *result,
-	struct sieve_error_handler *ehandler)
+	struct sieve_error_handler *ehandler, bool success)
 {
 	int ret;
 
 	_sieve_result_prepare_execution(result, ehandler);
 
-	ret = _sieve_result_implicit_keep(result, TRUE);
+	ret = _sieve_result_implicit_keep(result, !success);
 
 	result->action_env.ehandler = NULL;
 
diff --git a/src/lib-sieve/sieve-result.h b/src/lib-sieve/sieve-result.h
index ae63bc537..e2c2f5f3d 100644
--- a/src/lib-sieve/sieve-result.h
+++ b/src/lib-sieve/sieve-result.h
@@ -142,8 +142,9 @@ void sieve_result_set_failure_action
  * Result execution
  */
 
-int sieve_result_implicit_keep(struct sieve_result *result,
-	struct sieve_error_handler *ehandler);
+int sieve_result_implicit_keep
+	(struct sieve_result *result,
+		struct sieve_error_handler *ehandler, bool success);
 
 void sieve_result_mark_executed(struct sieve_result *result);
 
diff --git a/src/lib-sieve/sieve.c b/src/lib-sieve/sieve.c
index 412047a65..5d28fd354 100644
--- a/src/lib-sieve/sieve.c
+++ b/src/lib-sieve/sieve.c
@@ -560,7 +560,7 @@ int sieve_execute
 	} else if ( ret == SIEVE_EXEC_FAILURE ) {
 		/* Perform implicit keep if script failed with a normal runtime error */
 		switch ( sieve_result_implicit_keep
-			(result, action_ehandler) ) {
+			(result, action_ehandler, FALSE) ) {
 		case SIEVE_EXEC_OK:
 			if ( keep != NULL ) *keep = TRUE;
 			break;
@@ -653,7 +653,8 @@ static void sieve_multiscript_execute
 	if ( mscript->status > 0 ) {
 		mscript->status = sieve_result_execute(mscript->result, keep, ehandler);
 	} else {
-		if ( !sieve_result_implicit_keep(mscript->result, ehandler) )
+		if ( !sieve_result_implicit_keep
+			(mscript->result, ehandler, FALSE) )
 			mscript->status = SIEVE_EXEC_KEEP_FAILED;
 		else
 			if ( keep != NULL ) *keep = TRUE;
@@ -714,7 +715,7 @@ int sieve_multiscript_tempfail(struct sieve_multiscript **_mscript,
 			 * to implicit keep (FIXME)
 			 */
 			switch ( sieve_result_implicit_keep
-				(result, action_ehandler) ) {
+				(result, action_ehandler, FALSE) ) {
 			case SIEVE_EXEC_OK:
 				ret = SIEVE_EXEC_FAILURE;
 				break;
@@ -746,7 +747,7 @@ int sieve_multiscript_finish(struct sieve_multiscript **_mscript,
 			mscript->keep = TRUE;
 		} else {
 			switch ( sieve_result_implicit_keep
-				(result, action_ehandler) ) {
+				(result, action_ehandler, TRUE) ) {
 			case SIEVE_EXEC_OK:
 				mscript->keep = TRUE;
 				break;
diff --git a/tests/extensions/editheader/execute.svtest b/tests/extensions/editheader/execute.svtest
new file mode 100644
index 000000000..ca33548e4
--- /dev/null
+++ b/tests/extensions/editheader/execute.svtest
@@ -0,0 +1,45 @@
+require "vnd.dovecot.testsuite";
+require "include";
+require "variables";
+
+/*
+ * Multi script
+ */
+
+test_set "message" text:
+From: idiot@example.com
+To: idiot@example.org
+Subject: Frop!
+
+Frop.
+.
+;
+
+test_result_reset;
+test "Multi script" {
+	if not test_multiscript [
+		"execute/multiscript-before.sieve",
+		"execute/multiscript-personal.sieve",
+		"execute/multiscript-after.sieve"
+	] {
+		test_fail "failed to run all scripts";
+	}
+
+	test_message :folder "INBOX" 0;
+
+	if not header "subject" "Frop!" {
+		test_fail "keep not executed.";
+	}
+
+	if not header "X-Before" "before" {
+		test_fail "No X-Before header";
+	}
+
+	if not header "X-Personal" "personal" {
+		test_fail "No X-Personal header";
+	}
+
+	if not header "X-After" "after" {
+		test_fail "No X-After header";
+	}	
+}
diff --git a/tests/extensions/editheader/execute/multiscript-after.sieve b/tests/extensions/editheader/execute/multiscript-after.sieve
new file mode 100644
index 000000000..f11f02dba
--- /dev/null
+++ b/tests/extensions/editheader/execute/multiscript-after.sieve
@@ -0,0 +1,4 @@
+require "editheader";
+
+addheader "X-After" "after";
+
diff --git a/tests/extensions/editheader/execute/multiscript-before.sieve b/tests/extensions/editheader/execute/multiscript-before.sieve
new file mode 100644
index 000000000..5c8a988f2
--- /dev/null
+++ b/tests/extensions/editheader/execute/multiscript-before.sieve
@@ -0,0 +1,4 @@
+require "editheader";
+
+addheader "X-Before" "before";
+
diff --git a/tests/extensions/editheader/execute/multiscript-personal.sieve b/tests/extensions/editheader/execute/multiscript-personal.sieve
new file mode 100644
index 000000000..92e82ac44
--- /dev/null
+++ b/tests/extensions/editheader/execute/multiscript-personal.sieve
@@ -0,0 +1,4 @@
+require "editheader";
+
+addheader "X-Personal" "personal";
+
-- 
GitLab