From 556da05080a9e3faf8330d02cad94b6cf7a38f32 Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan@rename-it.nl>
Date: Sat, 16 Aug 2008 12:29:06 +0200
Subject: [PATCH] Regex: fixed a few minor bugs.

---
 Makefile.am                                   |  1 +
 .../rfc}/draft-murchison-sieve-regex-07.txt   |  0
 src/lib-sieve/plugins/regex/mcht-regex.c      | 43 +++++++++--------
 src/lib-sieve/plugins/regex/regex.sieve       | 11 -----
 src/lib-sieve/sieve-match-types.c             |  2 +-
 tests/extensions/variables/regex.svtest       | 35 ++++++++++++++
 tests/match-types/regex.svtest                | 46 +++++++------------
 7 files changed, 76 insertions(+), 62 deletions(-)
 rename {src/lib-sieve/plugins/regex => doc/rfc}/draft-murchison-sieve-regex-07.txt (100%)
 delete mode 100644 src/lib-sieve/plugins/regex/regex.sieve
 create mode 100644 tests/extensions/variables/regex.svtest

diff --git a/Makefile.am b/Makefile.am
index c9b9a54b1..6d9e511fa 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -37,6 +37,7 @@ test_cases = \
 	tests/extensions/variables/quoting.svtest \
 	tests/extensions/variables/string.svtest \
 	tests/extensions/variables/errors.svtest \
+	tests/extensions/variables/regex.svtest \
 	tests/extensions/include/variables.svtest \
 	tests/extensions/include/errors.svtest \
 	tests/extensions/imapflags/basic.svtest \
diff --git a/src/lib-sieve/plugins/regex/draft-murchison-sieve-regex-07.txt b/doc/rfc/draft-murchison-sieve-regex-07.txt
similarity index 100%
rename from src/lib-sieve/plugins/regex/draft-murchison-sieve-regex-07.txt
rename to doc/rfc/draft-murchison-sieve-regex-07.txt
diff --git a/src/lib-sieve/plugins/regex/mcht-regex.c b/src/lib-sieve/plugins/regex/mcht-regex.c
index fa0501836..d69539d4b 100644
--- a/src/lib-sieve/plugins/regex/mcht-regex.c
+++ b/src/lib-sieve/plugins/regex/mcht-regex.c
@@ -164,7 +164,6 @@ struct mcht_regex_context {
 	int value_index;
 	regmatch_t *pmatch;
 	size_t nmatch;
-	bool with_match_values;
 };
 
 static void mcht_regex_match_init
@@ -176,8 +175,7 @@ static void mcht_regex_match_init
 	t_array_init(&ctx->reg_expressions, 4);
 
 	ctx->value_index = -1;
