From b29320f29e5849b3df09501e716df4cbea9702f3 Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan@rename-it.nl>
Date: Tue, 29 Jul 2008 22:21:32 +0200
Subject: [PATCH] Variables: fixed very significant bug in the variable scope
 implementation.

---
 .../plugins/variables/ext-variables-common.c  | 12 +--
 tests/extensions/variables/basic.svtest       | 82 ++++++++++++++++++-
 2 files changed, 88 insertions(+), 6 deletions(-)

diff --git a/src/lib-sieve/plugins/variables/ext-variables-common.c b/src/lib-sieve/plugins/variables/ext-variables-common.c
index 1459f07e4..70aef5dd7 100644
--- a/src/lib-sieve/plugins/variables/ext-variables-common.c
+++ b/src/lib-sieve/plugins/variables/ext-variables-common.c
@@ -86,11 +86,11 @@ struct sieve_variable *sieve_variable_scope_declare
 (struct sieve_variable_scope *scope, const char *identifier)
 {
 	struct sieve_variable *new_var = p_new(scope->pool, struct sieve_variable, 1);
-	new_var->identifier = identifier;
+	new_var->identifier = p_strdup(scope->pool, identifier);
 	new_var->index = scope->next_index++;
 	new_var->ext = scope->ext;
-		
-	hash_insert(scope->variables, (void *) identifier, (void *) new_var);
+
+	hash_insert(scope->variables, (void *) new_var->identifier, (void *) new_var);
 	
 	return new_var;
 }
@@ -100,10 +100,12 @@ struct sieve_variable *sieve_variable_scope_get_variable
 {
 	struct sieve_variable *var = 
 		(struct sieve_variable *) hash_lookup(scope->variables, identifier);
+
 	
-	if ( var == NULL && declare )
+	if ( var == NULL && declare ) {
 		var = sieve_variable_scope_declare(scope, identifier);
-	
+	}
+
 	return var;
 }
 
diff --git a/tests/extensions/variables/basic.svtest b/tests/extensions/variables/basic.svtest
index 7dde684fa..fbcf5d4ca 100644
--- a/tests/extensions/variables/basic.svtest
+++ b/tests/extensions/variables/basic.svtest
@@ -10,6 +10,50 @@ Testing variables...
 .
 ;
 
+/*
+ * Substitution syntax
+ */
+
+test "Unknown variables" {
+	set "q" "a";
+	set "qw" "bb";
+	set "qwe" "ccc";
+	set "qwer" "dddd";
+	set "qwert" "ccc";
+
+	if not string "[${qwerty}]" "[]" {
+		test_fail "unknown variable not substituted with empty string";
+	}
+}
+
+test "One pass" {
+	set "something" "value";
+	set "s" "$";
+	
+	if string "${s}{something}" "value" {
+		test_fail "somehow variable string is scanned multiple times";
+	}
+
+	if not string :matches "${s}{something}" "?{something}" {
+		test_fail "unexpected result";
+	}
+}
+
+test "Syntax errors" {
+	set "s" "$";
+	set "variable" "nonsense";
+
+	if anyof ( 
+		not string "$" "${s}",
+		not string "${" "${s}{",
+		not string "${a" "${s}{a",
+		not string "${$}" "${s}{$}",
+		not string "${%%%%}" "${s}{%%%%}" )
+	{
+		test_fail "variables substitution changed substring not matching variable-ref";
+	}	
+}
+
 /*
  * Variable assignments
  */
@@ -60,6 +104,18 @@ test "Two assignments" {
 	}
 }
 
+test "Variables case-insensitive" {
+	set "VeRyElAboRATeVaRIABLeName" "interesting value";
+
+	if not string "${veryelaboratevariablename}" "interesting value" {
+		test_fail "variable names are case sensitive (lower case try)";
+	}
+
+	if not string "${VERYELABORATEVARIABLENAME}" "interesting value" {
+		test_fail "variable names are case sensitive (upper case try)";
+	}
+}
+
 /*
  * Modifiers
  */
@@ -170,6 +226,31 @@ test "Modifier :length :quotewildcard" {
  * Variable substitution
  */
 
+test "Multi-line string substitution" {
+	set "name" "Stephan Bosch";
+	set "address" "stephan@rename-it.nl";
+	set "subject" "Test message";
+	
+	set "message" text: # Message with substitutions
+From: ${name} <${address}>
+To: Bertus van Asseldonk <b.vanasseldonk@hetkennet.nl>
+Subject: ${subject}
+
+This is a test message.
+.
+;
+	if not string :is "${message}" text:
+From: Stephan Bosch <stephan@rename-it.nl>
+To: Bertus van Asseldonk <b.vanasseldonk@hetkennet.nl>
+Subject: Test message
+
+This is a test message.
+.
+	{
+		test_fail "variable substitution failed";
+	}
+}
+
 test "Multiple substitutions" {
 	set "a" "the monkey";
 	set "b" "a nut";
@@ -194,4 +275,3 @@ test "Multiple substitutions" {
 }
 
 
-
-- 
GitLab