From 3de551b54b8ded0b5f7a2cb6f8ed8fb61bfef3a8 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Tue, 5 Jul 2011 20:32:28 +0200 Subject: [PATCH] lib-sieve: include extension: forgot to check variable identifier syntax. --- src/lib-sieve/plugins/include/cmd-global.c | 4 +- .../plugins/include/ext-include-variables.c | 9 ++++ .../variables/ext-variables-arguments.c | 10 ++-- .../plugins/variables/ext-variables-name.c | 50 ++++++++++++++----- .../plugins/variables/sieve-ext-variables.h | 2 + .../extensions/include/rfc-ex2-default.sieve | 2 +- 6 files changed, 57 insertions(+), 20 deletions(-) diff --git a/src/lib-sieve/plugins/include/cmd-global.c b/src/lib-sieve/plugins/include/cmd-global.c index 6bef5cf6b..93f4a8f61 100644 --- a/src/lib-sieve/plugins/include/cmd-global.c +++ b/src/lib-sieve/plugins/include/cmd-global.c @@ -174,13 +174,13 @@ static bool cmd_global_validate sieve_ast_argument_name(arg)); return FALSE; } - + /* Join global commands with predecessors if possible */ if ( sieve_commands_equal(prev, cmd) ) { /* Join this command's string list with the previous one */ prev->first_positional = sieve_ast_stringlist_join (prev->first_positional, cmd->first_positional); - + if ( prev->first_positional == NULL ) { /* Not going to happen unless MAXINT stringlist items are specified */ sieve_command_validate_error(valdtr, cmd, diff --git a/src/lib-sieve/plugins/include/ext-include-variables.c b/src/lib-sieve/plugins/include/ext-include-variables.c index 436723190..bebf5dcc8 100644 --- a/src/lib-sieve/plugins/include/ext-include-variables.c +++ b/src/lib-sieve/plugins/include/ext-include-variables.c @@ -1,6 +1,9 @@ /* Copyright (c) 2002-2011 Pigeonhole authors, see the included COPYING file */ +#include "lib.h" +#include "str-sanitize.h" + #include "sieve-common.h" #include "sieve-error.h" #include "sieve-script.h" @@ -38,6 +41,12 @@ struct sieve_variable *ext_include_variable_import_global /* Sanity safeguard */ i_assert ( ctx->global_vars != NULL ); + if ( !sieve_variable_identifier_is_valid(variable) ) { + sieve_command_validate_error(valdtr, cmd, + "invalid variable identifier '%s'", str_sanitize(variable,80)); + return NULL; + } + /* Get/Declare the variable in the global scope */ global_var = sieve_variable_scope_get_variable(global_scope, variable, TRUE); diff --git a/src/lib-sieve/plugins/variables/ext-variables-arguments.c b/src/lib-sieve/plugins/variables/ext-variables-arguments.c index e2402a5fb..026bb13eb 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-arguments.c +++ b/src/lib-sieve/plugins/variables/ext-variables-arguments.c @@ -343,19 +343,19 @@ static bool _sieve_variable_argument_activate bool result = FALSE; string_t *variable; const char *varstr, *varend; - ARRAY_TYPE(sieve_variable_name) vname; + ARRAY_TYPE(sieve_variable_name) vname; int nelements = 0; T_BEGIN { - t_array_init(&vname, 2); - + t_array_init(&vname, 2); + variable = sieve_ast_argument_str(arg); varstr = str_c(variable); varend = PTR_OFFSET(varstr, str_len(variable)); nelements = ext_variable_name_parse(&vname, &varstr, varend); - /* Check whether name parsing succeeded */ - if ( nelements < 0 || varstr != varend ) { + /* Check whether name parsing succeeded */ + if ( nelements <= 0 || varstr != varend ) { /* Parse failed */ sieve_argument_validate_error(valdtr, arg, "invalid variable name '%s'", str_sanitize(str_c(variable),80)); diff --git a/src/lib-sieve/plugins/variables/ext-variables-name.c b/src/lib-sieve/plugins/variables/ext-variables-name.c index b0e72dec7..28817a12f 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-name.c +++ b/src/lib-sieve/plugins/variables/ext-variables-name.c @@ -13,14 +13,36 @@ #include <ctype.h> +bool sieve_variable_identifier_is_valid(const char *identifier) +{ + const char *p = identifier; + size_t plen = strlen(identifier); + const char *pend; + + if ( plen == 0 || plen >= EXT_VARIABLES_MAX_VARIABLE_NAME_LEN ) + return FALSE; + + pend = PTR_OFFSET(identifier, plen); + + if ( *p == '_' || i_isalpha(*p) ) { + p++; + + while ( p < pend && (*p == '_' || i_isalnum(*p)) ) { + p++; + } + } + + return ( p == pend ); +} + int ext_variable_name_parse (ARRAY_TYPE(sieve_variable_name) *vname, const char **str, const char *strend) { const char *p = *str; - + array_clear(vname); - for (;;) { + while ( p < strend ) { struct sieve_variable_name *cur_element; string_t *cur_ident; @@ -40,23 +62,23 @@ int ext_variable_name_parse str_truncate(cur_ident, 0); str_append_c(cur_ident, *p); p++; - + while ( p < strend && (*p == '_' || i_isalnum(*p)) ) { if ( str_len(cur_ident) >= EXT_VARIABLES_MAX_VARIABLE_NAME_LEN ) return -1; str_append_c(cur_ident, *p); p++; } - + /* Num-variable */ } else if ( i_isdigit(*p) ) { cur_element->num_variable = *p - '0'; p++; - + while ( p < strend && i_isdigit(*p) ) { cur_element->num_variable = cur_element->num_variable*10 + (*p - '0'); p++; - } + } /* If a num-variable is first, no more elements can follow because no * namespace is specified. @@ -69,16 +91,20 @@ int ext_variable_name_parse *str = p; return -1; } - + /* Check whether next name element is present */ - if ( p < strend && *p == '.' ) + if ( p < strend && *p == '.' ) { p++; - else + + /* It may not be empty */ + if ( p >= strend ) + return -1; + } else break; } - + *str = p; return array_count(vname); -} - +} + diff --git a/src/lib-sieve/plugins/variables/sieve-ext-variables.h b/src/lib-sieve/plugins/variables/sieve-ext-variables.h index 9eba962e1..5258e04ad 100644 --- a/src/lib-sieve/plugins/variables/sieve-ext-variables.h +++ b/src/lib-sieve/plugins/variables/sieve-ext-variables.h @@ -46,6 +46,8 @@ struct sieve_variable_name { ARRAY_DEFINE_TYPE(sieve_variable_name, struct sieve_variable_name); +bool sieve_variable_identifier_is_valid(const char *identifier); + /* * Variable scope */ diff --git a/tests/extensions/include/rfc-ex2-default.sieve b/tests/extensions/include/rfc-ex2-default.sieve index 7124e03af..8b1bf4de6 100644 --- a/tests/extensions/include/rfc-ex2-default.sieve +++ b/tests/extensions/include/rfc-ex2-default.sieve @@ -1,6 +1,6 @@ require ["variables", "include", "relational", "fileinto"]; global "test"; -global "test-mailbox"; +global "test_mailbox"; # The included script may contain repetitive code that is # effectively a subroutine that can be factored out. -- GitLab