From d728be0dea9c17c66c6066de5408a73a17317c55 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Wed, 13 Aug 2008 23:50:15 +0200 Subject: [PATCH] Include: implemented runtime checking of export/import. --- TODO | 3 -- src/lib-sieve/plugins/include/cmd-import.c | 40 +++++++++++++++---- .../plugins/include/ext-include-common.c | 9 +++++ .../plugins/include/ext-include-common.h | 3 ++ .../plugins/variables/ext-variables-common.c | 13 +++--- tests/extensions/include/errors/runtime.sieve | 4 ++ 6 files changed, 56 insertions(+), 16 deletions(-) create mode 100644 tests/extensions/include/errors/runtime.sieve diff --git a/TODO b/TODO index c02b30550..cfb5cfaa0 100644 --- a/TODO +++ b/TODO @@ -3,9 +3,6 @@ Next (in order of descending priority/precedence): sieve extensions. Issues discovered so far: - Body: contains various bugs that need to be resolved for standards compliance. - - Include: import command must only trigger an error about unknown - exported variables at runtime, otherwise managesieve upload is - impossible. - Imapflags: when keep/fileinto is used multiple times in a script and duplicate message elimination is performed, the last flag list value MUST win. diff --git a/src/lib-sieve/plugins/include/cmd-import.c b/src/lib-sieve/plugins/include/cmd-import.c index d39aa3f72..973ba8a72 100644 --- a/src/lib-sieve/plugins/include/cmd-import.c +++ b/src/lib-sieve/plugins/include/cmd-import.c @@ -227,10 +227,9 @@ static bool opc_import_dump (const struct sieve_operation *op, const struct sieve_dumptime_env *denv, sieve_size_t *address) { - unsigned int count, i; + unsigned int count, i, var_count; struct sieve_variable_scope *scope; struct sieve_variable * const *vars; - unsigned var_count; if ( !sieve_binary_read_integer(denv->sbin, address, &count) ) return FALSE; @@ -277,12 +276,19 @@ static int opc_import_execute (const struct sieve_operation *op, const struct sieve_runtime_env *renv, sieve_size_t *address) { - unsigned int count, i; + struct sieve_variable_scope *scope; + struct sieve_variable_storage *storage; + struct sieve_variable * const *vars; + unsigned int var_count, count, i; if ( !sieve_binary_read_integer(renv->sbin, address, &count) ) { sieve_runtime_trace_error(renv, "invalid count operand"); return SIEVE_EXEC_BIN_CORRUPT; } + + scope = ext_include_binary_get_global_scope(renv->sbin); + vars = sieve_variable_scope_get_variables(scope, &var_count); + storage = ext_include_interpreter_get_global_variables(renv->interp); for ( i = 0; i < count; i++ ) { unsigned int index, source_line; @@ -292,13 +298,33 @@ static int opc_import_execute return SIEVE_EXEC_BIN_CORRUPT; } - if ( op == &import_operation && - !sieve_code_source_line_read(renv, address, &source_line) ) { - sieve_runtime_trace_error(renv, "invalid source line operand"); + if ( index >= var_count ) { + sieve_runtime_trace_error(renv, "invalid global variable index"); return SIEVE_EXEC_BIN_CORRUPT; } - /* FIXME: do something */ + if ( op == &import_operation ) { + string_t *varval; + + if ( !sieve_code_source_line_read(renv, address, &source_line) ) { + sieve_runtime_trace_error(renv, "invalid source line operand"); + return SIEVE_EXEC_BIN_CORRUPT; + } + + /* Verify variables initialization */ + (void)sieve_variable_get(storage, index, &varval); + + if ( varval == NULL ) { + sieve_runtime_error(renv, + sieve_error_script_location(renv->script, source_line), + "include: imported variable '%s' not previously exported", + vars[index]->identifier); + return SIEVE_EXEC_FAILURE; + } + } else { + /* Make sure variable is initialized (export) */ + (void)sieve_variable_get_modifiable(storage, index, NULL); + } } return SIEVE_EXEC_OK; diff --git a/src/lib-sieve/plugins/include/ext-include-common.c b/src/lib-sieve/plugins/include/ext-include-common.c index cdaa9ba37..4f685a2ab 100644 --- a/src/lib-sieve/plugins/include/ext-include-common.c +++ b/src/lib-sieve/plugins/include/ext-include-common.c @@ -317,6 +317,15 @@ void ext_include_interpreter_context_init } } +struct sieve_variable_storage *ext_include_interpreter_get_global_variables +(struct sieve_interpreter *interp) +{ + struct ext_include_interpreter_context *ctx = + ext_include_get_interpreter_context(interp); + + return ctx->global_variables; +} + /* * Including a script during generation */ diff --git a/src/lib-sieve/plugins/include/ext-include-common.h b/src/lib-sieve/plugins/include/ext-include-common.h index 9eb415910..018129b0a 100644 --- a/src/lib-sieve/plugins/include/ext-include-common.h +++ b/src/lib-sieve/plugins/include/ext-include-common.h @@ -101,4 +101,7 @@ bool ext_include_execute_include (const struct sieve_runtime_env *renv, unsigned int block_id); void ext_include_execute_return(const struct sieve_runtime_env *renv); +struct sieve_variable_storage *ext_include_interpreter_get_global_variables + (struct sieve_interpreter *interp); + #endif /* __EXT_INCLUDE_COMMON_H */ diff --git a/src/lib-sieve/plugins/variables/ext-variables-common.c b/src/lib-sieve/plugins/variables/ext-variables-common.c index 6cc6c4e0a..d1969ffee 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-common.c +++ b/src/lib-sieve/plugins/variables/ext-variables-common.c @@ -280,6 +280,10 @@ bool sieve_variable_get bool sieve_variable_get_modifiable (struct sieve_variable_storage *storage, unsigned int index, string_t **value) { + string_t *dummy; + + if ( value == NULL ) value = &dummy; + if ( !sieve_variable_get(storage, index, value) ) return FALSE; @@ -297,14 +301,9 @@ bool sieve_variable_assign { string_t *varval; - if ( !sieve_variable_get(storage, index, &varval) ) + if ( !sieve_variable_get_modifiable(storage, index, &varval) ) return FALSE; - if ( varval == NULL ) { - varval = str_new(storage->pool, str_len(value)); - array_idx_set(&storage->var_values, index, &varval); - } - str_truncate(varval, 0); str_append_str(varval, value); @@ -315,6 +314,8 @@ bool sieve_variable_assign return TRUE; } + + /* * AST Context */ diff --git a/tests/extensions/include/errors/runtime.sieve b/tests/extensions/include/errors/runtime.sieve new file mode 100644 index 000000000..fe640b049 --- /dev/null +++ b/tests/extensions/include/errors/runtime.sieve @@ -0,0 +1,4 @@ +require "include"; +require "variables"; + +import "frop"; -- GitLab