From fa4ae8167f446e094758368559f9f6f69f96c291 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Wed, 12 Nov 2014 22:09:44 +0100 Subject: [PATCH] lib-sieve: Made validator resolve all tagged command arguments before validating them. This is needed so that argument validation functions can reliably verify other arguments at arbitrary positions. --- src/lib-sieve/sieve-validator.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/lib-sieve/sieve-validator.c b/src/lib-sieve/sieve-validator.c index 667997d04..5a01fb0d8 100644 --- a/src/lib-sieve/sieve-validator.c +++ b/src/lib-sieve/sieve-validator.c @@ -890,17 +890,20 @@ static bool sieve_validate_command_arguments struct sieve_ast_argument *arg; struct sieve_command_registration *cmd_reg = cmd->reg; - /* Validate any tags that might be present */ + /* Resolve tagged arguments */ arg = sieve_ast_argument_first(cmd->ast_node); - - /* Visit tagged and optional arguments */ - while ( arg != NULL && sieve_ast_argument_type(arg) == SAAT_TAG ) { - struct sieve_ast_argument *parg; + while ( arg != NULL ) { void *arg_data = NULL; - struct sieve_tag_registration *tag_reg = - sieve_validator_command_tag_get(valdtr, cmd, arg, &arg_data); + struct sieve_tag_registration *tag_reg; const struct sieve_argument_def *tag_def; + if (sieve_ast_argument_type(arg) != SAAT_TAG) { + arg = sieve_ast_argument_next(arg); + continue; + } + + tag_reg = sieve_validator_command_tag_get(valdtr, cmd, arg, &arg_data); + if ( tag_reg == NULL ) { sieve_argument_validate_error(valdtr, arg, "unknown tagged argument ':%s' for the %s %s " @@ -923,13 +926,22 @@ static bool sieve_validate_command_arguments (arg->ast, tag_def, tag_reg->ext, tag_reg->id_code); arg->argument->data = arg_data; + arg = sieve_ast_argument_next(arg); + } + + /* Validate tagged arguments */ + arg = sieve_ast_argument_first(cmd->ast_node); + while ( arg != NULL && sieve_ast_argument_type(arg) == SAAT_TAG) { + const struct sieve_argument_def *tag_def = arg->argument->def; + struct sieve_ast_argument *parg; + /* Scan backwards for any duplicates */ parg = sieve_ast_argument_prev(arg); while ( parg != NULL ) { if ( (sieve_ast_argument_type(parg) == SAAT_TAG && - parg->argument->def == tag_reg->tag_def) - || (tag_reg->id_code > 0 && parg->argument != NULL && - parg->argument->id_code == tag_reg->id_code) ) + parg->argument->def == tag_def) + || (arg->argument->id_code > 0 && parg->argument != NULL && + parg->argument->id_code == arg->argument->id_code) ) { const char *tag_id = sieve_ast_argument_tag(arg); const char *tag_desc = -- GitLab