From f32edce23ecb2ba0ca6387a2aec57856bd05f543 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Tue, 20 Nov 2007 12:29:58 +0100 Subject: [PATCH] Made regex match complaint about comparators other than i;octet or i;ascii-casemap --- src/lib-sieve/plugins/regex/ext-regex.c | 37 ++++++++++++++++++- .../plugins/regex/regex-errors.sieve | 9 +++++ src/lib-sieve/sieve-commands.h | 11 ++++-- src/lib-sieve/sieve-comparators.c | 7 ++++ src/lib-sieve/sieve-comparators.h | 8 +++- src/lib-sieve/sieve-validator.c | 3 +- 6 files changed, 67 insertions(+), 8 deletions(-) create mode 100644 src/lib-sieve/plugins/regex/regex-errors.sieve diff --git a/src/lib-sieve/plugins/regex/ext-regex.c b/src/lib-sieve/plugins/regex/ext-regex.c index ab8ae3d0c..829d3d30e 100644 --- a/src/lib-sieve/plugins/regex/ext-regex.c +++ b/src/lib-sieve/plugins/regex/ext-regex.c @@ -13,7 +13,10 @@ #include "sieve-code.h" #include "sieve-extensions.h" #include "sieve-commands.h" + +#include "sieve-comparators.h" #include "sieve-match-types.h" + #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" @@ -53,13 +56,17 @@ static bool ext_regex_load(int ext_id) extern const struct sieve_match_type_extension regex_match_extension; +bool mtch_regex_validate_context +(struct sieve_validator *validator, struct sieve_ast_argument *arg, + struct sieve_match_type_context *ctx); + const struct sieve_match_type regex_match_type = { "regex", SIEVE_MATCH_TYPE_CUSTOM, ®ex_match_extension, 0, NULL, - NULL, + mtch_regex_validate_context, NULL }; @@ -69,6 +76,34 @@ const struct sieve_match_type_extension regex_match_extension = { NULL }; +/* Validation */ + +bool mtch_regex_validate_context +(struct sieve_validator *validator, struct sieve_ast_argument *arg, + struct sieve_match_type_context *ctx) +{ + struct sieve_ast_argument *carg = + sieve_command_first_argument(ctx->command_ctx); + + while ( carg != NULL ) { + if ( carg != arg && carg->argument == &comparator_tag ) { + if (!sieve_comparator_tag_is(carg, &i_ascii_casemap_comparator) && + !sieve_comparator_tag_is(carg, &i_octet_comparator) ) + { + sieve_command_validate_error(validator, ctx->command_ctx, + "regex match type only supports i;octet and i;ascii-casemap comparators" ); + return FALSE; + } + + return TRUE; + } + + carg = sieve_ast_argument_next(carg); + } + + return TRUE; +} + /* Load extension into validator */ static bool ext_regex_validator_load(struct sieve_validator *validator) diff --git a/src/lib-sieve/plugins/regex/regex-errors.sieve b/src/lib-sieve/plugins/regex/regex-errors.sieve new file mode 100644 index 000000000..10b8b6a65 --- /dev/null +++ b/src/lib-sieve/plugins/regex/regex-errors.sieve @@ -0,0 +1,9 @@ +require "regex"; +require "comparator-i;ascii-numeric"; + +if address :regex :comparator "i;ascii-numeric" "from" "sirius(\\+.*)?@drunksnipers\\.com" { + keep; + stop; +} + +discard; diff --git a/src/lib-sieve/sieve-commands.h b/src/lib-sieve/sieve-commands.h index 30c7c6ae4..bc41804e8 100644 --- a/src/lib-sieve/sieve-commands.h +++ b/src/lib-sieve/sieve-commands.h @@ -83,14 +83,17 @@ struct sieve_command_context *sieve_command_context_create const char *sieve_command_type_name(const struct sieve_command *command); #define sieve_command_validate_error(validator, context, ...) \ - sieve_validator_error(validator, context->ast_node, __VA_ARGS__) + sieve_validator_error(validator, (context)->ast_node, __VA_ARGS__) #define sieve_command_pool(context) \ - sieve_ast_node_pool(context->ast_node) + sieve_ast_node_pool((context)->ast_node) + +#define sieve_command_first_argument(context) \ + sieve_ast_argument_first((context)->ast_node) #define sieve_command_is_toplevel(context) \ - ( sieve_ast_node_type(sieve_ast_node_parent(context->ast_node)) == SAT_ROOT ) + ( sieve_ast_node_type(sieve_ast_node_parent((context)->ast_node)) == SAT_ROOT ) #define sieve_command_is_first(context) \ - ( sieve_ast_node_prev(context->ast_node) == NULL ) + ( sieve_ast_node_prev((context)->ast_node) == NULL ) struct sieve_command_context *sieve_command_prev_context (struct sieve_command_context *context); diff --git a/src/lib-sieve/sieve-comparators.c b/src/lib-sieve/sieve-comparators.c index 2dfdf6e10..24a2a77ae 100644 --- a/src/lib-sieve/sieve-comparators.c +++ b/src/lib-sieve/sieve-comparators.c @@ -285,6 +285,13 @@ void sieve_comparators_link_tag sieve_validator_register_tag(validator, cmd_reg, &comparator_tag, id_code); } +inline bool sieve_comparator_tag_is +(struct sieve_ast_argument *tag, const struct sieve_comparator *cmp) +{ + return (tag->argument == &comparator_tag && + ((const struct sieve_comparator *) tag->context) == cmp); +} + /* Code generation */ static void opr_comparator_emit diff --git a/src/lib-sieve/sieve-comparators.h b/src/lib-sieve/sieve-comparators.h index 70ce48e55..4bd564511 100644 --- a/src/lib-sieve/sieve-comparators.h +++ b/src/lib-sieve/sieve-comparators.h @@ -47,13 +47,17 @@ struct sieve_comparator_extension { (unsigned int code); }; +extern const struct sieve_argument comparator_tag; + void sieve_comparators_link_tag (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg, unsigned int id_code); +inline bool sieve_comparator_tag_is +(struct sieve_ast_argument *tag, const struct sieve_comparator *cmp); -const struct sieve_comparator i_octet_comparator; -const struct sieve_comparator i_ascii_casemap_comparator; +extern const struct sieve_comparator i_octet_comparator; +extern const struct sieve_comparator i_ascii_casemap_comparator; void sieve_comparator_register (struct sieve_validator *validator, diff --git a/src/lib-sieve/sieve-validator.c b/src/lib-sieve/sieve-validator.c index 5cb8997a6..715903ff4 100644 --- a/src/lib-sieve/sieve-validator.c +++ b/src/lib-sieve/sieve-validator.c @@ -465,7 +465,8 @@ static bool sieve_validate_command_arguments static bool sieve_validate_arguments_context (struct sieve_validator *validator, struct sieve_command_context *cmd) { - struct sieve_ast_argument *arg = sieve_ast_argument_first(cmd->ast_node); + struct sieve_ast_argument *arg = + sieve_command_first_argument(cmd); while ( arg != NULL ) { const struct sieve_argument *argument = arg->argument; -- GitLab