From 05545fa1445b855bdd5a5017765330fb85b39504 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Tue, 20 Nov 2007 14:26:33 +0100 Subject: [PATCH] Implemented detection of duplicate optional arguments. --- sieve/errors/address-part-errors.sieve | 10 +++++++ sieve/errors/interesting.sieve | 8 ++++-- sieve/errors/match-type-errors.sieve | 10 +++++++ src/lib-sieve/sieve-address-parts.c | 2 +- src/lib-sieve/sieve-ast.h | 1 + src/lib-sieve/sieve-match-types.c | 2 +- src/lib-sieve/sieve-validator.c | 37 +++++++++++++++++++++++--- 7 files changed, 62 insertions(+), 8 deletions(-) create mode 100644 sieve/errors/address-part-errors.sieve create mode 100644 sieve/errors/match-type-errors.sieve diff --git a/sieve/errors/address-part-errors.sieve b/sieve/errors/address-part-errors.sieve new file mode 100644 index 000000000..9a49af08a --- /dev/null +++ b/sieve/errors/address-part-errors.sieve @@ -0,0 +1,10 @@ +if address :all :comparator "i;octet" :domain "from" "STEPHAN" { + discard; + + if address :localpart :domain :comparator "i;octet" "from" "drunksnipers.com" { + keep; + } + stop; +} + +keep; diff --git a/sieve/errors/interesting.sieve b/sieve/errors/interesting.sieve index 6db130c8f..84ee424bf 100644 --- a/sieve/errors/interesting.sieve +++ b/sieve/errors/interesting.sieve @@ -3,9 +3,9 @@ require ["copy", "relational"]; require "envelope"; require "regex"; -if header :is "To" "Stephan \"Nico\" Bosch <nico@vestingbar>" { +if header :is "To" "Stephan \"Nico\" Bosch <nico@voorbeeld.nl>" { fileinto "INBOX.stephan"; -} elsif header :matches "To" "*@vestingbar.nl" { +} elsif header :matches "To" "*@voorbeeld.nl" { fileinto "INBOX.vestingbar"; } @@ -16,3 +16,7 @@ if envelope :isnot :comperator "i;ascii-casemap" :localpart "From" "nico" { if :disabled true { break; } + +if header :comparator "i;octet" :is :comparator "i;ascii-casemap" { + frop; +} diff --git a/sieve/errors/match-type-errors.sieve b/sieve/errors/match-type-errors.sieve new file mode 100644 index 000000000..05723d71f --- /dev/null +++ b/sieve/errors/match-type-errors.sieve @@ -0,0 +1,10 @@ +if address :contains :is :comparator "i;ascii-casemap" :localpart "from" "STEPHAN" { + discard; + + if address :contains :domain :comparator "i;octet" :matches "from" "drunksnipers.com" { + keep; + } + stop; +} + +keep; diff --git a/src/lib-sieve/sieve-address-parts.c b/src/lib-sieve/sieve-address-parts.c index 77e5e39da..26d14a58e 100644 --- a/src/lib-sieve/sieve-address-parts.c +++ b/src/lib-sieve/sieve-address-parts.c @@ -410,7 +410,7 @@ bool sieve_address_match_stringlist */ const struct sieve_argument address_part_tag = { - NULL, + "ADDRESS-PART", tag_address_part_is_instance_of, tag_address_part_validate, NULL, diff --git a/src/lib-sieve/sieve-ast.h b/src/lib-sieve/sieve-ast.h index 5b196c541..ecaa436af 100644 --- a/src/lib-sieve/sieve-ast.h +++ b/src/lib-sieve/sieve-ast.h @@ -232,6 +232,7 @@ void sieve_ast_unparse(struct sieve_ast *ast); /* AST argument macros */ #define sieve_ast_argument_first(node) __LIST_FIRST(node, arguments) +#define sieve_ast_argument_prev(argument) __LIST_PREV(argument) #define sieve_ast_argument_next(argument) __LIST_NEXT(argument) #define sieve_ast_argument_count(node) __LIST_COUNT(node, arguments) #define sieve_ast_argument_type(argument) ((argument) == NULL ? SAAT_NONE : (argument)->type) diff --git a/src/lib-sieve/sieve-match-types.c b/src/lib-sieve/sieve-match-types.c index bb3ec242d..5ac03d8cd 100644 --- a/src/lib-sieve/sieve-match-types.c +++ b/src/lib-sieve/sieve-match-types.c @@ -475,7 +475,7 @@ static bool mtch_matches_match */ const struct sieve_argument match_type_tag = { - NULL, + "MATCH-TYPE", tag_match_type_is_instance_of, tag_match_type_validate, tag_match_type_validate_context, diff --git a/src/lib-sieve/sieve-validator.c b/src/lib-sieve/sieve-validator.c index 715903ff4..d3aac8522 100644 --- a/src/lib-sieve/sieve-validator.c +++ b/src/lib-sieve/sieve-validator.c @@ -402,6 +402,8 @@ static bool sieve_validate_command_arguments /* Parse tagged and optional arguments */ while ( sieve_ast_argument_type(arg) == SAAT_TAG ) { unsigned int id_code; + struct sieve_ast_argument *tag_arg = arg; + struct sieve_ast_argument *parg; const struct sieve_argument *tag = sieve_validator_find_tag (validator, cmd_reg, sieve_ast_argument_tag(arg), &id_code); @@ -421,18 +423,43 @@ static bool sieve_validate_command_arguments if ( tag->identifier != NULL && *(tag->identifier) == '\0' ) return FALSE; - /* Assign the tagged argument type to the ast for later reference (in generator) */ + /* Assign the tagged argument type to the ast for later reference + * (in generator) + */ arg->argument = tag; arg->arg_id_code = id_code; /* Call the validation function for the tag (if present) - * Fail if the validation fails. + * Fail if the validation fails: + * Let's not whine multiple times about a single command having multiple + * bad arguments... */ if ( tag->validate != NULL ) { if ( !tag->validate(validator, &arg, cmd) ) return FALSE; } else arg = sieve_ast_argument_next(arg); + + /* Scan backwards for any duplicates */ + parg = sieve_ast_argument_prev(tag_arg); + while ( parg != NULL ) { + if ( parg->argument == tag ) { + const char *tag_id = sieve_ast_argument_tag(tag_arg); + const char *tag_desc = + strcmp(tag->identifier, tag_id) != 0 ? + t_strdup_printf("%s argument (:%s)", tag->identifier, tag_id) : + t_strdup_printf(":%s argument", tag->identifier); + + sieve_command_validate_error(validator, cmd, + "encountered duplicate %s for the %s %s", + tag_desc, cmd->command->identifier, + sieve_command_type_name(cmd->command)); + + return FALSE; + } + + parg = sieve_ast_argument_prev(parg); + } } /* Remaining arguments should be positional (tags are not allowed here) */ @@ -441,8 +468,10 @@ static bool sieve_validate_command_arguments while ( arg != NULL ) { if ( sieve_ast_argument_type(arg) == SAAT_TAG ) { sieve_command_validate_error(validator, cmd, - "encountered an unexpected tagged argument ':%s' while validating positional arguments for the %s %s", - sieve_ast_argument_tag(arg), cmd->command->identifier, sieve_command_type_name(cmd->command)); + "encountered an unexpected tagged argument ':%s' " + "while validating positional arguments for the %s %s", + sieve_ast_argument_tag(arg), cmd->command->identifier, + sieve_command_type_name(cmd->command)); return FALSE; } -- GitLab