-	ctx->with_match_values = sieve_match_values_are_enabled(mctx->interp);
-	if ( ctx->with_match_values ) {
+	if ( sieve_match_values_are_enabled(mctx->interp) ) {
 		ctx->pmatch = t_new(regmatch_t, MCHT_REGEX_MAX_SUBSTITUTIONS);
 		ctx->nmatch = MCHT_REGEX_MAX_SUBSTITUTIONS;
 	} else {
@@ -208,7 +206,7 @@ static regex_t *mcht_regex_get
 		else
 			return NULL;
 			
-		if ( !ctx->with_match_values ) cflags |= REG_NOSUB;
+		if ( ctx->nmatch == 0 ) cflags |= REG_NOSUB;
 
 		if ( (ret=regcomp(regexp, key, cflags)) != 0 ) {
 			/* FIXME: Do something useful, i.e. report error somewhere */
@@ -245,28 +243,33 @@ static int mcht_regex_match
 		return FALSE;
 
 	if ( regexec(regexp, val, ctx->nmatch, ctx->pmatch, 0) == 0 ) {
-		size_t i;
-		int skipped = 0;
-		string_t *subst = t_str_new(32);
-		struct sieve_match_values *mvalues = sieve_match_values_start(mctx->interp);
 
-		i_assert( mvalues != NULL );
+		if ( ctx->nmatch > 0 ) {
+			size_t i;
+			int skipped = 0;
+			string_t *subst = t_str_new(32);
 
-		for ( i = 0; i < ctx->nmatch; i++ ) {
-			str_truncate(subst, 0);
+			struct sieve_match_values *mvalues = sieve_match_values_start(mctx->interp);
+
+			i_assert( mvalues != NULL );
+
+			for ( i = 0; i < ctx->nmatch; i++ ) {
+				str_truncate(subst, 0);
 			
-			if ( ctx->pmatch[i].rm_so != -1 ) {
-				if ( skipped > 0 )
-					sieve_match_values_skip(mvalues, skipped);
+				if ( ctx->pmatch[i].rm_so != -1 ) {
+					if ( skipped > 0 )
+						sieve_match_values_skip(mvalues, skipped);
 					
-				str_append_n(subst, val + ctx->pmatch[i].rm_so, 
-					ctx->pmatch[i].rm_eo - ctx->pmatch[i].rm_so);
-				sieve_match_values_add(mvalues, subst);
-			} else 
-				skipped++;
+					str_append_n(subst, val + ctx->pmatch[i].rm_so, 
+						ctx->pmatch[i].rm_eo - ctx->pmatch[i].rm_so);
+					sieve_match_values_add(mvalues, subst);
+				} else 
+					skipped++;
+			}
+
+			sieve_match_values_commit(mctx->interp, &mvalues);
 		}
 
-		sieve_match_values_commit(mctx->interp, &mvalues);
 		return TRUE;
 	}
 	
diff --git a/src/lib-sieve/plugins/regex/regex.sieve b/src/lib-sieve/plugins/regex/regex.sieve
deleted file mode 100644
index 7380e4618..000000000
--- a/src/lib-sieve/plugins/regex/regex.sieve
+++ /dev/null
@@ -1,11 +0,0 @@
-require "regex";
-
-if address :regex :comparator "i;ascii-casemap" "from" [
-	"stephan(\\+.*)?@rename-it\\.com", 
-	"stephan(\\+.*)?@drunksnipers\\.com" 
-	] {
-	keep;
-	stop;
-}
-
-discard;
diff --git a/src/lib-sieve/sieve-match-types.c b/src/lib-sieve/sieve-match-types.c
index 66c29f0c6..1153a4901 100644
--- a/src/lib-sieve/sieve-match-types.c
+++ b/src/lib-sieve/sieve-match-types.c
@@ -181,7 +181,7 @@ bool sieve_match_values_are_enabled
 {
 	struct mtch_interpreter_context *ctx = get_interpreter_context(interp);
 		
-	return ctx->match_values_enabled;
+	return ( ctx == NULL ? FALSE : ctx->match_values_enabled );
 }
 
 struct sieve_match_values *sieve_match_values_start
diff --git a/tests/extensions/variables/regex.svtest b/tests/extensions/variables/regex.svtest
new file mode 100644
index 000000000..8e814b51a
--- /dev/null
+++ b/tests/extensions/variables/regex.svtest
@@ -0,0 +1,35 @@
+require "vnd.dovecot.testsuite";
+
+require "regex";
+require "variables";
+
+# Test overwriting only on match 
+test "RFC - values overwrite" {
+	set "sentence1" "the cat jumps off the table";
+	set "sentence2" "the dog barks at the cat in the alley";
+
+	if not string :regex "${sentence1}" "the (.*) jumps off the (.*)" {
+		test_fail "failed to match first sentence";
+	} 
+	
+	if not string :is "${1}:${2}" "cat:table" {
+		test_fail "invalid match values";
+	}
+
+	if string :regex "${sentence2}" "the (.*) barks at the (.*) in the store" {
+		test_fail "should not have matched second sentence";
+	}
+
+	if not string :is "${1}:${2}" "cat:table" {
+		test_fail "should have preserved match values";
+	}
+
+	if not string :regex "${sentence2}" "the (.*) barks at the (.*) in the alley" {
+		test_fail "failed to match the second sentence (second time)";
+	}
+
+	if not string :is "${1}:${2}" "dog:cat" {
+		test_fail "should have overwritten match values";
+	}
+}
+
diff --git a/tests/match-types/regex.svtest b/tests/match-types/regex.svtest
index 8e814b51a..9286a12fc 100644
--- a/tests/match-types/regex.svtest
+++ b/tests/match-types/regex.svtest
@@ -1,35 +1,21 @@
 require "vnd.dovecot.testsuite";
 
 require "regex";
-require "variables";
 
-# Test overwriting only on match 
-test "RFC - values overwrite" {
-	set "sentence1" "the cat jumps off the table";
-	set "sentence2" "the dog barks at the cat in the alley";
-
-	if not string :regex "${sentence1}" "the (.*) jumps off the (.*)" {
-		test_fail "failed to match first sentence";
-	} 
-	
-	if not string :is "${1}:${2}" "cat:table" {
-		test_fail "invalid match values";
-	}
-
-	if string :regex "${sentence2}" "the (.*) barks at the (.*) in the store" {
-		test_fail "should not have matched second sentence";
-	}
-
-	if not string :is "${1}:${2}" "cat:table" {
-		test_fail "should have preserved match values";
+test_set "message" text:
+From: stephan+sieve@drunksnipers.com
+To: tss@iki.fi
+Subject: Test
+
+Test message.
+.
+;
+
+test "Basic example" {
+	if not address :regex :comparator "i;ascii-casemap" "from" [
+		"stephan(\\+.*)?@rename-it\\.com", 
+		"stephan(\\+.*)?@drunksnipers\\.com" 
+		] {
+		test_fail "failed to match";
 	}
-
-	if not string :regex "${sentence2}" "the (.*) barks at the (.*) in the alley" {
-		test_fail "failed to match the second sentence (second time)";
-	}
-
-	if not string :is "${1}:${2}" "dog:cat" {
-		test_fail "should have overwritten match values";
-	}
-}
-
+}	
-- 
GitLab