From 07397d2634f5e30da30fa4266952ac00cf98e14d Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan.bosch@open-xchange.com>
Date: Sat, 12 Oct 2024 15:23:23 +0200
Subject: [PATCH] lib-sieve: plugins: variables: Use int for
 sieve_ext_variables_get_extension() status result

---
 src/lib-sieve/plugins/enotify/ext-enotify.c   |  6 +++-
 .../imap4flags/ext-imap4flags-common.c        |  5 +--
 .../imap4flags/ext-imap4flags-common.h        |  8 +++++
 .../plugins/imap4flags/ext-imap4flags.c       | 35 +++++++++++++++++++
 .../plugins/include/ext-include-common.c      |  9 +++--
 src/lib-sieve/plugins/mime/ext-extracttext.c  |  3 +-
 .../plugins/variables/sieve-ext-variables.h   | 13 +++----
 .../environment/ext-vnd-environment.c         |  5 ++-
 .../sieve-extprograms-common.c                | 12 ++++---
 src/testsuite/testsuite-variables.c           |  7 ++--
 10 files changed, 81 insertions(+), 22 deletions(-)

diff --git a/src/lib-sieve/plugins/enotify/ext-enotify.c b/src/lib-sieve/plugins/enotify/ext-enotify.c
index 1926158b5..47f95d2fb 100644
--- a/src/lib-sieve/plugins/enotify/ext-enotify.c
+++ b/src/lib-sieve/plugins/enotify/ext-enotify.c
@@ -57,6 +57,7 @@ const struct sieve_extension_def enotify_extension = {
 
 static bool ext_enotify_load(const struct sieve_extension *ext, void **context)
 {
+	const struct sieve_extension *var_ext;
 	struct ext_enotify_context *extctx;
 
 	if (*context != NULL) {
@@ -64,8 +65,11 @@ static bool ext_enotify_load(const struct sieve_extension *ext, void **context)
 		*context = NULL;
 	}
 
+	if (sieve_ext_variables_get_extension(ext->svinst, &var_ext) < 0)
+		return FALSE;
+
 	extctx = i_new(struct ext_enotify_context, 1);
-	extctx->var_ext = sieve_ext_variables_get_extension(ext->svinst);
+	extctx->var_ext = var_ext;
 	*context = extctx;
 
 	ext_enotify_methods_init(ext->svinst, extctx);
diff --git a/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c b/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c
index 712b7a185..98caf9c8a 100644
--- a/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c
+++ b/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c
@@ -36,9 +36,11 @@ extern const struct sieve_argument_def tag_flags_implicit;
 bool ext_imap4flags_command_validate(struct sieve_validator *valdtr,
 				     struct sieve_command *cmd)
 {
+	const struct sieve_extension *ext = cmd->ext;
+	struct ext_imap4flags_context *extctx = ext->context;
+	const struct sieve_extension *var_ext = extctx->var_ext;
 	struct sieve_ast_argument *arg = cmd->first_positional;
 	struct sieve_ast_argument *arg2;
-	const struct sieve_extension *var_ext;
 
 	/* Check arguments */
 
@@ -95,7 +97,6 @@ bool ext_imap4flags_command_validate(struct sieve_validator *valdtr,
 
 		/* Then, check whether the second argument is permitted */
 
-		var_ext = sieve_ext_variables_get_extension(cmd->ext->svinst);
 		if (var_ext == NULL ||
 		    !sieve_ext_variables_is_active(var_ext, valdtr)) {
 			sieve_argument_validate_error(
diff --git a/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.h b/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.h
index 3883f44c8..c1de6c852 100644
--- a/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.h
+++ b/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.h
@@ -8,6 +8,14 @@
 
 #include "sieve-ext-imap4flags.h"
 
+/*
+ * Extension
+ */
+
+struct ext_imap4flags_context {
+	const struct sieve_extension *var_ext;
+};
+
 /*
  * Side effect
  */
diff --git a/src/lib-sieve/plugins/imap4flags/ext-imap4flags.c b/src/lib-sieve/plugins/imap4flags/ext-imap4flags.c
index 23230c110..4582943a6 100644
--- a/src/lib-sieve/plugins/imap4flags/ext-imap4flags.c
+++ b/src/lib-sieve/plugins/imap4flags/ext-imap4flags.c
@@ -42,6 +42,10 @@ const struct sieve_operation_def *imap4flags_operations[] = {
  * Extension
  */
 
+static bool
+ext_imap4flags_load(const struct sieve_extension *ext, void **context);
+static void ext_imap4flags_unload(const struct sieve_extension *ext);
+
 static bool ext_imap4flags_validator_load
 	(const struct sieve_extension *ext, struct sieve_validator *valdtr);
 static bool ext_imap4flags_interpreter_load
@@ -51,12 +55,43 @@ static bool ext_imap4flags_interpreter_load
 const struct sieve_extension_def imap4flags_extension = {
 	.name = "imap4flags",
 	.version = 1,
+	.load = ext_imap4flags_load,
+	.unload = ext_imap4flags_unload,
 	.validator_load = ext_imap4flags_validator_load,
 	.interpreter_load = ext_imap4flags_interpreter_load,
 	SIEVE_EXT_DEFINE_OPERATIONS(imap4flags_operations),
 	SIEVE_EXT_DEFINE_OPERAND(flags_side_effect_operand)
 };
 
+static bool
+ext_imap4flags_load(const struct sieve_extension *ext, void **context)
+{
+	struct sieve_instance *svinst = ext->svinst;
+	const struct sieve_extension *var_ext;
+	struct ext_imap4flags_context *extctx;
+
+	if (*context != NULL) {
+		ext_imap4flags_unload(ext);
+		*context = NULL;
+	}
+
+	if (sieve_ext_variables_get_extension(svinst, &var_ext) < 0)
+		return FALSE;
+
+	extctx = i_new(struct ext_imap4flags_context, 1);
+	extctx->var_ext = var_ext;
+
+	*context = extctx;
+	return TRUE;
+}
+
+static void ext_imap4flags_unload(const struct sieve_extension *ext)
+{
+	struct ext_imap4flags_context *extctx = ext->context;
+
+	i_free(extctx);
+}
+
 static bool ext_imap4flags_validator_load
 (const struct sieve_extension *ext, struct sieve_validator *valdtr)
 {
diff --git a/src/lib-sieve/plugins/include/ext-include-common.c b/src/lib-sieve/plugins/include/ext-include-common.c
index a26c6a744..db20e2681 100644
--- a/src/lib-sieve/plugins/include/ext-include-common.c
+++ b/src/lib-sieve/plugins/include/ext-include-common.c
@@ -76,6 +76,7 @@ struct ext_include_interpreter_context {
 bool ext_include_load(const struct sieve_extension *ext, void **context)
 {
 	struct sieve_instance *svinst = ext->svinst;
+	const struct sieve_extension *var_ext;
 	struct ext_include_context *extctx;
 	const char *location;
 	unsigned long long int uint_setting;
@@ -85,7 +86,12 @@ bool ext_include_load(const struct sieve_extension *ext, void **context)
 		*context = NULL;
 	}
 
+	/* Extension dependencies */
+	if (sieve_ext_variables_get_extension(ext->svinst, &var_ext) < 0)
+		return FALSE;
+
 	extctx = i_new(struct ext_include_context, 1);
+	extctx->var_ext = var_ext;
 
 	/* Get location for :global scripts */
 	location = sieve_setting_get(svinst, "sieve_global");
@@ -109,9 +115,6 @@ bool ext_include_load(const struct sieve_extension *ext, void **context)
 		svinst, "sieve_include_max_includes", &uint_setting))
 		extctx->max_includes = (unsigned int)uint_setting;
 
-	/* Extension dependencies */
-	extctx->var_ext = sieve_ext_variables_get_extension(ext->svinst);
-
 	*context = extctx;
 	return TRUE;
 }
diff --git a/src/lib-sieve/plugins/mime/ext-extracttext.c b/src/lib-sieve/plugins/mime/ext-extracttext.c
index 4fe0aaa1a..1c059c9ee 100644
--- a/src/lib-sieve/plugins/mime/ext-extracttext.c
+++ b/src/lib-sieve/plugins/mime/ext-extracttext.c
@@ -59,7 +59,8 @@ ext_extracttext_load(const struct sieve_extension *ext, void **context)
 		*context = NULL;
 	}
 
-	var_ext = sieve_ext_variables_get_extension(ext->svinst);
+	if (sieve_ext_variables_get_extension(ext->svinst, &var_ext) < 0)
+		return FALSE;
 	if (sieve_extension_register(svinst, &foreverypart_extension, FALSE,
 				     &fep_ext) < 0)
 		return FALSE;
diff --git a/src/lib-sieve/plugins/variables/sieve-ext-variables.h b/src/lib-sieve/plugins/variables/sieve-ext-variables.h
index 1392a8ffb..4f9fa1df3 100644
--- a/src/lib-sieve/plugins/variables/sieve-ext-variables.h
+++ b/src/lib-sieve/plugins/variables/sieve-ext-variables.h
@@ -28,15 +28,12 @@ size_t sieve_variables_get_max_variable_size(
 
 extern const struct sieve_extension_def variables_extension;
 
-static inline const struct sieve_extension *
-sieve_ext_variables_get_extension(struct sieve_instance *svinst)
+static inline int
+sieve_ext_variables_get_extension(struct sieve_instance *svinst,
+				  const struct sieve_extension **ext_r)
 {
-	const struct sieve_extension *ext;
-
-	if (sieve_extension_register(svinst, &variables_extension, FALSE,
-				     &ext) < 0)
-		return NULL;
-	return ext;
+	return sieve_extension_register(svinst, &variables_extension, FALSE,
+					ext_r);
 }
 
 /*
diff --git a/src/lib-sieve/plugins/vnd.dovecot/environment/ext-vnd-environment.c b/src/lib-sieve/plugins/vnd.dovecot/environment/ext-vnd-environment.c
index 76794c196..8be2944d1 100644
--- a/src/lib-sieve/plugins/vnd.dovecot/environment/ext-vnd-environment.c
+++ b/src/lib-sieve/plugins/vnd.dovecot/environment/ext-vnd-environment.c
@@ -60,6 +60,7 @@ static bool
 ext_vnd_environment_load(const struct sieve_extension *ext, void **context)
 {
 	const struct sieve_extension *ext_env;
+	const struct sieve_extension *ext_var;
 	struct ext_vnd_environment_context *extctx;
 
 	if (*context != NULL) {
@@ -69,10 +70,12 @@ ext_vnd_environment_load(const struct sieve_extension *ext, void **context)
 
 	if (sieve_ext_environment_require_extension(ext->svinst, &ext_env) < 0)
 		return FALSE;
+	if (sieve_ext_variables_get_extension(ext->svinst, &ext_var) < 0)
+		return FALSE;
 
 	extctx = i_new(struct ext_vnd_environment_context, 1);
 	extctx->env_ext = ext_env;
-	extctx->var_ext = sieve_ext_variables_get_extension(ext->svinst);
+	extctx->var_ext = ext_var;
 
 	*context = extctx;
 	return TRUE;
diff --git a/src/plugins/sieve-extprograms/sieve-extprograms-common.c b/src/plugins/sieve-extprograms/sieve-extprograms-common.c
index 922ecff8b..b797383c3 100644
--- a/src/plugins/sieve-extprograms/sieve-extprograms-common.c
+++ b/src/plugins/sieve-extprograms/sieve-extprograms-common.c
@@ -60,6 +60,7 @@ bool sieve_extprograms_ext_load(const struct sieve_extension *ext,
 				void **context)
 {
 	struct sieve_instance *svinst = ext->svinst;
+	const struct sieve_extension *var_ext = NULL;
 	struct sieve_extprograms_ext_context *extctx;
 	const char *extname = sieve_extension_name(ext);
 	const char *bin_dir, *socket_dir, *input_eol;
@@ -81,9 +82,16 @@ bool sieve_extprograms_ext_load(const struct sieve_extension *ext,
 	input_eol = sieve_setting_get(
 		svinst, t_strdup_printf("sieve_%s_input_eol", extname));
 
+	if (sieve_extension_is(ext, sieve_ext_vnd_execute)) {
+		if (sieve_ext_variables_get_extension(ext->svinst,
+						      &var_ext) < 0)
+			return FALSE;
+	}
+
 	extctx = i_new(struct sieve_extprograms_ext_context, 1);
 	extctx->execute_timeout =
 		SIEVE_EXTPROGRAMS_DEFAULT_EXEC_TIMEOUT_SECS;
+	extctx->var_ext = var_ext;
 
 	if (bin_dir == NULL && socket_dir == NULL) {
 		e_debug(svinst->event, "%s extension: "
@@ -109,10 +117,6 @@ bool sieve_extprograms_ext_load(const struct sieve_extension *ext,
 		extctx->copy_ext =
 			sieve_ext_copy_get_extension(ext->svinst);
 	}
-	if (sieve_extension_is(ext, sieve_ext_vnd_execute)) {
-		extctx->var_ext =
-			sieve_ext_variables_get_extension(ext->svinst);
-	}
 
 	*context = extctx;
 	return TRUE;
diff --git a/src/testsuite/testsuite-variables.c b/src/testsuite/testsuite-variables.c
index eb6ed6a14..0181f0b25 100644
--- a/src/testsuite/testsuite-variables.c
+++ b/src/testsuite/testsuite-variables.c
@@ -179,8 +179,11 @@ const struct sieve_operand_def testsuite_namespace_operand = {
 void testsuite_variables_init(const struct sieve_extension *this_ext,
 			      struct sieve_validator *valdtr)
 {
-	testsuite_ext_variables =
-		sieve_ext_variables_get_extension(this_ext->svinst);
+	int ret;
+
+	ret = sieve_ext_variables_get_extension(this_ext->svinst,
+						&testsuite_ext_variables);
+	i_assert(ret == 0);
 
 	sieve_variables_namespace_register(testsuite_ext_variables, valdtr,
 					   this_ext, &testsuite_namespace);
-- 
GitLab