From 745eb64dd4bed57cfe3b2634d5f669d485155d83 Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan.bosch@open-xchange.com>
Date: Mon, 28 Mar 2022 23:31:19 +0200
Subject: [PATCH] lib-sieve: plugins: variables: tst-string - Fix default
 comparator to be "i;ascii-casemap".

It was "i;octet" previously, which is not standard.
---
 src/lib-sieve/plugins/variables/tst-string.c |  4 +-
 tests/extensions/encoded-character.svtest    | 16 +++----
 tests/extensions/variables/basic.svtest      |  2 +-
 tests/extensions/variables/modifiers.svtest  | 46 ++++++++++----------
 tests/extensions/variables/string.svtest     | 18 ++++++++
 5 files changed, 52 insertions(+), 34 deletions(-)

diff --git a/src/lib-sieve/plugins/variables/tst-string.c b/src/lib-sieve/plugins/variables/tst-string.c
index 91b0b82f6..3a47c09e3 100644
--- a/src/lib-sieve/plugins/variables/tst-string.c
+++ b/src/lib-sieve/plugins/variables/tst-string.c
@@ -96,7 +96,7 @@ static bool tst_string_validate
 	const struct sieve_match_type mcht_default =
 		SIEVE_MATCH_TYPE_DEFAULT(is_match_type);
 	const struct sieve_comparator cmp_default =
-		SIEVE_COMPARATOR_DEFAULT(i_octet_comparator);
+		SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator);
 
 	if ( !sieve_validate_positional_argument
 		(valdtr, tst, arg, "source", 1, SAAT_STRING_LIST) ) {
@@ -230,7 +230,7 @@ static int tst_string_operation_execute
 	struct sieve_match_type mcht =
 		SIEVE_MATCH_TYPE_DEFAULT(is_match_type);
 	struct sieve_comparator cmp =
-		SIEVE_COMPARATOR_DEFAULT(i_octet_comparator);
+		SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator);
 	struct sieve_stringlist *source, *value_list, *key_list;
 	int match, ret;
 
