Skip to content
Snippets Groups Projects
Commit 59568b9d authored by Stephan Bosch's avatar Stephan Bosch
Browse files

Regex: added support for variable regex keys.

parent 52b7dd1a
No related branches found
No related tags found
No related merge requests found
......@@ -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:
......
......@@ -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(&regexp, sieve_ast_argument_strc(key), cflags)) != 0 ) {
if ( (ret=regcomp(&regexp, regex_str, cflags)) != 0 ) {
sieve_argument_validate_error(valdtr, key,
"invalid regular expression for regex match: %s",
_regexp_error(&regexp, ret));
"invalid regular expression '%s' for regex match: %s",
str_sanitize(regex_str, 128), _regexp_error(&regexp, ret));
regfree(&regexp);
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;
......
......@@ -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";
}
}
......@@ -26,14 +26,5 @@ set "script" "blacklist";
include "${blacklist}";
/* Variable regexp */
set "match" "(.*)rename-it(.*)";
if address :regex "from" "${match}" {
stop;
}
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";
}
}
......@@ -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";
}
}
require "regex";
require "variables";
require "fileinto";
set "regex" "[";
if header :regex "to" "${regex}" {
fileinto "frop";
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment

Consent

On this website, we use the web analytics service Matomo to analyze and review the use of our website. Through the collected statistics, we can improve our offerings and make them more appealing for you. Here, you can decide whether to allow us to process your data and set corresponding cookies for these purposes, in addition to technically necessary cookies. Further information on data protection—especially regarding "cookies" and "Matomo"—can be found in our privacy policy. You can withdraw your consent at any time.