From 59568b9dee7cef3afc47f42d6bc2a0164fc9359e Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Fri, 17 Sep 2010 22:05:33 +0200 Subject: [PATCH] Regex: added support for variable regex keys. --- TODO | 1 - src/lib-sieve/plugins/regex/mcht-regex.c | 29 ++++++++++++--------- tests/compile/errors.svtest | 2 +- tests/compile/errors/unsupported.sieve | 9 ------- tests/extensions/regex/basic.svtest | 13 +++++++++ tests/extensions/regex/errors.svtest | 15 +++++++++++ tests/extensions/regex/errors/runtime.sieve | 9 +++++++ 7 files changed, 55 insertions(+), 23 deletions(-) create mode 100644 tests/extensions/regex/errors/runtime.sieve diff --git a/TODO b/TODO index 57d0d5a5d..1305d77f2 100644 --- a/TODO +++ b/TODO @@ -7,7 +7,6 @@ Next (in order of descending priority/precedence): * Add normalize() method to comparators to normalize the string before matching (for efficiency). * Further develop regex extension and update it to the latest draft: - - Allow for :regex matching with variable key - Implement the :quoteregex set modifier - Investigate the use of the TRE regexp library to gain UTF-8 capability * Finish body extension: diff --git a/src/lib-sieve/plugins/regex/mcht-regex.c b/src/lib-sieve/plugins/regex/mcht-regex.c index 9d1061564..ed06114de 100644 --- a/src/lib-sieve/plugins/regex/mcht-regex.c +++ b/src/lib-sieve/plugins/regex/mcht-regex.c @@ -17,6 +17,7 @@ #include "sieve-stringlist.h" #include "sieve-commands.h" #include "sieve-validator.h" +#include "sieve-interpreter.h" #include "sieve-comparators.h" #include "sieve-match-types.h" #include "sieve-match.h" @@ -94,11 +95,12 @@ static int mcht_regex_validate_regexp { int ret; regex_t regexp; + const char *regex_str = sieve_ast_argument_strc(key); - if ( (ret=regcomp(®exp, sieve_ast_argument_strc(key), cflags)) != 0 ) { + if ( (ret=regcomp(®exp, regex_str, cflags)) != 0 ) { sieve_argument_validate_error(valdtr, key, - "invalid regular expression for regex match: %s", - _regexp_error(®exp, ret)); + "invalid regular expression '%s' for regex match: %s", + str_sanitize(regex_str, 128), _regexp_error(®exp, ret)); regfree(®exp); return FALSE; @@ -122,15 +124,12 @@ static int mcht_regex_validate_key_argument /* FIXME: We can currently only handle string literal argument, so * variables are not allowed. */ - if ( !sieve_argument_is_string_literal(key) ) { - sieve_argument_validate_error(keyctx->valdtr, key, - "this Sieve implementation currently only accepts a literal string " - "for a regular expression"); - return FALSE; + if ( sieve_argument_is_string_literal(key) ) { + return mcht_regex_validate_regexp + (keyctx->valdtr, keyctx->mtctx, key, keyctx->cflags); } - return mcht_regex_validate_regexp - (keyctx->valdtr, keyctx->mtctx, key, keyctx->cflags); + return TRUE; } static bool mcht_regex_validate_context @@ -301,12 +300,18 @@ static int mcht_regex_match_keys rkey->status = -1; /* Not supported */ if ( rkey->status >= 0 ) { + const char *regex_str = str_c(key_item); + int rxret; + /* Indicate whether match values need to be produced */ if ( ctx->nmatch == 0 ) cflags |= REG_NOSUB; /* Compile regular expression */ - if ( regcomp(&rkey->regexp, str_c(key_item), cflags) != 0 ) { - /* FIXME: Do something useful, i.e. report error somewhere */ + if ( (rxret=regcomp(&rkey->regexp, regex_str, cflags)) != 0 ) { + sieve_runtime_error(renv, NULL, + "invalid regular expression '%s' for regex match: %s", + str_sanitize(regex_str, 128), + _regexp_error(&rkey->regexp, rxret)); rkey->status = -1; } else { rkey->status = 1; diff --git a/tests/compile/errors.svtest b/tests/compile/errors.svtest index 8dc58aeee..a1d3673c5 100644 --- a/tests/compile/errors.svtest +++ b/tests/compile/errors.svtest @@ -361,7 +361,7 @@ test "Unsupported language features (FIXME: count only)" { test_fail "compile should have failed."; } - if not test_error :count "eq" :comparator "i;ascii-numeric" "4" { + if not test_error :count "eq" :comparator "i;ascii-numeric" "3" { test_fail "wrong number of errors reported"; } } diff --git a/tests/compile/errors/unsupported.sieve b/tests/compile/errors/unsupported.sieve index a9481d256..e367ad193 100644 --- a/tests/compile/errors/unsupported.sieve +++ b/tests/compile/errors/unsupported.sieve @@ -26,14 +26,5 @@ set "script" "blacklist"; include "${blacklist}"; -/* Variable regexp */ - -set "match" "(.*)rename-it(.*)"; - -if address :regex "from" "${match}" { - stop; -} - - diff --git a/tests/extensions/regex/basic.svtest b/tests/extensions/regex/basic.svtest index 940fec8ec..a78abfac2 100644 --- a/tests/extensions/regex/basic.svtest +++ b/tests/extensions/regex/basic.svtest @@ -1,6 +1,7 @@ require "vnd.dovecot.testsuite"; require "regex"; +require "variables"; test_set "message" text: From: stephan+sieve@friep.example.com @@ -35,4 +36,16 @@ test "More values" { if not address :regex "to" [".*\\.uk", ".*\\.nl", ".*\\.tk", ".*fi\\..*"] { test_fail "failed to match last"; } +} + +test "Variable regex" { + set "regex" "stephan[+](sieve)@friep.example.com"; + + if not header :regex "from" "${regex}" { + test_fail "failed to match variable regex"; + } + + if not string "${1}" "sieve" { + test_fail "failed to extract proper match value from variable regex"; + } } diff --git a/tests/extensions/regex/errors.svtest b/tests/extensions/regex/errors.svtest index 79c4115e3..2e0ebe0d6 100644 --- a/tests/extensions/regex/errors.svtest +++ b/tests/extensions/regex/errors.svtest @@ -12,3 +12,18 @@ test "Compile errors" { test_fail "wrong number of errors reported"; } } + +test "Runtime errors" { + if not test_script_compile "errors/runtime.sieve" { + test_fail "failed to compile"; + } + + if not test_script_run { + test_fail "script should have run fine"; + } + + if not test_error :count "eq" :comparator "i;ascii-numeric" "1" { + test_fail "wrong number of errors reported"; + } +} + diff --git a/tests/extensions/regex/errors/runtime.sieve b/tests/extensions/regex/errors/runtime.sieve new file mode 100644 index 000000000..2d0bf6628 --- /dev/null +++ b/tests/extensions/regex/errors/runtime.sieve @@ -0,0 +1,9 @@ +require "regex"; +require "variables"; +require "fileinto"; + +set "regex" "["; + +if header :regex "to" "${regex}" { + fileinto "frop"; +} -- GitLab