From 353c11c7ad621c051007b9173092deb9e5eba5fe Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Fri, 1 Aug 2008 17:54:40 +0200 Subject: [PATCH] Fixed bug in the order of default argument processing. Variable strings were evaluated befor constant strings, which is wrong. --- src/lib-sieve/ext-encoded-character.c | 3 +- .../variables/ext-variables-arguments.c | 2 +- src/lib-sieve/sieve-validator.c | 46 +++++++++++-------- tests/extensions/variables/quoting.svtest | 36 +++++++++++++++ 4 files changed, 64 insertions(+), 23 deletions(-) create mode 100644 tests/extensions/variables/quoting.svtest diff --git a/src/lib-sieve/ext-encoded-character.c b/src/lib-sieve/ext-encoded-character.c index 1097b3eee..85532885e 100644 --- a/src/lib-sieve/ext-encoded-character.c +++ b/src/lib-sieve/ext-encoded-character.c @@ -94,9 +94,8 @@ static bool _parse_hexint if ( (**in) >= '0' && (**in) <= '9' ) *result = ((*result) << 4) + (**in) - ((unsigned int) '0'); - /* REPORTME: Lower-case version is not allowed by RFC else if ( (**in) >= 'a' && (**in) <= 'f' ) - *result = ((*result) << 4) + (**in) - ((unsigned int) 'a') + 0x0a;*/ + *result = ((*result) << 4) + (**in) - ((unsigned int) 'a') + 0x0a; else if ( (**in) >= 'A' && (**in) <= 'F' ) *result = ((*result) << 4) + (**in) - ((unsigned int) 'A') + 0x0a; else diff --git a/src/lib-sieve/plugins/variables/ext-variables-arguments.c b/src/lib-sieve/plugins/variables/ext-variables-arguments.c index 07788ac0d..146fd8f2d 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-arguments.c +++ b/src/lib-sieve/plugins/variables/ext-variables-arguments.c @@ -210,7 +210,7 @@ static bool arg_variable_string_validate const char *strend = strval + str_len(str); struct _variable_string_data *strdata; bool result = TRUE; - + ARRAY_TYPE(ext_variable_name) substitution; int nelements = 0; diff --git a/src/lib-sieve/sieve-validator.c b/src/lib-sieve/sieve-validator.c index f6f38ff8a..c91d6113e 100644 --- a/src/lib-sieve/sieve-validator.c +++ b/src/lib-sieve/sieve-validator.c @@ -39,8 +39,11 @@ struct sieve_validator { /* This is currently a wee bit ugly and needs more thought */ struct sieve_default_argument default_arguments[SAT_COUNT]; + + /* Default argument processing state (FIXME: ugly) */ struct sieve_default_argument *current_defarg; enum sieve_argument_type current_defarg_type; + bool current_defarg_constant; }; /* Predeclared statics */ @@ -106,6 +109,8 @@ struct sieve_validator *sieve_validator_create /* Setup default arguments */ validator->default_arguments[SAT_NUMBER]. argument = &number_argument; + validator->default_arguments[SAT_VAR_STRING]. + argument = &string_argument; validator->default_arguments[SAT_CONST_STRING]. argument = &string_argument; validator->default_arguments[SAT_STRING_LIST]. @@ -497,27 +502,26 @@ bool sieve_validator_argument_activate_super struct sieve_ast_argument *arg, bool constant ATTR_UNUSED) { struct sieve_default_argument *defarg; - - if ( validator->current_defarg == NULL ) + + if ( validator->current_defarg == NULL || + validator->current_defarg->overrides == NULL ) return FALSE; - if ( validator->current_defarg->overrides == NULL ) { - enum sieve_argument_type prev_type = validator->current_defarg_type; - - switch ( validator->current_defarg_type ) { - case SAT_NUMBER: + if ( validator->current_defarg->overrides->argument == &string_argument ) { + switch ( validator->current_defarg_type) { case SAT_CONST_STRING: - case SAT_STRING_LIST: - return FALSE; + if ( !validator->current_defarg_constant ) { + validator->current_defarg_type = SAT_VAR_STRING; + defarg = &validator->default_arguments[SAT_VAR_STRING]; + } else + defarg = validator->current_defarg->overrides; + break; case SAT_VAR_STRING: - validator->current_defarg_type = SAT_CONST_STRING; - defarg = &validator->default_arguments[validator->current_defarg_type]; + defarg = validator->current_defarg->overrides; break; - default: + default: return FALSE; } - - validator->current_defarg_type = prev_type; } else defarg = validator->current_defarg->overrides; @@ -536,11 +540,7 @@ bool sieve_validator_argument_activate validator->current_defarg_type = SAT_NUMBER; break; case SAAT_STRING: - if ( constant || - validator->default_arguments[SAT_VAR_STRING].argument == NULL ) - validator->current_defarg_type = SAT_CONST_STRING; - else - validator->current_defarg_type = SAT_VAR_STRING; + validator->current_defarg_type = SAT_CONST_STRING; break; case SAAT_STRING_LIST: validator->current_defarg_type = SAT_STRING_LIST; @@ -548,8 +548,14 @@ bool sieve_validator_argument_activate default: return FALSE; } - + + validator->current_defarg_constant = constant; defarg = &validator->default_arguments[validator->current_defarg_type]; + + if ( !constant && defarg->argument == &string_argument ) { + validator->current_defarg_type = SAT_VAR_STRING; + defarg = &validator->default_arguments[SAT_VAR_STRING]; + } return sieve_validator_argument_default_activate(validator, cmd, defarg, arg); } diff --git a/tests/extensions/variables/quoting.svtest b/tests/extensions/variables/quoting.svtest new file mode 100644 index 000000000..e9a23b0a0 --- /dev/null +++ b/tests/extensions/variables/quoting.svtest @@ -0,0 +1,36 @@ +require "vnd.dovecot.testsuite"; + +require "variables"; +require "encoded-character"; + +test "Encodings - RFC examples" { + set "s" "$"; + set "foo" "bar"; + + # "${fo\o}" => ${foo} => the expansion of variable foo. + if not string :is "${fo\o}" "bar" { + test_fail "failed 'the expansion of variable foo (${s}{fo\\o})'"; + } + + # "${fo\\o}" => ${fo\o} => illegal identifier => left verbatim. + if not string :is "${fo\\o}" "${s}{fo\\o}" { + test_fail "failed 'illegal identifier => left verbatim'"; + } + + # "\${foo}" => ${foo} => the expansion of variable foo. + if not string "\${foo}" "bar" { + test_fail "failed 'the expansion of variable foo (\\${s}{foo})'"; + } + + # "\\${foo}" => \${foo} => a backslash character followed by the + # expansion of variable foo. + if not string "\\${foo}" "\\bar" { + test_fail "failed 'a backslash character followed by expansion of variable foo"; + } + + set "name" "Ethelbert"; + if not string "dear${hex:20 24 7b 4e}ame}" "dear Ethelbert" { + test_fail "failed 'dear Ethelbert' example"; + } +} + -- GitLab