From 548ad6690c117a90377f292ba7913e65cadec00a Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Fri, 1 Aug 2008 20:40:36 +0200 Subject: [PATCH] Variables: fixed :count issue for the string test. --- Makefile.am | 1 + TODO | 1 - src/lib-sieve/mcht-contains.c | 3 ++ src/lib-sieve/mcht-is.c | 9 ++++-- src/lib-sieve/mcht-matches.c | 32 +++++++++++-------- src/lib-sieve/plugins/regex/mcht-regex.c | 5 +++ src/lib-sieve/plugins/relational/mcht-count.c | 3 ++ src/lib-sieve/plugins/relational/mcht-value.c | 9 +++++- src/lib-sieve/plugins/variables/tst-string.c | 3 +- src/lib-sieve/sieve-match-types.h | 11 +++++++ src/lib-sieve/sieve-match.c | 2 +- tests/extensions/variables/string.svtest | 10 ++++++ 12 files changed, 69 insertions(+), 20 deletions(-) diff --git a/Makefile.am b/Makefile.am index 3090495a4..523036a24 100644 --- a/Makefile.am +++ b/Makefile.am @@ -34,6 +34,7 @@ test_cases = \ tests/extensions/variables/match.svtest \ tests/extensions/variables/modifiers.svtest \ tests/extensions/variables/quoting.svtest \ + tests/extensions/variables/string.svtest \ tests/extensions/include/variables.svtest \ tests/extensions/imapflags/basic.svtest \ tests/extensions/imapflags/rfc.svtest \ diff --git a/TODO b/TODO index 535bc73f0..20c6231d4 100644 --- a/TODO +++ b/TODO @@ -2,7 +2,6 @@ Next (in order of descending priority/precedence): * Full standards compliance review for the engine and all fully implemented sieve extensions. Issues discovered so far: - :matches : match values must only be changed when the test matches. - - string test must not :count empty strings - If an address is not syntactically valid, then it will not be matched by tests specifying ":localpart" or ":domain". - Allow for the existance of dynamic comparators diff --git a/src/lib-sieve/mcht-contains.c b/src/lib-sieve/mcht-contains.c index e10b59967..dc4174d0d 100644 --- a/src/lib-sieve/mcht-contains.c +++ b/src/lib-sieve/mcht-contains.c @@ -49,6 +49,9 @@ static int mcht_contains_match const char *vp = val; const char *kp = key; + if ( val == NULL || val_size == 0 ) + return ( key_size == 0 ); + if ( mctx->comparator->char_match == NULL ) return FALSE; diff --git a/src/lib-sieve/mcht-is.c b/src/lib-sieve/mcht-is.c index 0b131615b..dd64df659 100644 --- a/src/lib-sieve/mcht-is.c +++ b/src/lib-sieve/mcht-is.c @@ -16,7 +16,7 @@ */ static int mcht_is_match - (struct sieve_match_context *mctx, const char *val1, size_t val1_size, + (struct sieve_match_context *mctx, const char *val, size_t val_size, const char *key, size_t key_size, int key_index); /* @@ -37,12 +37,15 @@ const struct sieve_match_type is_match_type = { static int mcht_is_match (struct sieve_match_context *mctx ATTR_UNUSED, - const char *val1, size_t val1_size, + const char *val, size_t val_size, const char *key, size_t key_size, int key_index ATTR_UNUSED) { + if ( (val == NULL || val_size == 0) ) + return ( key_size == 0 ); + if ( mctx->comparator->compare != NULL ) return (mctx->comparator->compare(mctx->comparator, - val1, val1_size, key, key_size) == 0); + val, val_size, key, key_size) == 0); return FALSE; } diff --git a/src/lib-sieve/mcht-matches.c b/src/lib-sieve/mcht-matches.c index 4d6a441fb..00b57a2c5 100644 --- a/src/lib-sieve/mcht-matches.c +++ b/src/lib-sieve/mcht-matches.c @@ -86,24 +86,30 @@ static int mcht_matches_match { const struct sieve_comparator *cmp = mctx->comparator; struct sieve_match_values *mvalues; - - string_t *mvalue = t_str_new(32); /* Match value (*) */ - string_t *mchars = t_str_new(32); /* Match characters (.?..?.??) */ - string_t *section = t_str_new(32); /* Section (after beginning or *) */ - string_t *subsection = t_str_new(32); /* Sub-section (after ?) */ - - const char *vend = (const char *) val + val_size; - const char *kend = (const char *) key + key_size; - const char *vp = val; /* Value pointer */ - const char *kp = key; /* Key pointer */ - const char *wp = key; /* Wildcard (key) pointer */ - const char *pvp = val; /* Previous value Pointer */ - + string_t *mvalue, *mchars, *section, *subsection; + const char *vend, *kend, *vp, *kp, *wp, *pvp; bool backtrack = FALSE; /* TRUE: match of '?'-connected sections failed */ char wcard = '\0'; /* Current wildcard */ char next_wcard = '\0'; /* Next widlcard */ unsigned int key_offset = 0; unsigned int j = 0; + + if ( val == NULL ) { + val = ""; + val_size = 0; + } + + mvalue = t_str_new(32); /* Match value (*) */ + mchars = t_str_new(32); /* Match characters (.?..?.??) */ + section = t_str_new(32); /* Section (after beginning or *) */ + subsection = t_str_new(32); /* Sub-section (after ?) */ + + vend = (const char *) val + val_size; + kend = (const char *) key + key_size; + vp = val; /* Value pointer */ + kp = key; /* Key pointer */ + wp = key; /* Wildcard (key) pointer */ + pvp = val; /* Previous value Pointer */ /* Reset match values list */ mvalues = sieve_match_values_start(mctx->interp); diff --git a/src/lib-sieve/plugins/regex/mcht-regex.c b/src/lib-sieve/plugins/regex/mcht-regex.c index 439637b32..dc4c3ec11 100644 --- a/src/lib-sieve/plugins/regex/mcht-regex.c +++ b/src/lib-sieve/plugins/regex/mcht-regex.c @@ -231,6 +231,11 @@ static int mcht_regex_match struct mcht_regex_context *ctx = (struct mcht_regex_context *) mctx->data; regex_t *regexp; + if ( val == NULL ) { + val = ""; + val_size = 0; + } + if ( key_index < 0 ) return FALSE; if ( key_index == 0 ) ctx->value_index++; diff --git a/src/lib-sieve/plugins/relational/mcht-count.c b/src/lib-sieve/plugins/relational/mcht-count.c index 874f22b01..fe7bcc775 100644 --- a/src/lib-sieve/plugins/relational/mcht-count.c +++ b/src/lib-sieve/plugins/relational/mcht-count.c @@ -74,6 +74,9 @@ static int mcht_count_match const char *key ATTR_UNUSED, size_t key_size ATTR_UNUSED, int key_index) { + if ( val == NULL ) + return FALSE; + /* Count values */ if ( key_index == -1 ) { mctx->data = (void *) (((int) mctx->data) + 1); diff --git a/src/lib-sieve/plugins/relational/mcht-value.c b/src/lib-sieve/plugins/relational/mcht-value.c index 0ccc26864..d9c121233 100644 --- a/src/lib-sieve/plugins/relational/mcht-value.c +++ b/src/lib-sieve/plugins/relational/mcht-value.c @@ -55,7 +55,14 @@ int mcht_value_match { const struct sieve_match_type *mtch = mctx->match_type; unsigned int rel_match = REL_MATCH(mtch->object.code); - int cmp_result = mctx->comparator-> + int cmp_result; + + if ( val == NULL ) { + val = ""; + val_size = 0; + } + + cmp_result = mctx->comparator-> compare(mctx->comparator, val, val_size, key, key_size); switch ( rel_match ) { diff --git a/src/lib-sieve/plugins/variables/tst-string.c b/src/lib-sieve/plugins/variables/tst-string.c index add6d9403..a80eabd3c 100644 --- a/src/lib-sieve/plugins/variables/tst-string.c +++ b/src/lib-sieve/plugins/variables/tst-string.c @@ -214,9 +214,10 @@ static int tst_string_operation_execute while ( result && !matched && (result=sieve_coded_stringlist_next_item(source, &src_item)) && src_item != NULL ) { + const char *src = str_len(src_item) > 0 ? str_c(src_item) : NULL; if ( (mret=sieve_match_value - (mctx, str_c(src_item), str_len(src_item))) < 0 ) { + (mctx, src, str_len(src_item))) < 0 ) { result = FALSE; break; } diff --git a/src/lib-sieve/sieve-match-types.h b/src/lib-sieve/sieve-match-types.h index 293b6eec7..309d8bd25 100644 --- a/src/lib-sieve/sieve-match-types.h +++ b/src/lib-sieve/sieve-match-types.h @@ -44,7 +44,18 @@ struct sieve_match_type { (struct sieve_validator *validator, struct sieve_ast_argument *arg, struct sieve_match_type_context *ctx, struct sieve_ast_argument *key_arg); + /* + * Matching + */ + void (*match_init)(struct sieve_match_context *mctx); + + /* WARNING: some tests may pass a val == NULL parameter indicating that the passed + * value has no significance. For string-type matches this should map to the empty + * string "", but for match types that consider the passed values as objects rather + * than strings (e.g. :count) this means that the passed value should be skipped. + * This is currently only used by string test of the variables extension. + */ int (*match) (struct sieve_match_context *mctx, const char *val, size_t val_size, const char *key, size_t key_size, int key_index); diff --git a/src/lib-sieve/sieve-match.c b/src/lib-sieve/sieve-match.c index 816da07d5..37615566e 100644 --- a/src/lib-sieve/sieve-match.c +++ b/src/lib-sieve/sieve-match.c @@ -97,7 +97,7 @@ int sieve_match_value return -1; } else { - return mtch->match(mctx, value, strlen(value), NULL, 0, -1); + return mtch->match(mctx, value, val_size, NULL, 0, -1); } return FALSE; diff --git a/tests/extensions/variables/string.svtest b/tests/extensions/variables/string.svtest index 0763aae28..a2d4aa6ec 100644 --- a/tests/extensions/variables/string.svtest +++ b/tests/extensions/variables/string.svtest @@ -16,3 +16,13 @@ test "String - :count \"\"" { test_fail "string test failed :count match"; } } + +test "RFC example" { + set "state" "${state} pending"; + + if not string :matches " ${state} " "* pending *" { + # the above test always succeeds + + test_fail "test should have matched: \" ${state} \""; + } +} -- GitLab