diff --git a/tests/extensions/encoded-character.svtest b/tests/extensions/encoded-character.svtest
index 150d81251..96ff35179 100644
--- a/tests/extensions/encoded-character.svtest
+++ b/tests/extensions/encoded-character.svtest
@@ -4,11 +4,11 @@ require "encoded-character";
 require "variables";
 
 test "HEX equality one" {
-	if not string "${hex:42}" "B" {
+	if not string :comparator "i;octet" "${hex:42}" "B" {
 		test_fail "failed to match the string 'B'";
 	}
 
-	if string "${hex:42}" "b" {
+	if string :comparator "i;octet" "${hex:42}" "b" {
 		test_fail "matched nonsense";
 	}
 
@@ -18,11 +18,11 @@ test "HEX equality one" {
 }
 
 test "HEX equality one middle" {
-	if not string " ${hex:42} " " B " {
+	if not string :comparator "i;octet" " ${hex:42} " " B " {
 		test_fail "failed to match the string ' B '";
 	}
 
-	if string " ${hex:42} " " b " {
+	if string :comparator "i;octet" " ${hex:42} " " b " {
 		test_fail "matched nonsense";
 	}
 
@@ -32,11 +32,11 @@ test "HEX equality one middle" {
 }
 
 test "HEX equality one begin" {
-	if not string "${hex:42} " "B " {
+	if not string :comparator "i;octet" "${hex:42} " "B " {
 		test_fail "failed to match the string 'B '";
 	}
 
-	if string "${hex:42} " " b" {
+	if string :comparator "i;octet" "${hex:42} " " b" {
 		test_fail "matched nonsense";
 	}
 
@@ -46,11 +46,11 @@ test "HEX equality one begin" {
 }
 
 test "HEX equality one end" {
-	if not string " ${hex:42}" " B" {
+	if not string :comparator "i;octet" " ${hex:42}" " B" {
 		test_fail "failed to match the string ' B'";
 	}
 
-	if string " ${hex:42}" " b " {
+	if string :comparator "i;octet" " ${hex:42}" " b " {
 		test_fail "matched nonsense";
 	}
 
diff --git a/tests/extensions/variables/basic.svtest b/tests/extensions/variables/basic.svtest
index f01aeeb92..eb361852a 100644
--- a/tests/extensions/variables/basic.svtest
+++ b/tests/extensions/variables/basic.svtest
@@ -99,7 +99,7 @@ test "Basic assignment" {
 		test_fail "variable assignment failed";
 	}
 
-	if string :is "${test}" "value" {
+	if string :is :comparator "i;octet" "${test}" "value" {
 		test_fail "string test failed";
 	}
 }
diff --git a/tests/extensions/variables/modifiers.svtest b/tests/extensions/variables/modifiers.svtest
index 37068b63d..57f95e4b3 100644
--- a/tests/extensions/variables/modifiers.svtest
+++ b/tests/extensions/variables/modifiers.svtest
@@ -9,7 +9,7 @@ require "encoded-character";
 test "Modifier :lower" {
 	set :lower "test" "VaLuE";
 
-	if not string :is "${test}" "value" {
+	if not string :comparator "i;octet" :is "${test}" "value" {
 		test_fail "modified variable assignment failed";
 	}
 }
@@ -17,11 +17,11 @@ test "Modifier :lower" {
 test "Modifiers :lower :upperfirst" {
 	set :lower :upperfirst "test" "vAlUe";
 
-	if string :is "${test}" "value" {
+	if string :comparator "i;octet" :is "${test}" "value" {
 		test_fail "modifiers applied with wrong precedence";
 	}
 
-	if not string :is "${test}" "Value" {
+	if not string :comparator "i;octet" :is "${test}" "Value" {
 		test_fail "modified variable assignment failed";
 	}
 }
@@ -29,11 +29,11 @@ test "Modifiers :lower :upperfirst" {
 test "Modifiers :upperfirst :lower" {
 	set :upperfirst :lower "test" "vAlUe";
 
-	if string :is "${test}" "value" {
+	if string :comparator "i;octet" :is "${test}" "value" {
 		test_fail "modifiers applied with wrong precedence";
 	}
 
-	if not string :is "${test}" "Value" {
+	if not string :comparator "i;octet" :is "${test}" "Value" {
 		test_fail "modified variable assignment failed";
 	}
 }
@@ -41,7 +41,7 @@ test "Modifiers :upperfirst :lower" {
 test "Modifier :upper" {
 	set :upper "test" "vAlUe";
 
-	if not string :is "${test}" "VALUE" {
+	if not string :comparator "i;octet" :is "${test}" "VALUE" {
 		test_fail "modified variable assignment failed";
 	}
 }
@@ -49,11 +49,11 @@ test "Modifier :upper" {
 test "Modifiers :upper :lowerfirst" {
 	set :upper :lowerfirst "test" "VaLuE";
 
-	if string :is "${test}" "VALUE" {
+	if string :comparator "i;octet" :is "${test}" "VALUE" {
 		test_fail "modifiers applied with wrong precedence";
 	}
 
-	if not string :is "${test}" "vALUE" {
+	if not string :comparator "i;octet" :is "${test}" "vALUE" {
 		test_fail "modified variable assignment failed";
 	}
 }
@@ -61,11 +61,11 @@ test "Modifiers :upper :lowerfirst" {
 test "Modifiers :lowerfirst :upper" {
 	set :lowerfirst :upper "test" "VaLuE";
 
-	if string :is "${test}" "VALUE" {
+	if string :comparator "i;octet" :is "${test}" "VALUE" {
 		test_fail "modifiers applied with wrong precedence";
 	}
 
-	if not string :is "${test}" "vALUE" {
+	if not string :comparator "i;octet" :is "${test}" "vALUE" {
 		test_fail "modified variable assignment failed";
 	}
 }
@@ -73,7 +73,7 @@ test "Modifiers :lowerfirst :upper" {
 test "Modifier :length (empty)" {
 	set :length "test" "";
 
-	if not string :is "${test}" "0" {
+	if not string :comparator "i;octet" :is "${test}" "0" {
 		test_fail "modified variable assignment failed";
 	}
 }
@@ -81,7 +81,7 @@ test "Modifier :length (empty)" {
 test "Modifier :length (simple)" {
 	set :length "test" "VaLuE";
 
-	if not string :is "${test}" "5" {
+	if not string :comparator "i;octet" :is "${test}" "5" {
 		test_fail "modified variable assignment failed";
 	}
 }
@@ -91,7 +91,7 @@ test "Modifier :length (elaborate)" {
 	set "b" "1234567890";
 	set :length "test" " ${a}:${b}  ";
 
-	if not string :is "${test}" "40" {
+	if not string :comparator "i;octet" :is "${test}" "40" {
 		test_fail "modified variable assignment failed";
 	}
 }
@@ -99,7 +99,7 @@ test "Modifier :length (elaborate)" {
 test "Modifier :quotewildcard" {
 	set :quotewildcard "test" "^^***??**^^";
 
-	if not string :is "${test}" "^^\\*\\*\\*\\?\\?\\*\\*^^" {
+	if not string :comparator "i;octet" :is "${test}" "^^\\*\\*\\*\\?\\?\\*\\*^^" {
 		test_fail "modified variable assignment failed";
 	}
 }
@@ -107,43 +107,43 @@ test "Modifier :quotewildcard" {
 test "Modifier :length :quotewildcard" {
 	set :length :quotewildcard "test" "^^***??**^^";
 
-	if string :is "${test}" "11" {
+	if string :comparator "i;octet" :is "${test}" "11" {
 		test_fail "modifiers applied with wrong precedence";
 	}
 
-	if not string :is "${test}" "18" {
+	if not string :comparator "i;octet" :is "${test}" "18" {
 		test_fail "modified variable assignment failed";
 	}
 }
 
 test "RFC examples" {
 	set "a" "juMBlEd lETteRS";             # => "juMBlEd lETteRS"
-	if not string "${a}" "juMBlEd lETteRS" {
+	if not string :comparator "i;octet" "${a}" "juMBlEd lETteRS" {
 		test_fail "modified assignment failed (1): ${a}";
 	}
 
 	set :length "b" "${a}";                # => "15"
-	if not string "${b}" "15" {
+	if not string :comparator "i;octet" "${b}" "15" {
 		test_fail "modified assignment failed (2): ${a}";
 	}
 
 	set :lower "b" "${a}";                 #  => "jumbled letters"
-	if not string "${b}" "jumbled letters" {
+	if not string :comparator "i;octet" "${b}" "jumbled letters" {
 		test_fail "modified assignment failed (3): ${a}";
 	}
 
     set :upperfirst "b" "${a}";            # => "JuMBlEd lETteRS"
-	if not string "${b}" "JuMBlEd lETteRS" {
+	if not string :comparator "i;octet" "${b}" "JuMBlEd lETteRS" {
 		test_fail "modified assignment failed (4): ${a}";
 	}
 
 	set :upperfirst :lower "b" "${a}";     # => "Jumbled letters"
-	if not string "${b}" "Jumbled letters" {
+	if not string :comparator "i;octet" "${b}" "Jumbled letters" {
 		test_fail "modified assignment failed (5): ${a}";
 	}
 
 	set :quotewildcard "b" "Rock*";        # => "Rock\*"
-	if not string "${b}" "Rock\\*" {
+	if not string :comparator "i;octet" "${b}" "Rock\\*" {
 		test_fail "modified assignment failed (6): ${a}";
 	}
 }
@@ -154,7 +154,7 @@ test "Modifier :length utf8" {
 	set "a" "Das ist ${unicode: 00fc}berhaupt nicht m${unicode: 00f6}glich.";
 
 	set :length "b" "${a}";
-    if not string "${b}" "32" {
+    if not string :comparator "i;octet" "${b}" "32" {
         test_fail "incorrect number of unicode characters reported: ${b}/32";
     }
 }
diff --git a/tests/extensions/variables/string.svtest b/tests/extensions/variables/string.svtest
index d0244e606..5b19b355d 100644
--- a/tests/extensions/variables/string.svtest
+++ b/tests/extensions/variables/string.svtest
@@ -35,3 +35,21 @@ test "No whitespace stripping" {
 		test_fail "string test seems to have stripped white space";
 	}
 }
+
+test "Case sensitivity" {
+	if not string :comparator "i;octet" :is "fropfropfrop" "fropfropfrop" {
+		test_fail "exact match fails";
+	}
+
+	if not string :is "fropfropfrop" "FrOpfropfRoP" {
+		test_fail "string test is case-sensitive by default";
+	}
+
+	if string :comparator "i;octet" :is "frop" "FrOp" {
+		test_fail "string test is not using comparator definition";
+	}
+
+	if not string :is :comparator "i;ascii-casemap" "frop" "FrOp" {
+		test_fail "string test is case-sensitive even with i;ascii-casemap";
+	}
+}
-- 
GitLab