diff --git a/src/lib-sieve/plugins/include/cmd-global.c b/src/lib-sieve/plugins/include/cmd-global.c index 6bef5cf6b8033289c980c00c17e16a6d23ef3019..93f4a8f617bf7af6b06a519fd1909d7e8b78b57a 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 43672319032a04fac10ad9fb75c75d37948cbc20..bebf5dcc867159a0fdefc32144799a8770ff0b1f 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 e2402a5fb92d9a70b597e48d9c9cd1ebafb82c8d..026bb13eb8b7f782cbaaff809a1af2e4b7df88da 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 b0e72dec79e77a542acf07de099d63ed1c76c1fc..28817a12f5c2630b61b438a5cf414a886bc99fdd 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 9eba962e10c2b01b649205f83c61df43d481f126..5258e04ad8610c08a000124efef297431a703cd5 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 7124e03afcc6188111da18d5693a9adc4b4df7d6..8b1bf4de611243aab248a6a9ec21957139bb1702 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.