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

Regex: added match values support.

parent a5b4c2c5
No related branches found
No related tags found
No related merge requests found
...@@ -20,6 +20,11 @@ ...@@ -20,6 +20,11 @@
#include <ctype.h> #include <ctype.h>
#include <regex.h> #include <regex.h>
/*
* Configuration
*/
#define MCHT_REGEX_MAX_SUBSTITUTIONS 64
/* /*
* Forward declarations * Forward declarations
*/ */
...@@ -108,7 +113,7 @@ bool mcht_regex_validate_context ...@@ -108,7 +113,7 @@ bool mcht_regex_validate_context
if ( sieve_comparator_tag_is(carg, &i_ascii_casemap_comparator) ) if ( sieve_comparator_tag_is(carg, &i_ascii_casemap_comparator) )
cflags = REG_EXTENDED | REG_NOSUB | REG_ICASE; cflags = REG_EXTENDED | REG_NOSUB | REG_ICASE;
else if ( sieve_comparator_tag_is(carg, &i_octet_comparator) ) else if ( sieve_comparator_tag_is(carg, &i_octet_comparator) )
cflags = REG_EXTENDED | REG_NOSUB ; cflags = REG_EXTENDED | REG_NOSUB;
else { else {
sieve_command_validate_error(validator, ctx->command_ctx, sieve_command_validate_error(validator, ctx->command_ctx,
"regex match type only supports " "regex match type only supports "
...@@ -121,7 +126,7 @@ bool mcht_regex_validate_context ...@@ -121,7 +126,7 @@ bool mcht_regex_validate_context
carg = sieve_ast_argument_next(carg); carg = sieve_ast_argument_next(carg);
} }
/* Validate regular expression(s) */ /* Validate regular expression(s) */
if ( sieve_ast_argument_type(key_arg) == SAAT_STRING ) { if ( sieve_ast_argument_type(key_arg) == SAAT_STRING ) {
/* Single string */ /* Single string */
...@@ -156,6 +161,9 @@ bool mcht_regex_validate_context ...@@ -156,6 +161,9 @@ bool mcht_regex_validate_context
struct mcht_regex_context { struct mcht_regex_context {
ARRAY_DEFINE(reg_expressions, regex_t *); ARRAY_DEFINE(reg_expressions, regex_t *);
int value_index; int value_index;
struct sieve_match_values *mvalues;
regmatch_t *pmatch;
size_t nmatch;
}; };
void mcht_regex_match_init void mcht_regex_match_init
...@@ -167,7 +175,15 @@ void mcht_regex_match_init ...@@ -167,7 +175,15 @@ void mcht_regex_match_init
t_array_init(&ctx->reg_expressions, 4); t_array_init(&ctx->reg_expressions, 4);
ctx->value_index = -1; ctx->value_index = -1;
ctx->mvalues = sieve_match_values_start(mctx->interp);
if ( ctx->mvalues != NULL ) {
ctx->pmatch = t_new(regmatch_t, MCHT_REGEX_MAX_SUBSTITUTIONS);
ctx->nmatch = MCHT_REGEX_MAX_SUBSTITUTIONS;
} else {
ctx->pmatch = NULL;
ctx->nmatch = 0;
}
mctx->data = (void *) ctx; mctx->data = (void *) ctx;
} }
...@@ -182,17 +198,19 @@ static regex_t *mcht_regex_get ...@@ -182,17 +198,19 @@ static regex_t *mcht_regex_get
int cflags; int cflags;
if ( ctx->value_index <= 0 ) { if ( ctx->value_index <= 0 ) {
regexp = p_new(pool_datastack_create(), regex_t, 1); regexp = t_new(regex_t, 1);
if ( cmp == &i_octet_comparator ) if ( cmp == &i_octet_comparator )
cflags = REG_EXTENDED | REG_NOSUB; cflags = REG_EXTENDED;
else if ( cmp == &i_ascii_casemap_comparator ) else if ( cmp == &i_ascii_casemap_comparator )
cflags = REG_EXTENDED | REG_NOSUB | REG_ICASE; cflags = REG_EXTENDED | REG_ICASE;
else else
return NULL; return NULL;
if ( ctx->mvalues == NULL ) cflags |= REG_NOSUB;
if ( (ret=regcomp(regexp, key, cflags)) != 0 ) { if ( (ret=regcomp(regexp, key, cflags)) != 0 ) {
/* FIXME: Do something useful, i.e. report error somewhere */ /* FIXME: Do something useful, i.e. report error somewhere */
return NULL; return NULL;
} }
...@@ -219,7 +237,28 @@ static bool mcht_regex_match ...@@ -219,7 +237,28 @@ static bool mcht_regex_match
regexp = mcht_regex_get(ctx, mctx->comparator, key, key_index); regexp = mcht_regex_get(ctx, mctx->comparator, key, key_index);
return ( regexec(regexp, val, 0, NULL, 0) == 0 ); if ( regexec(regexp, val, ctx->nmatch, ctx->pmatch, 0) == 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);
if ( ctx->pmatch[i].rm_so != -1 ) {
if ( skipped > 0 )
sieve_match_values_skip(ctx->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(ctx->mvalues, subst);
} else
skipped++;
}
return TRUE;
}
return FALSE;
} }
bool mcht_regex_match_deinit bool mcht_regex_match_deinit
......
...@@ -22,6 +22,6 @@ libsieve_ext_variables_la_SOURCES = \ ...@@ -22,6 +22,6 @@ libsieve_ext_variables_la_SOURCES = \
noinst_HEADERS = \ noinst_HEADERS = \
ext-variables-common.h \ ext-variables-common.h \
ext-variables-name.h ext-variables-name.h \
sieve-ext-variables.h
require "variables";
require "regex";
require "fileinto";
set "match1" "Hutseflutsfropfrml";
if string :regex "${match1}" "Hutse(.+)fropfrml" {
fileinto "${0}:${1}:${2}";
}
if string :regex "${match1}" "(.+)f((.+)f(.+))f(.+)" {
fileinto "${0}:${1}:${2}:${3}:${4}:${5}";
}
if string :regex "${match1}" "(.+)((g(.+)friep)|(f(.+)frop))(.+)" {
fileinto "${0}:${1}:${2}:${3}:${4}:${5}:${6}:${7}";
}
...@@ -303,6 +303,15 @@ void sieve_match_values_add_char ...@@ -303,6 +303,15 @@ void sieve_match_values_add_char
str_append_c(entry, c); str_append_c(entry, c);
} }
void sieve_match_values_skip
(struct sieve_match_values *mvalues, int num)
{
int i;
for ( i = 0; i < num; i++ )
(void) sieve_match_values_add_entry(mvalues);
}
void sieve_match_values_get void sieve_match_values_get
(struct sieve_interpreter *interp, unsigned int index, string_t **value_r) (struct sieve_interpreter *interp, unsigned int index, string_t **value_r)
{ {
......
...@@ -83,6 +83,8 @@ void sieve_match_values_add ...@@ -83,6 +83,8 @@ void sieve_match_values_add
(struct sieve_match_values *mvalues, string_t *value); (struct sieve_match_values *mvalues, string_t *value);
void sieve_match_values_add_char void sieve_match_values_add_char
(struct sieve_match_values *mvalues, char c); (struct sieve_match_values *mvalues, char c);
void sieve_match_values_skip
(struct sieve_match_values *mvalues, int num);
void sieve_match_values_get void sieve_match_values_get
(struct sieve_interpreter *interp, unsigned int index, string_t **value_r); (struct sieve_interpreter *interp, unsigned int index, string_t **value_r);
......
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.