diff --git a/TODO b/TODO index 971b040e81154db17727f4e1e5d7a44949b84aba..52f9d7d9c02d685e6f21587b0363a3a6ab960756 100644 --- a/TODO +++ b/TODO @@ -3,8 +3,8 @@ Next (in order of descending priority/precedence): * Finish the test suite for the base functionality * Improve debugging and error handling: - Variables: dump variable identifiers in stead of storage indexes - - Improve argument errors * Make sure cmusieve can be replaced seamlessly with the new plugin. + - Fileinto must optionally create missing folders. * Fix/Report issues listed in 'doc/rfc/RFC Controversy.txt' * ## MAKE A FIRST RELEASE (0.1.x) ## diff --git a/src/lib-sieve/cmd-redirect.c b/src/lib-sieve/cmd-redirect.c index 3adfee6c2dbbc07ca708bb53dc445ac6b4ad7812..5f6393bcc6925a97764607fa5d536e55af23ac6a 100644 --- a/src/lib-sieve/cmd-redirect.c +++ b/src/lib-sieve/cmd-redirect.c @@ -131,7 +131,7 @@ static bool cmd_redirect_validate norm_address = sieve_address_normalize(address, &error); if ( norm_address == NULL ) { - sieve_command_validate_error(validator, cmd, + sieve_argument_validate_error(validator, arg, "specified redirect address '%s' is invalid: %s", str_sanitize(str_c(address),128), error); } else { diff --git a/src/lib-sieve/cmd-require.c b/src/lib-sieve/cmd-require.c index f6d25a3a7529ef451145b54c852b69dfd5a0a4ce..bd7ae1bb9be0828c1f85273a636465913eb515ae 100644 --- a/src/lib-sieve/cmd-require.c +++ b/src/lib-sieve/cmd-require.c @@ -75,7 +75,7 @@ static bool cmd_require_validate } } else { /* Something else */ - sieve_command_validate_error(validator, cmd, + sieve_argument_validate_error(validator, arg, "the require command accepts a single string or string list argument, " "but %s was found", sieve_ast_argument_name(arg)); diff --git a/src/lib-sieve/ext-encoded-character.c b/src/lib-sieve/ext-encoded-character.c index 85532885ef7507a3fd36db97218e5c03e46e58c8..2eb6a0552681dbab64285a0fa0b43171fbcdedc6 100644 --- a/src/lib-sieve/ext-encoded-character.c +++ b/src/lib-sieve/ext-encoded-character.c @@ -234,7 +234,7 @@ bool arg_encoded_string_validate /* We now know that the substitution is valid */ if ( error_hex != 0 ) { - sieve_command_validate_error(validator, cmd, + sieve_argument_validate_error(validator, *arg, "invalid unicode character 0x%08x in encoded character substitution", error_hex); result = FALSE; diff --git a/src/lib-sieve/ext-envelope.c b/src/lib-sieve/ext-envelope.c index 7abd09a80b943b70c200be18654f3b7008d86898..f4d59daf31ebf4fe12edeaa7c65033d92d49a0be 100644 --- a/src/lib-sieve/ext-envelope.c +++ b/src/lib-sieve/ext-envelope.c @@ -250,7 +250,7 @@ static bool tst_envelope_validate if ( !sieve_ast_stringlist_map(&epart, (void *) ¬_address, _envelope_part_is_supported) ) { - sieve_command_validate_error(validator, tst, + sieve_argument_validate_error(validator, epart, "specified envelope part '%s' is not supported by the envelope test", str_sanitize(sieve_ast_strlist_strc(epart), 64)); return FALSE; @@ -261,7 +261,7 @@ static bool tst_envelope_validate sieve_command_find_argument(tst, &address_part_tag); if ( addrp_arg != NULL ) { - sieve_command_validate_error(validator, tst, + sieve_argument_validate_error(validator, addrp_arg, "address part ':%s' specified while non-address envelope part '%s' " "is tested with the envelope test", sieve_ast_argument_tag(addrp_arg), not_address->identifier); diff --git a/src/lib-sieve/plugins/body/tst-body.c b/src/lib-sieve/plugins/body/tst-body.c index 9b3c1ed579d1ead31257ea73ddee60116d7639dc..aad6b11ec1c8896ad33c658154c47169bbf56e2e 100644 --- a/src/lib-sieve/plugins/body/tst-body.c +++ b/src/lib-sieve/plugins/body/tst-body.c @@ -134,7 +134,7 @@ static bool tag_body_transform_validate * / :text */ if ( (bool) cmd->data ) { - sieve_command_validate_error(validator, cmd, + sieve_argument_validate_error(validator, *arg, "the :raw, :content and :text arguments for the body test are mutually " "exclusive, but more than one was specified"); return FALSE; diff --git a/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c b/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c index bf45d62aee951754dfb0a1278748556b4c19b6e7..1196a850af1747903818d715212cebbf08c2bd30 100644 --- a/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c +++ b/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c @@ -54,7 +54,7 @@ bool ext_imapflags_command_validate if ( sieve_ast_argument_type(arg) != SAAT_STRING && sieve_ast_argument_type(arg) != SAAT_STRING_LIST ) { - sieve_command_validate_error(validator, cmd, + sieve_argument_validate_error(validator, arg, "the %s %s expects either a string (variable name) or " "a string-list (list of flags) as first argument, but %s was found", cmd->command->identifier, sieve_command_type_name(cmd->command), @@ -70,14 +70,14 @@ bool ext_imapflags_command_validate { if ( cmd->command == &tst_hasflag ) { if ( sieve_ast_argument_type(arg) != SAAT_STRING_LIST ) { - sieve_command_validate_error(validator, cmd, + sieve_argument_validate_error(validator, arg, "if a second argument is specified for the hasflag, the first " "must be a string-list (variable-list), but %s was found", sieve_ast_argument_name(arg)); return FALSE; } } else { - sieve_command_validate_error(validator, cmd, + sieve_argument_validate_error(validator, arg, "if a second argument is specified for the %s %s, the first " "must be a string (variable name), but %s was found", cmd->command->identifier, sieve_command_type_name(cmd->command), @@ -89,7 +89,7 @@ bool ext_imapflags_command_validate /* Then, check whether the second argument is permitted */ if ( !sieve_ext_variables_is_active(validator) ) { - sieve_command_validate_error(validator, cmd, + sieve_argument_validate_error(validator,arg, "the %s %s only allows for the specification of a " "variable name when the variables extension is active", cmd->command->identifier, sieve_command_type_name(cmd->command)); @@ -103,7 +103,7 @@ bool ext_imapflags_command_validate if ( sieve_ast_argument_type(arg2) != SAAT_STRING && sieve_ast_argument_type(arg2) != SAAT_STRING_LIST ) { - sieve_command_validate_error(validator, cmd, + sieve_argument_validate_error(validator, arg2, "the %s %s expects a string list (list of flags) as " "second argument when two arguments are specified, " "but %s was found", @@ -126,7 +126,7 @@ bool ext_imapflags_command_validate while ( (flag=ext_imapflags_iter_get_flag(&fiter)) != NULL ) { if ( !flag_is_valid(flag) ) { - sieve_command_validate_warning(validator, cmd, + sieve_argument_validate_warning(validator, arg, "IMAP flag '%s' specified for the %s command is invalid " "and will be ignored (only first invalid is reported)", str_sanitize(flag, 64), cmd->command->identifier); diff --git a/src/lib-sieve/plugins/include/cmd-import.c b/src/lib-sieve/plugins/include/cmd-import.c index cacab7da64f95298bd7920f28084c2745a55c48a..bc1e9376c5f4afca628c6bda32f8d6c23b02a098 100644 --- a/src/lib-sieve/plugins/include/cmd-import.c +++ b/src/lib-sieve/plugins/include/cmd-import.c @@ -150,7 +150,7 @@ static bool cmd_import_validate } } else { /* Something else */ - sieve_command_validate_error(validator, cmd, + sieve_argument_validate_error(validator, arg, "the %s command accepts a single string or string list argument, " "but %s was found", cmd->command->identifier, sieve_ast_argument_name(arg)); @@ -164,6 +164,7 @@ static bool cmd_import_validate (prev_context->first_positional, cmd->first_positional); if ( prev_context->first_positional == NULL ) { + /* Not going to happen unless MAXINT stringlist items are specified */ sieve_command_validate_error(validator, cmd, "compiler reached AST limit (script too complex)"); return FALSE; @@ -194,8 +195,8 @@ static bool cmd_import_generate /* Single string */ struct sieve_variable *var = (struct sieve_variable *) arg->context; - (void)sieve_binary_emit_integer(cgenv->sbin, 1); - (void)sieve_binary_emit_integer(cgenv->sbin, var->index); + (void)sieve_binary_emit_unsigned(cgenv->sbin, 1); + (void)sieve_binary_emit_unsigned(cgenv->sbin, var->index); if ( cmd->command == &cmd_import ) (void)sieve_code_source_line_emit(cgenv->sbin, arg->source_line); @@ -203,12 +204,12 @@ static bool cmd_import_generate /* String list */ struct sieve_ast_argument *stritem = sieve_ast_strlist_first(arg); - (void)sieve_binary_emit_integer(cgenv->sbin, sieve_ast_strlist_count(arg)); + (void)sieve_binary_emit_unsigned(cgenv->sbin, sieve_ast_strlist_count(arg)); while ( stritem != NULL ) { struct sieve_variable *var = (struct sieve_variable *) stritem->context; - (void)sieve_binary_emit_integer(cgenv->sbin, var->index); + (void)sieve_binary_emit_unsigned(cgenv->sbin, var->index); if ( cmd->command == &cmd_import ) (void)sieve_code_source_line_emit(cgenv->sbin, stritem->source_line); @@ -234,7 +235,7 @@ static bool opc_import_dump struct sieve_variable_scope *scope; struct sieve_variable * const *vars; - if ( !sieve_binary_read_integer(denv->sbin, address, &count) ) + if ( !sieve_binary_read_unsigned(denv->sbin, address, &count) ) return FALSE; if ( op == &import_operation ) @@ -251,7 +252,7 @@ static bool opc_import_dump unsigned int index; sieve_code_mark(denv); - if ( !sieve_binary_read_integer(denv->sbin, address, &index) || + if ( !sieve_binary_read_unsigned(denv->sbin, address, &index) || index >= var_count ) return FALSE; @@ -284,7 +285,7 @@ static int opc_import_execute struct sieve_variable * const *vars; unsigned int var_count, count, i; - if ( !sieve_binary_read_integer(renv->sbin, address, &count) ) { + if ( !sieve_binary_read_unsigned(renv->sbin, address, &count) ) { sieve_runtime_trace_error(renv, "invalid count operand"); return SIEVE_EXEC_BIN_CORRUPT; } @@ -296,13 +297,14 @@ static int opc_import_execute for ( i = 0; i < count; i++ ) { unsigned int index, source_line; - if ( !sieve_binary_read_integer(renv->sbin, address, &index) ) { + if ( !sieve_binary_read_unsigned(renv->sbin, address, &index) ) { sieve_runtime_trace_error(renv, "invalid global variable operand"); return SIEVE_EXEC_BIN_CORRUPT; } if ( index >= var_count ) { - sieve_runtime_trace_error(renv, "invalid global variable index"); + sieve_runtime_trace_error(renv, "invalid global variable index (%u > %u)", + index, var_count); return SIEVE_EXEC_BIN_CORRUPT; } diff --git a/src/lib-sieve/plugins/include/cmd-include.c b/src/lib-sieve/plugins/include/cmd-include.c index f76bf90a474b69ee15cdd22008738840d9d5fa91..ca1a329e2997953a3c80dcaf10ba2168114f27c7 100644 --- a/src/lib-sieve/plugins/include/cmd-include.c +++ b/src/lib-sieve/plugins/include/cmd-include.c @@ -113,7 +113,7 @@ static bool cmd_include_validate_location_tag (struct cmd_include_context_data *) cmd->data; if ( ctx_data->location_assigned) { - sieve_command_validate_error(validator, cmd, + sieve_argument_validate_error(validator, *arg, "include: cannot use location tags ':personal' and ':global' " "multiple times"); return FALSE; @@ -186,7 +186,7 @@ static bool cmd_include_validate(struct sieve_validator *validator, script_name = sieve_ast_argument_strc(arg); if ( strchr(script_name, '/') != NULL ) { - sieve_command_validate_error(validator, cmd, + sieve_argument_validate_error(validator, arg, "include: '/' not allowed in script name (%s)", str_sanitize(script_name, 80)); return FALSE; @@ -195,7 +195,7 @@ static bool cmd_include_validate(struct sieve_validator *validator, script_dir = ext_include_get_script_directory (ctx_data->location, script_name); if ( script_dir == NULL ) { - sieve_command_validate_error(validator, cmd, + sieve_argument_validate_error(validator, arg, "include: specified location for included script '%s' is unavailable " "(system logs should provide more information)", str_sanitize(script_name, 80)); @@ -235,7 +235,7 @@ static bool cmd_include_generate return FALSE; (void)sieve_operation_emit_code(cgenv->sbin, &include_operation); - (void)sieve_binary_emit_integer(cgenv->sbin, included->id); + (void)sieve_binary_emit_unsigned(cgenv->sbin, included->id); return TRUE; } @@ -255,7 +255,7 @@ static bool opc_include_dump sieve_code_dumpf(denv, "INCLUDE:"); sieve_code_mark(denv); - if ( !sieve_binary_read_integer(denv->sbin, address, &include_id) ) + if ( !sieve_binary_read_unsigned(denv->sbin, address, &include_id) ) return FALSE; binctx = ext_include_binary_get_context(denv->sbin); @@ -280,7 +280,7 @@ static int opc_include_execute { unsigned int include_id; - if ( !sieve_binary_read_integer(renv->sbin, address, &include_id) ) { + if ( !sieve_binary_read_unsigned(renv->sbin, address, &include_id) ) { sieve_runtime_trace_error(renv, "invalid include-id operand"); return SIEVE_EXEC_BIN_CORRUPT; } diff --git a/src/lib-sieve/plugins/include/ext-include-binary.c b/src/lib-sieve/plugins/include/ext-include-binary.c index cf1b4bc5246cf75b829a2cee2c6779db90ee4659..34e759a52ceb41bfe348fc225f31a8b0738fc6b0 100644 --- a/src/lib-sieve/plugins/include/ext-include-binary.c +++ b/src/lib-sieve/plugins/include/ext-include-binary.c @@ -207,12 +207,12 @@ static bool ext_include_binary_save(struct sieve_binary *sbin) scripts = array_get(&binctx->include_index, &script_count); - sieve_binary_emit_integer(sbin, script_count); + sieve_binary_emit_unsigned(sbin, script_count); for ( i = 0; i < script_count; i++ ) { struct ext_include_script_info *incscript = scripts[i]; - sieve_binary_emit_integer(sbin, incscript->block_id); + sieve_binary_emit_unsigned(sbin, incscript->block_id); sieve_binary_emit_byte(sbin, incscript->location); sieve_binary_emit_cstring(sbin, sieve_script_name(incscript->script)); } @@ -237,7 +237,7 @@ static bool ext_include_binary_open(struct sieve_binary *sbin) offset = 0; - if ( !sieve_binary_read_integer(sbin, &offset, &depcount) ) { + if ( !sieve_binary_read_unsigned(sbin, &offset, &depcount) ) { sieve_sys_error("include: failed to read include count " "for dependency block %d of binary %s", block, sieve_binary_path(sbin)); return FALSE; @@ -261,7 +261,7 @@ static bool ext_include_binary_open(struct sieve_binary *sbin) struct sieve_script *script; if ( - !sieve_binary_read_integer(sbin, &offset, &block_id) || + !sieve_binary_read_unsigned(sbin, &offset, &block_id) || !sieve_binary_read_byte(sbin, &offset, &location) || !sieve_binary_read_string(sbin, &offset, &script_name) ) { /* Binary is corrupt, recompile */ diff --git a/src/lib-sieve/plugins/include/ext-include-variables.c b/src/lib-sieve/plugins/include/ext-include-variables.c index 6726fc8130e4c48e50eb3ca9ff886cf2770c3b9f..bae0048063e9b43fd6a058fc467d8d312850fe8b 100644 --- a/src/lib-sieve/plugins/include/ext-include-variables.c +++ b/src/lib-sieve/plugins/include/ext-include-variables.c @@ -124,7 +124,7 @@ bool ext_include_variables_save { unsigned int count = sieve_variable_scope_size(global_vars); - sieve_binary_emit_integer(sbin, count); + sieve_binary_emit_unsigned(sbin, count); if ( count > 0 ) { unsigned int size, i; @@ -149,14 +149,14 @@ bool ext_include_variables_load (struct sieve_binary *sbin, sieve_size_t *offset, unsigned int block, struct sieve_variable_scope **global_vars_r) { - sieve_size_t count = 0; + unsigned int count = 0; unsigned int i; pool_t pool; /* Sanity assert */ i_assert( *global_vars_r == NULL ); - if ( !sieve_binary_read_integer(sbin, offset, &count) ) { + if ( !sieve_binary_read_unsigned(sbin, offset, &count) ) { sieve_sys_error("include: failed to read global variables count " "from dependency block %d of binary %s", block, sieve_binary_path(sbin)); return FALSE; diff --git a/src/lib-sieve/plugins/regex/mcht-regex.c b/src/lib-sieve/plugins/regex/mcht-regex.c index cd4b41b44afcebc46278e158880fc96ee350d7eb..77536621db0044fe97433fbc315e1d0643be24a6 100644 --- a/src/lib-sieve/plugins/regex/mcht-regex.c +++ b/src/lib-sieve/plugins/regex/mcht-regex.c @@ -85,14 +85,15 @@ static const char *_regexp_error(regex_t *regexp, int errorcode) } static int mcht_regex_validate_regexp -(struct sieve_validator *validator, struct sieve_match_type_context *ctx, +(struct sieve_validator *validator, + struct sieve_match_type_context *ctx ATTR_UNUSED, struct sieve_ast_argument *key, int cflags) { int ret; regex_t regexp; if ( (ret=regcomp(®exp, sieve_ast_argument_strc(key), cflags)) != 0 ) { - sieve_command_validate_error(validator, ctx->command_ctx, + sieve_argument_validate_error(validator, key, "invalid regular expression for regex match: %s", _regexp_error(®exp, ret)); @@ -116,7 +117,7 @@ static int mcht_regex_validate_key_argument struct _regex_key_context *keyctx = (struct _regex_key_context *) context; if ( !sieve_argument_is_string_literal(key) ) { - sieve_command_validate_error(keyctx->valdtr, keyctx->mctx->command_ctx, + sieve_argument_validate_error(keyctx->valdtr, key, "this sieve implementation currently does not accept variable strings " "as regular expression"); return FALSE; @@ -141,7 +142,7 @@ bool mcht_regex_validate_context else if ( cmp == &i_octet_comparator ) cflags = REG_EXTENDED | REG_NOSUB; else { - sieve_command_validate_error(validator, ctx->command_ctx, + sieve_argument_validate_error(validator, ctx->match_type_arg, "regex match type only supports " "i;octet and i;ascii-casemap comparators" ); return FALSE; diff --git a/src/lib-sieve/plugins/relational/ext-relational-common.c b/src/lib-sieve/plugins/relational/ext-relational-common.c index 88c80a0db3c3003e215150c7f4ccfaebe1070ac6..92c6dc39697054afe4862271982459a5bf13361e 100644 --- a/src/lib-sieve/plugins/relational/ext-relational-common.c +++ b/src/lib-sieve/plugins/relational/ext-relational-common.c @@ -52,7 +52,7 @@ bool mcht_relational_validate /* Did we get a string in the first place ? */ if ( (*arg)->type != SAAT_STRING ) { - sieve_command_validate_error(validator, ctx->command_ctx, + sieve_argument_validate_error(validator, *arg, "the :%s match-type requires a constant string argument being " "one of \"gt\", \"ge\", \"lt\", \"le\", \"eq\" or \"ne\", " "but %s was found", @@ -114,7 +114,7 @@ bool mcht_relational_validate } if ( rel_match >= REL_MATCH_INVALID ) { - sieve_command_validate_error(validator, ctx->command_ctx, + sieve_argument_validate_error(validator, *arg, "the :%s match-type requires a constant string argument being " "one of \"gt\", \"ge\", \"lt\", \"le\", \"eq\" or \"ne\", " "but \"%s\" was found", diff --git a/src/lib-sieve/plugins/relational/mcht-count.c b/src/lib-sieve/plugins/relational/mcht-count.c index 0616488275312fe5fe9ec7323468c88cb615f563..fcc8f25238c4b9fba9caf89f938747cd34256a95 100644 --- a/src/lib-sieve/plugins/relational/mcht-count.c +++ b/src/lib-sieve/plugins/relational/mcht-count.c @@ -65,9 +65,16 @@ COUNT_MATCH_TYPE(ne, REL_MATCH_NOT_EQUAL); * Match-type implementation */ +struct mcht_count_context { + unsigned int count; +}; + static void mcht_count_match_init(struct sieve_match_context *mctx) { - mctx->data = (void *) 0; + struct mcht_count_context *cctx = t_new(struct mcht_count_context, 1); + + cctx->count = 0; + mctx->data = (void *) cctx; } static int mcht_count_match @@ -81,7 +88,10 @@ static int mcht_count_match /* Count values */ if ( key_index == -1 ) { - mctx->data = (void *) (((int) mctx->data) + 1); + struct mcht_count_context *cctx = + (struct mcht_count_context *) mctx->data; + + cctx->count++; } return FALSE; @@ -89,14 +99,15 @@ static int mcht_count_match static int mcht_count_match_deinit(struct sieve_match_context *mctx) { - unsigned int val_count = (unsigned int) mctx->data; + struct mcht_count_context *cctx = + (struct mcht_count_context *) mctx->data; int key_index; string_t *key_item; sieve_coded_stringlist_reset(mctx->key_list); bool ok = TRUE; string_t *value = t_str_new(20); - str_printfa(value, "%d", val_count); + str_printfa(value, "%d", cctx->count); /* Match to all key values */ key_index = 0; diff --git a/src/lib-sieve/plugins/vacation/cmd-vacation.c b/src/lib-sieve/plugins/vacation/cmd-vacation.c index 5ee5257faee996853f5925591c3f3743ce9bb140..57c3343ce73e6452f929c6e2232768ea6b920244 100644 --- a/src/lib-sieve/plugins/vacation/cmd-vacation.c +++ b/src/lib-sieve/plugins/vacation/cmd-vacation.c @@ -198,7 +198,7 @@ const struct sieve_action act_vacation = { struct act_vacation_context { const char *reason; - sieve_size_t days; + sieve_number_t days; const char *subject; const char *handle; bool mime; @@ -282,7 +282,7 @@ static bool cmd_vacation_validate_string_tag result = sieve_address_validate(address, &error); if ( !result ) { - sieve_command_validate_error(validator, cmd, + sieve_argument_validate_error(validator, *arg, "specified :from address '%s' is invalid for vacation action: %s", str_sanitize(str_c(address), 128), error); } @@ -542,7 +542,7 @@ static int ext_vacation_operation_execute struct act_vacation_context *act; pool_t pool; int opt_code = 1; - sieve_size_t days = 7; + sieve_number_t days = 7; bool mime = FALSE; struct sieve_coded_stringlist *addresses = NULL; string_t *reason, *subject = NULL, *from = NULL, *handle = NULL; diff --git a/src/lib-sieve/plugins/variables/cmd-set.c b/src/lib-sieve/plugins/variables/cmd-set.c index 084d4bc0596a9a3c54a4edd13ebd6eea2317e4a0..759f9d2c8935aa250c9dd84749c7e96a66c2095d 100644 --- a/src/lib-sieve/plugins/variables/cmd-set.c +++ b/src/lib-sieve/plugins/variables/cmd-set.c @@ -133,7 +133,7 @@ static bool tag_modifier_validate array_idx(&sctx->modifiers, i); if ( (*smdf)->precedence == modf->precedence ) { - sieve_command_validate_error(validator, cmd, + sieve_argument_validate_error(validator, *arg, "modifiers :%s and :%s specified for the set command conflict " "having equal precedence", (*smdf)->object.identifier, modf->object.identifier); diff --git a/src/lib-sieve/plugins/variables/ext-variables-arguments.c b/src/lib-sieve/plugins/variables/ext-variables-arguments.c index 9cdebcf3070994b820eb4e73ec66c26183873ffc..67ff4fbed4e9817125012de49fd2d7e238749bce 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-arguments.c +++ b/src/lib-sieve/plugins/variables/ext-variables-arguments.c @@ -25,20 +25,20 @@ */ static inline void _ext_variables_scope_size_error -(struct sieve_validator *valdtr, struct sieve_command_context *cmd, +(struct sieve_validator *valdtr, struct sieve_ast_argument *arg, const char *variable) { - sieve_command_validate_error(valdtr, cmd, + sieve_argument_validate_error(valdtr, arg, "(implicit) declaration of new variable '%s' exceeds the limit " "(max variables: %u)", variable, SIEVE_VARIABLES_MAX_SCOPE_SIZE); } static inline void _ext_variables_match_index_error -(struct sieve_validator *valdtr, struct sieve_command_context *cmd, +(struct sieve_validator *valdtr, struct sieve_ast_argument *arg, unsigned int variable_index) { - sieve_command_validate_error(valdtr, cmd, + sieve_argument_validate_error(valdtr, arg, "match value index %u out of range (max: %u)", variable_index, SIEVE_VARIABLES_MAX_MATCH_INDEX); } @@ -78,7 +78,7 @@ static struct sieve_ast_argument *ext_variables_variable_argument_create } static bool _sieve_variable_argument_activate -(struct sieve_validator *validator, struct sieve_command_context *cmd, +(struct sieve_validator *validator, struct sieve_command_context *cmd ATTR_UNUSED, struct sieve_ast_argument *arg, bool assignment) { bool result = FALSE; @@ -99,7 +99,7 @@ static bool _sieve_variable_argument_activate /* Check whether name parsing succeeded */ if ( nelements < 0 || varstr != varend ) { /* Parse failed */ - sieve_command_validate_error(validator, cmd, + sieve_argument_validate_error(validator, arg, "invalid variable name '%s'", str_sanitize(str_c(variable),80)); } else if ( nelements == 1 ) { /* Normal (match) variable */ @@ -114,7 +114,7 @@ static bool _sieve_variable_argument_activate if ( var == NULL ) { _ext_variables_scope_size_error - (validator, cmd, str_c(cur_element->identifier)); + (validator, arg, str_c(cur_element->identifier)); } else { arg->argument = &variable_argument; arg->context = (void *) var; @@ -126,15 +126,15 @@ static bool _sieve_variable_argument_activate if ( !assignment ) { if ( cur_element->num_variable > SIEVE_VARIABLES_MAX_MATCH_INDEX ) { _ext_variables_match_index_error - (validator, cmd, cur_element->num_variable); + (validator, arg, cur_element->num_variable); } else { arg->argument = &match_value_argument; - arg->context = (void *) cur_element->num_variable; + arg->context = POINTER_CAST(cur_element->num_variable); result = TRUE; } } else { - sieve_command_validate_error(validator, cmd, + sieve_argument_validate_error(validator, arg, "cannot assign to match variable"); } } @@ -150,7 +150,7 @@ static bool _sieve_variable_argument_activate * the relevant extension MUST cause an error. */ - sieve_command_validate_error(validator, cmd, + sieve_argument_validate_error(validator, arg, "cannot %s to variable in unknown namespace '%s'", assignment ? "assign" : "refer", str_c(cur_element->identifier)); } @@ -180,6 +180,7 @@ bool sieve_variable_argument_activate return FALSE; stritem = sieve_ast_strlist_next(stritem); + } arg->argument = &string_list_argument; @@ -224,7 +225,7 @@ static struct sieve_ast_argument *ext_variables_match_value_argument_create arg = sieve_ast_argument_create(ast, source_line); arg->type = SAAT_STRING; arg->argument = &match_value_argument; - arg->context = (void *) index; + arg->context = POINTER_CAST(index); return arg; } @@ -233,7 +234,7 @@ static bool arg_match_value_generate (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, struct sieve_command_context *context ATTR_UNUSED) { - unsigned int index = (unsigned int) arg->context; + unsigned int index = POINTER_CAST_TO(arg->context, unsigned int); ext_variables_opr_match_value_emit(cgenv->sbin, index); @@ -374,7 +375,7 @@ static bool arg_variable_string_validate sieve_ast_arg_list_add(arglist, strarg); else { _ext_variables_scope_size_error - (validator, cmd, str_c(cur_element->identifier)); + (validator, *arg, str_c(cur_element->identifier)); result = FALSE; break; } @@ -382,7 +383,7 @@ static bool arg_variable_string_validate /* Add match value argument '${000}' */ if ( cur_element->num_variable > SIEVE_VARIABLES_MAX_MATCH_INDEX ) { _ext_variables_match_index_error - (validator, cmd, cur_element->num_variable); + (validator, *arg, cur_element->num_variable); result = FALSE; break; } @@ -402,7 +403,7 @@ static bool arg_variable_string_validate /* References to namespaces without a prior require * statement for thecrelevant extension MUST cause an error. */ - sieve_command_validate_error(validator, cmd, + sieve_argument_validate_error(validator, *arg, "referring to variable in unknown namespace '%s'", str_c(cur_element->identifier)); result = FALSE; diff --git a/src/lib-sieve/plugins/variables/ext-variables-common.c b/src/lib-sieve/plugins/variables/ext-variables-common.c index f54a132e77ad13d0a72514bcbf41ff8ca9651797..f5bf51f288540bd50da909ccc9bb7bd2fd6ea519 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-common.c +++ b/src/lib-sieve/plugins/variables/ext-variables-common.c @@ -409,7 +409,7 @@ bool ext_variables_generator_load(const struct sieve_codegen_env *cgenv) unsigned int count = sieve_variable_scope_size(main_scope); sieve_size_t jump; - sieve_binary_emit_integer(cgenv->sbin, count); + sieve_binary_emit_unsigned(cgenv->sbin, count); jump = sieve_binary_emit_offset(cgenv->sbin, 0); @@ -440,15 +440,15 @@ bool ext_variables_code_dump int end_offset; sieve_code_mark(denv); - if ( !sieve_binary_read_integer(denv->sbin, address, &scope_size) ) + if ( !sieve_binary_read_unsigned(denv->sbin, address, &scope_size) ) return FALSE; pc = *address; if ( !sieve_binary_read_offset(denv->sbin, address, &end_offset) ) return FALSE; - sieve_code_dumpf(denv, "SCOPE [%d] (end: %08x)", - scope_size, pc + end_offset); + sieve_code_dumpf(denv, "SCOPE [%u] (end: %08x)", + scope_size, (unsigned int) (pc + end_offset)); /* Read global variable scope */ for ( i = 0; i < scope_size; i++ ) { @@ -500,7 +500,7 @@ bool ext_variables_interpreter_load sieve_size_t pc; int end_offset; - if ( !sieve_binary_read_integer(renv->sbin, address, &scope_size) ) { + if ( !sieve_binary_read_unsigned(renv->sbin, address, &scope_size) ) { sieve_sys_error("variables: failed to read main scope size"); return FALSE; } diff --git a/src/lib-sieve/plugins/variables/ext-variables-modifiers.c b/src/lib-sieve/plugins/variables/ext-variables-modifiers.c index 9713122e9b9654c2fc06e3c3eec9979cd9b0357f..98fbb5ffc2f83816dadd77c8cd0aff13d208fc98 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-modifiers.c +++ b/src/lib-sieve/plugins/variables/ext-variables-modifiers.c @@ -209,7 +209,7 @@ bool mod_lower_modify(string_t *in, string_t **result) bool mod_length_modify(string_t *in, string_t **result) { *result = t_str_new(64); - str_printfa(*result, "%d", str_len(in)); + str_printfa(*result, "%llu", (unsigned long long) str_len(in)); return TRUE; } diff --git a/src/lib-sieve/plugins/variables/ext-variables-operands.c b/src/lib-sieve/plugins/variables/ext-variables-operands.c index c551bcd0db942b62cd80de65e991194450037695..7b303999fed62e627dce32b2a693fd50c62bcc26 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-operands.c +++ b/src/lib-sieve/plugins/variables/ext-variables-operands.c @@ -52,27 +52,27 @@ void ext_variables_opr_variable_emit /* Default variable storage */ (void) sieve_operand_emit_code(sbin, &variable_operand); (void) sieve_binary_emit_byte(sbin, 0); - (void) sieve_binary_emit_integer(sbin, var->index); + (void) sieve_binary_emit_unsigned(sbin, var->index); return; } (void) sieve_operand_emit_code(sbin, &variable_operand); (void) sieve_binary_emit_extension(sbin, var->ext, 1); - (void) sieve_binary_emit_integer(sbin, var->index); + (void) sieve_binary_emit_unsigned(sbin, var->index); } static bool opr_variable_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address, const char *field_name) { - sieve_size_t index = 0; + unsigned int index = 0; const struct sieve_extension *ext; unsigned int code = 1; /* Initially set to offset value */ if ( !sieve_binary_read_extension(denv->sbin, address, &code, &ext) ) return FALSE; - if ( !sieve_binary_read_integer(denv->sbin, address, &index) ) + if ( !sieve_binary_read_unsigned(denv->sbin, address, &index) ) return FALSE; if ( ext == NULL ) { @@ -97,7 +97,7 @@ static bool opr_variable_read_value const struct sieve_extension *ext; unsigned int code = 1; /* Initially set to offset value */ struct sieve_variable_storage *storage; - sieve_size_t index = 0; + unsigned int index = 0; if ( !sieve_binary_read_extension(renv->sbin, address, &code, &ext) ) return FALSE; @@ -106,7 +106,7 @@ static bool opr_variable_read_value if ( storage == NULL ) return FALSE; - if (sieve_binary_read_integer(renv->sbin, address, &index) ) { + if (sieve_binary_read_unsigned(renv->sbin, address, &index) ) { /* Parameter str can be NULL if we are requested to only skip and not * actually read the argument. */ @@ -129,7 +129,7 @@ bool sieve_variable_operand_read_data { const struct sieve_extension *ext; unsigned int code = 1; /* Initially set to offset value */ - sieve_size_t idx = 0; + unsigned int idx = 0; if ( operand != &variable_operand ) { return FALSE; @@ -142,7 +142,7 @@ bool sieve_variable_operand_read_data if ( *storage == NULL ) return FALSE; - if ( !sieve_binary_read_integer(renv->sbin, address, &idx) ) + if ( !sieve_binary_read_unsigned(renv->sbin, address, &idx) ) return FALSE; *var_index = idx; @@ -186,20 +186,20 @@ void ext_variables_opr_match_value_emit (struct sieve_binary *sbin, unsigned int index) { (void) sieve_operand_emit_code(sbin, &match_value_operand); - (void) sieve_binary_emit_integer(sbin, index); + (void) sieve_binary_emit_unsigned(sbin, index); } static bool opr_match_value_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address, const char *field_name) { - sieve_size_t index = 0; + unsigned int index = 0; - if (sieve_binary_read_integer(denv->sbin, address, &index) ) { + if (sieve_binary_read_unsigned(denv->sbin, address, &index) ) { if ( field_name != NULL ) - sieve_code_dumpf(denv, "%s: MATCHVAL %ld", field_name, (long) index); + sieve_code_dumpf(denv, "%s: MATCHVAL %lu", field_name, (unsigned long) index); else - sieve_code_dumpf(denv, "MATCHVAL %ld", (long) index); + sieve_code_dumpf(denv, "MATCHVAL %lu", (unsigned long) index); return TRUE; } @@ -210,14 +210,14 @@ static bool opr_match_value_dump static bool opr_match_value_read (const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str) { - sieve_size_t index = 0; + unsigned int index = 0; - if (sieve_binary_read_integer(renv->sbin, address, &index) ) { + if (sieve_binary_read_unsigned(renv->sbin, address, &index) ) { /* Parameter str can be NULL if we are requested to only skip and not * actually read the argument. */ if ( str != NULL ) { - sieve_match_values_get(renv->interp, (unsigned int) index, str); + sieve_match_values_get(renv->interp, index, str); if ( *str == NULL ) *str = t_str_new(0); @@ -257,17 +257,17 @@ void ext_variables_opr_variable_string_emit (struct sieve_binary *sbin, unsigned int elements) { (void) sieve_operand_emit_code(sbin, &variable_string_operand); - (void) sieve_binary_emit_integer(sbin, elements); + (void) sieve_binary_emit_unsigned(sbin, elements); } static bool opr_variable_string_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address, const char *field_name) { - sieve_size_t elements = 0; + unsigned int elements = 0; unsigned int i; - if (!sieve_binary_read_integer(denv->sbin, address, &elements) ) + if (!sieve_binary_read_unsigned(denv->sbin, address, &elements) ) return FALSE; if ( field_name != NULL ) @@ -288,10 +288,10 @@ static bool opr_variable_string_dump static bool opr_variable_string_read (const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str) { - sieve_size_t elements = 0; + unsigned int elements = 0; unsigned int i; - if ( !sieve_binary_read_integer(renv->sbin, address, &elements) ) + if ( !sieve_binary_read_unsigned(renv->sbin, address, &elements) ) return FALSE; /* Parameter str can be NULL if we are requested to only skip and not diff --git a/src/lib-sieve/sieve-ast.c b/src/lib-sieve/sieve-ast.c index ea271fe633a74f3e5dc3b673680bf02eb52e8f80..5e57d31a02dbdd4d658dd9e58456f9665fb17499 100644 --- a/src/lib-sieve/sieve-ast.c +++ b/src/lib-sieve/sieve-ast.c @@ -177,23 +177,6 @@ void *sieve_ast_extension_get_context return reg->context; } -/* - * Error reporting - */ - -void sieve_ast_error -(struct sieve_error_handler *ehandler, sieve_error_vfunc_t vfunc, - struct sieve_ast_node *node, const char *fmt, va_list args) -{ - struct sieve_script *script = node->ast->script; - - T_BEGIN { - vfunc(ehandler, - sieve_error_script_location(script, sieve_ast_node_line(node)), - fmt, args); - } T_END; -} - /* * AST list implementations */ diff --git a/src/lib-sieve/sieve-ast.h b/src/lib-sieve/sieve-ast.h index 564bd5f8b034759785f3b70861e85d8de7b3c676..7e4b424cb1a44f5b429de82614616dc59e5b4376 100644 --- a/src/lib-sieve/sieve-ast.h +++ b/src/lib-sieve/sieve-ast.h @@ -200,12 +200,6 @@ void sieve_ast_extension_register void *sieve_ast_extension_get_context (struct sieve_ast *ast, const struct sieve_extension *ext); -/* Error reporting */ - -void sieve_ast_error -(struct sieve_error_handler *ehandler, sieve_error_vfunc_t vfunc, - struct sieve_ast_node *node, const char *fmt, va_list args); - /* * AST node manipulation */ diff --git a/src/lib-sieve/sieve-binary.c b/src/lib-sieve/sieve-binary.c index a30b9914bfa9cc407280b9d83715bdecdeb92cb6..0c48faa404d824ac4af2651c9b401581f85dcb37 100644 --- a/src/lib-sieve/sieve-binary.c +++ b/src/lib-sieve/sieve-binary.c @@ -562,14 +562,14 @@ static bool _sieve_binary_save return FALSE; ext_count = array_count(&sbin->linked_extensions); - sieve_binary_emit_integer(sbin, ext_count); + sieve_binary_emit_unsigned(sbin, ext_count); for ( i = 0; i < ext_count; i++ ) { struct sieve_binary_extension_reg * const *ext = array_idx(&sbin->linked_extensions, i); sieve_binary_emit_cstring(sbin, (*ext)->extension->name); - sieve_binary_emit_integer(sbin, (*ext)->block_id); + sieve_binary_emit_unsigned(sbin, (*ext)->block_id); } if ( !sieve_binary_block_set_active(sbin, SBIN_SYSBLOCK_MAIN_PROGRAM, NULL) ) @@ -979,14 +979,13 @@ static bool _load_block_index_record static bool _sieve_binary_load_extensions(struct sieve_binary *sbin) { sieve_size_t offset = 0; - sieve_size_t count = 0; + unsigned int i, count; bool result = TRUE; - unsigned int i; if ( !sieve_binary_block_set_active(sbin, SBIN_SYSBLOCK_EXTENSIONS, NULL) ) return FALSE; - if ( !sieve_binary_read_integer(sbin, &offset, &count) ) + if ( !sieve_binary_read_unsigned(sbin, &offset, &count) ) return FALSE; for ( i = 0; result && i < count; i++ ) { @@ -1005,7 +1004,7 @@ static bool _sieve_binary_load_extensions(struct sieve_binary *sbin) struct sieve_binary_extension_reg *ereg = NULL; (void) sieve_binary_extension_register(sbin, ext, &ereg); - if ( !sieve_binary_read_integer(sbin, &offset, &ereg->block_id) ) + if ( !sieve_binary_read_unsigned(sbin, &offset, &ereg->block_id) ) result = FALSE; } } else @@ -1471,11 +1470,11 @@ void sieve_binary_resolve_offset */ sieve_size_t sieve_binary_emit_integer -(struct sieve_binary *binary, sieve_size_t integer) +(struct sieve_binary *binary, sieve_number_t integer) { sieve_size_t address = _sieve_binary_get_code_size(binary); int i; - char buffer[sizeof(sieve_size_t) + 1]; + char buffer[sizeof(sieve_number_t) + 1]; int bufpos = sizeof(buffer) - 1; buffer[bufpos] = integer & 0x7F; @@ -1500,9 +1499,9 @@ sieve_size_t sieve_binary_emit_integer } static inline sieve_size_t sieve_binary_emit_dynamic_data - (struct sieve_binary *binary, const void *data, size_t size) + (struct sieve_binary *binary, const void *data, sieve_size_t size) { - sieve_size_t address = sieve_binary_emit_integer(binary, size); + sieve_size_t address = sieve_binary_emit_integer(binary, (sieve_number_t) size); _sieve_binary_emit_data(binary, data, size); @@ -1513,7 +1512,7 @@ sieve_size_t sieve_binary_emit_cstring (struct sieve_binary *binary, const char *str) { sieve_size_t address = sieve_binary_emit_dynamic_data - (binary, (void *) str, strlen(str)); + (binary, (void *) str, (sieve_size_t) strlen(str)); _sieve_binary_emit_byte(binary, 0); return address; @@ -1523,7 +1522,7 @@ sieve_size_t sieve_binary_emit_string (struct sieve_binary *binary, const string_t *str) { sieve_size_t address = sieve_binary_emit_dynamic_data - (binary, (void *) str_data(str), str_len(str)); + (binary, (void *) str_data(str), (sieve_size_t) str_len(str)); _sieve_binary_emit_byte(binary, 0); return address; @@ -1565,38 +1564,38 @@ void sieve_binary_emit_extension_object /* Literals */ bool sieve_binary_read_byte - (struct sieve_binary *binary, sieve_size_t *address, unsigned int *byte_val) + (struct sieve_binary *binary, sieve_size_t *address, unsigned int *byte_r) { if ( ADDR_BYTES_LEFT(binary, address) >= 1 ) { - if ( byte_val != NULL ) - *byte_val = ADDR_DATA_AT(binary, address); + if ( byte_r != NULL ) + *byte_r = ADDR_DATA_AT(binary, address); ADDR_JUMP(address, 1); return TRUE; } - *byte_val = 0; + *byte_r = 0; return FALSE; } bool sieve_binary_read_code - (struct sieve_binary *binary, sieve_size_t *address, int *code) + (struct sieve_binary *binary, sieve_size_t *address, int *code_r) { if ( ADDR_BYTES_LEFT(binary, address) >= 1 ) { - if ( code != NULL ) - *code = ADDR_CODE_AT(binary, address); + if ( code_r != NULL ) + *code_r = ADDR_CODE_AT(binary, address); ADDR_JUMP(address, 1); return TRUE; } - *code = 0; + *code_r = 0; return FALSE; } bool sieve_binary_read_offset - (struct sieve_binary *binary, sieve_size_t *address, int *offset) + (struct sieve_binary *binary, sieve_size_t *address, int *offset_r) { uint32_t offs = 0; @@ -1608,8 +1607,8 @@ bool sieve_binary_read_offset ADDR_JUMP(address, 1); } - if ( offset != NULL ) - *offset = (int) offs; + if ( offset_r != NULL ) + *offset_r = (int) offs; return TRUE; } @@ -1617,21 +1616,22 @@ bool sieve_binary_read_offset return FALSE; } +/* FIXME: might need negative numbers in the future */ bool sieve_binary_read_integer - (struct sieve_binary *binary, sieve_size_t *address, sieve_size_t *integer) + (struct sieve_binary *binary, sieve_size_t *address, sieve_number_t *int_r) { - int bits = sizeof(sieve_size_t) * 8; - *integer = 0; + int bits = sizeof(sieve_number_t) * 8; + *int_r = 0; if ( ADDR_BYTES_LEFT(binary, address) == 0 ) return FALSE; while ( (ADDR_DATA_AT(binary, address) & 0x80) > 0 ) { if ( ADDR_BYTES_LEFT(binary, address) > 0 && bits > 0) { - *integer |= ADDR_DATA_AT(binary, address) & 0x7F; + *int_r |= ADDR_DATA_AT(binary, address) & 0x7F; ADDR_JUMP(address, 1); - *integer <<= 7; + *int_r <<= 7; bits -= 7; } else { /* This is an error */ @@ -1639,7 +1639,7 @@ bool sieve_binary_read_integer } } - *integer |= ADDR_DATA_AT(binary, address) & 0x7F; + *int_r |= ADDR_DATA_AT(binary, address) & 0x7F; ADDR_JUMP(address, 1); return TRUE; @@ -1652,18 +1652,18 @@ static string_t *t_str_new_const(const char *str, size_t len) } bool sieve_binary_read_string -(struct sieve_binary *binary, sieve_size_t *address, string_t **str) +(struct sieve_binary *binary, sieve_size_t *address, string_t **str_r) { - sieve_size_t strlen = 0; + unsigned int strlen = 0; - if ( !sieve_binary_read_integer(binary, address, &strlen) ) + if ( !sieve_binary_read_unsigned(binary, address, &strlen) ) return FALSE; if ( strlen > ADDR_BYTES_LEFT(binary, address) ) return FALSE; - if ( str != NULL ) - *str = t_str_new_const(&ADDR_CODE_AT(binary, address), strlen); + if ( str_r != NULL ) + *str_r = t_str_new_const(&ADDR_CODE_AT(binary, address), strlen); ADDR_JUMP(address, strlen); if ( ADDR_CODE_AT(binary, address) != 0 ) diff --git a/src/lib-sieve/sieve-binary.h b/src/lib-sieve/sieve-binary.h index d2fd7cc565b9f734a4a123fa44cc551cc30811d3..d934c86cabd40dd4bf59cf9e8e4ed862fd265b66 100644 --- a/src/lib-sieve/sieve-binary.h +++ b/src/lib-sieve/sieve-binary.h @@ -125,12 +125,19 @@ void sieve_binary_resolve_offset /* Literal emission functions */ sieve_size_t sieve_binary_emit_integer - (struct sieve_binary *binary, sieve_size_t integer); + (struct sieve_binary *binary, sieve_number_t integer); sieve_size_t sieve_binary_emit_string (struct sieve_binary *binary, const string_t *str); sieve_size_t sieve_binary_emit_cstring (struct sieve_binary *binary, const char *str); +static inline sieve_size_t sieve_binary_emit_unsigned + (struct sieve_binary *binary, unsigned int count) +{ + return sieve_binary_emit_integer(binary, count); +} + + /* Extension emission functions */ sieve_size_t sieve_binary_emit_extension @@ -146,15 +153,28 @@ void sieve_binary_emit_extension_object /* Literals */ bool sieve_binary_read_byte - (struct sieve_binary *binary, sieve_size_t *address, unsigned int *byte_val); + (struct sieve_binary *binary, sieve_size_t *address, unsigned int *byte_r); bool sieve_binary_read_code - (struct sieve_binary *binary, sieve_size_t *address, int *code); + (struct sieve_binary *binary, sieve_size_t *address, int *code_r); bool sieve_binary_read_offset - (struct sieve_binary *binary, sieve_size_t *address, int *offset); + (struct sieve_binary *binary, sieve_size_t *address, int *offset_r); bool sieve_binary_read_integer - (struct sieve_binary *binary, sieve_size_t *address, sieve_size_t *integer); + (struct sieve_binary *binary, sieve_size_t *address, sieve_number_t *int_r); bool sieve_binary_read_string - (struct sieve_binary *binary, sieve_size_t *address, string_t **str); + (struct sieve_binary *binary, sieve_size_t *address, string_t **str_r); + +static inline bool sieve_binary_read_unsigned + (struct sieve_binary *binary, sieve_size_t *address, unsigned int *count_r) +{ + sieve_number_t integer; + + if ( !sieve_binary_read_integer(binary, address, &integer) ) + return FALSE; + + *count_r = integer; + + return TRUE; +} /* Extension */ bool sieve_binary_read_extension diff --git a/src/lib-sieve/sieve-code-dumper.c b/src/lib-sieve/sieve-code-dumper.c index ec693a05e272de9a63c2de709abb7465a515f49d..5a6f966f18e779bd769fee41d479098be6fde4f2 100644 --- a/src/lib-sieve/sieve-code-dumper.c +++ b/src/lib-sieve/sieve-code-dumper.c @@ -74,7 +74,7 @@ void sieve_code_dumpf va_list args; va_start(args, fmt); - str_printfa(outbuf, "%08x: ", cdumper->mark_address); + str_printfa(outbuf, "%08llx: ", (unsigned long long) cdumper->mark_address); while ( tab > 0 ) { str_append(outbuf, " "); @@ -178,7 +178,7 @@ void sieve_code_dumper_run(struct sieve_code_dumper *dumper) /* Load and dump extensions listed in code */ sieve_code_mark(denv); - if ( sieve_binary_read_integer(sbin, &dumper->pc, &ext_count) ) { + if ( sieve_binary_read_unsigned(sbin, &dumper->pc, &ext_count) ) { unsigned int i; sieve_code_dumpf(denv, "EXTENSIONS [%d]:", ext_count); diff --git a/src/lib-sieve/sieve-code.c b/src/lib-sieve/sieve-code.c index a77441583e7efdc750f183eb81366059403c209b..7155f987bac88b380abbbf2264ed2f028444a8f1 100644 --- a/src/lib-sieve/sieve-code.c +++ b/src/lib-sieve/sieve-code.c @@ -26,13 +26,13 @@ struct sieve_coded_stringlist { sieve_size_t start_address; sieve_size_t end_address; sieve_size_t current_offset; - int length; - int index; + unsigned int length; + unsigned int index; }; static struct sieve_coded_stringlist *sieve_coded_stringlist_create (const struct sieve_runtime_env *renv, - sieve_size_t start_address, sieve_size_t length, sieve_size_t end) + sieve_size_t start_address, unsigned int length, sieve_size_t end) { struct sieve_coded_stringlist *strlist; @@ -51,17 +51,17 @@ static struct sieve_coded_stringlist *sieve_coded_stringlist_create } bool sieve_coded_stringlist_next_item -(struct sieve_coded_stringlist *strlist, string_t **str) +(struct sieve_coded_stringlist *strlist, string_t **str_r) { sieve_size_t address; - *str = NULL; + *str_r = NULL; if ( strlist->index >= strlist->length ) return TRUE; else { address = strlist->current_offset; - if ( sieve_opr_string_read(strlist->runenv, &address, str) ) { + if ( sieve_opr_string_read(strlist->runenv, &address, str_r) ) { strlist->index++; strlist->current_offset = address; return TRUE; @@ -77,7 +77,7 @@ void sieve_coded_stringlist_reset(struct sieve_coded_stringlist *strlist) strlist->index = 0; } -int sieve_coded_stringlist_get_length +unsigned int sieve_coded_stringlist_get_length (struct sieve_coded_stringlist *strlist) { return strlist->length; @@ -123,18 +123,19 @@ bool sieve_coded_stringlist_read_all static bool sieve_coded_stringlist_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address, - sieve_size_t length, sieve_size_t end, const char *field_name) + unsigned int length, sieve_size_t end, const char *field_name) { unsigned int i; if ( end > sieve_binary_get_code_size(denv->sbin) ) return FALSE; - if ( field_name != NULL ) - sieve_code_dumpf(denv, "%s: STRLIST [%d] (end: %08x)", - field_name, length, end); + if ( field_name != NULL ) + sieve_code_dumpf(denv, "%s: STRLIST [%u] (end: %08llx)", + field_name, length, (unsigned long long) end); else - sieve_code_dumpf(denv, "STRLIST [%d] (end: %08x)", length, end); + sieve_code_dumpf(denv, "STRLIST [%u] (end: %08llx)", + length, (unsigned long long) end); sieve_code_descend(denv); @@ -160,17 +161,17 @@ static bool sieve_coded_stringlist_dump void sieve_code_source_line_emit (struct sieve_binary *sbin, unsigned int source_line) { - (void)sieve_binary_emit_integer(sbin, source_line); + (void)sieve_binary_emit_unsigned(sbin, source_line); } bool sieve_code_source_line_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address) { - sieve_size_t number = 0; + unsigned int number = 0; sieve_code_mark(denv); - if (sieve_binary_read_integer(denv->sbin, address, &number) ) { - sieve_code_dumpf(denv, "(source line: %ld)", (long) number); + if (sieve_binary_read_unsigned(denv->sbin, address, &number) ) { + sieve_code_dumpf(denv, "(source line: %lu)", (unsigned long) number); return TRUE; } @@ -180,15 +181,9 @@ bool sieve_code_source_line_dump bool sieve_code_source_line_read (const struct sieve_runtime_env *renv, sieve_size_t *address, - unsigned int *source_line) + unsigned int *source_line_r) { - sieve_size_t number; - - if ( !sieve_binary_read_integer(renv->sbin, address, &number) ) - return FALSE; - - *source_line = number; - return TRUE; + return sieve_binary_read_unsigned(renv->sbin, address, source_line_r); } /* @@ -291,7 +286,7 @@ static bool opr_number_dump const char *field_name); static bool opr_number_read (const struct sieve_runtime_env *renv, sieve_size_t *address, - sieve_size_t *number); + sieve_number_t *number_r); const struct sieve_opr_number_interface number_interface = { opr_number_dump, @@ -314,7 +309,7 @@ static bool opr_string_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address, const char *field_name); static bool opr_string_read - (const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str); + (const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str_r); const struct sieve_opr_string_interface string_interface ={ opr_string_dump, @@ -360,7 +355,7 @@ const struct sieve_operand stringlist_operand = { /* Number */ -void sieve_opr_number_emit(struct sieve_binary *sbin, sieve_size_t number) +void sieve_opr_number_emit(struct sieve_binary *sbin, sieve_number_t number) { (void) sieve_operand_emit_code(sbin, &number_operand); (void) sieve_binary_emit_integer(sbin, number); @@ -398,7 +393,7 @@ bool sieve_opr_number_dump bool sieve_opr_number_read_data (const struct sieve_runtime_env *renv, const struct sieve_operand *operand, - sieve_size_t *address, sieve_size_t *number) + sieve_size_t *address, sieve_number_t *number_r) { const struct sieve_opr_number_interface *intf; @@ -410,29 +405,29 @@ bool sieve_opr_number_read_data if ( intf->read == NULL ) return FALSE; - return intf->read(renv, address, number); + return intf->read(renv, address, number_r); } bool sieve_opr_number_read (const struct sieve_runtime_env *renv, sieve_size_t *address, - sieve_size_t *number) + sieve_number_t *number_r) { const struct sieve_operand *operand = sieve_operand_read(renv->sbin, address); - return sieve_opr_number_read_data(renv, operand, address, number); + return sieve_opr_number_read_data(renv, operand, address, number_r); } static bool opr_number_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address, const char *field_name) { - sieve_size_t number = 0; + sieve_number_t number = 0; if (sieve_binary_read_integer(denv->sbin, address, &number) ) { if ( field_name != NULL ) - sieve_code_dumpf(denv, "%s: NUM %llu", field_name, (long long) number); + sieve_code_dumpf(denv, "%s: NUM %llu", field_name, (unsigned long long) number); else - sieve_code_dumpf(denv, "NUM %llu", (long long) number); + sieve_code_dumpf(denv, "NUM %llu", (unsigned long long) number); return TRUE; } @@ -442,9 +437,9 @@ static bool opr_number_dump static bool opr_number_read (const struct sieve_runtime_env *renv, sieve_size_t *address, - sieve_size_t *number) + sieve_number_t *number_r) { - return sieve_binary_read_integer(renv->sbin, address, number); + return sieve_binary_read_integer(renv->sbin, address, number_r); } /* String */ @@ -486,21 +481,21 @@ bool sieve_opr_string_dump bool sieve_opr_string_dump_ex (const struct sieve_dumptime_env *denv, sieve_size_t *address, - const char *field_name, bool *literal) + const char *field_name, bool *literal_r) { const struct sieve_operand *operand; sieve_code_mark(denv); operand = sieve_operand_read(denv->sbin, address); - *literal = ( operand == &string_operand ); + *literal_r = ( operand == &string_operand ); return sieve_opr_string_dump_data(denv, operand, address, field_name); } bool sieve_opr_string_read_data (const struct sieve_runtime_env *renv, const struct sieve_operand *operand, - sieve_size_t *address, string_t **str) + sieve_size_t *address, string_t **str_r) { const struct sieve_opr_string_interface *intf; @@ -512,26 +507,26 @@ bool sieve_opr_string_read_data if ( intf->read == NULL ) return FALSE; - return intf->read(renv, address, str); + return intf->read(renv, address, str_r); } bool sieve_opr_string_read -(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str) +(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str_r) { const struct sieve_operand *operand = sieve_operand_read(renv->sbin, address); - return sieve_opr_string_read_data(renv, operand, address, str); + return sieve_opr_string_read_data(renv, operand, address, str_r); } bool sieve_opr_string_read_ex -(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str, - bool *literal) +(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str_r, + bool *literal_r) { const struct sieve_operand *operand = sieve_operand_read(renv->sbin, address); - *literal = ( operand == &string_operand ); + *literal_r = ( operand == &string_operand ); - return sieve_opr_string_read_data(renv, operand, address, str); + return sieve_opr_string_read_data(renv, operand, address, str_r); } static void _dump_string @@ -571,9 +566,9 @@ bool opr_string_dump } static bool opr_string_read -(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str) +(const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str_r) { - return sieve_binary_read_string(renv->sbin, address, str); + return sieve_binary_read_string(renv->sbin, address, str_r); } /* String list */ @@ -591,7 +586,7 @@ void sieve_opr_stringlist_emit_start *context = (void *) end_offset; /* Emit the length of the list */ - (void) sieve_binary_emit_integer(sbin, (int) listlen); + (void) sieve_binary_emit_unsigned(sbin, listlen); } void sieve_opr_stringlist_emit_item @@ -693,7 +688,7 @@ static bool opr_stringlist_dump { sieve_size_t pc = *address; sieve_size_t end; - sieve_size_t length = 0; + unsigned int length = 0; int end_offset; if ( !sieve_binary_read_offset(denv->sbin, address, &end_offset) ) @@ -701,7 +696,7 @@ static bool opr_stringlist_dump end = pc + end_offset; - if ( !sieve_binary_read_integer(denv->sbin, address, &length) ) + if ( !sieve_binary_read_unsigned(denv->sbin, address, &length) ) return FALSE; return sieve_coded_stringlist_dump(denv, address, length, end, field_name); @@ -713,7 +708,7 @@ static struct sieve_coded_stringlist *opr_stringlist_read struct sieve_coded_stringlist *strlist; sieve_size_t pc = *address; sieve_size_t end; - sieve_size_t length = 0; + unsigned int length = 0; int end_offset; if ( !sieve_binary_read_offset(renv->sbin, address, &end_offset) ) @@ -721,10 +716,10 @@ static struct sieve_coded_stringlist *opr_stringlist_read end = pc + end_offset; - if ( !sieve_binary_read_integer(renv->sbin, address, &length) ) - return NULL; + if ( !sieve_binary_read_unsigned(renv->sbin, address, &length) ) + return NULL; - strlist = sieve_coded_stringlist_create(renv, *address, length, end); + strlist = sieve_coded_stringlist_create(renv, *address, (unsigned int) length, end); /* Skip over the string list for now */ *address = end; diff --git a/src/lib-sieve/sieve-code.h b/src/lib-sieve/sieve-code.h index 9b8c2ccf4cf547a515444194081eeb51898ce285..9f1be317bf08e4969cf99b45fd5bad4194e073ad 100644 --- a/src/lib-sieve/sieve-code.h +++ b/src/lib-sieve/sieve-code.h @@ -18,14 +18,14 @@ struct sieve_coded_stringlist; bool sieve_coded_stringlist_next_item - (struct sieve_coded_stringlist *strlist, string_t **str); + (struct sieve_coded_stringlist *strlist, string_t **str_r); void sieve_coded_stringlist_reset (struct sieve_coded_stringlist *strlist); bool sieve_coded_stringlist_read_all (struct sieve_coded_stringlist *strlist, pool_t pool, const char * const **list_r); -int sieve_coded_stringlist_get_length +unsigned int sieve_coded_stringlist_get_length (struct sieve_coded_stringlist *strlist); sieve_size_t sieve_coded_stringlist_get_end_address (struct sieve_coded_stringlist *strlist); @@ -42,7 +42,7 @@ bool sieve_code_source_line_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address); bool sieve_code_source_line_read (const struct sieve_runtime_env *renv, sieve_size_t *address, - unsigned int *source_line); + unsigned int *source_line_r); /* * Operand object @@ -113,7 +113,7 @@ struct sieve_opr_number_interface { const char *field_name); bool (*read) (const struct sieve_runtime_env *renv, sieve_size_t *address, - sieve_size_t *number); + sieve_number_t *number_r); }; struct sieve_opr_string_interface { @@ -122,7 +122,7 @@ struct sieve_opr_string_interface { const char *field_name); bool (*read) (const struct sieve_runtime_env *renv, sieve_size_t *address, - string_t **str); + string_t **str_r); }; struct sieve_opr_stringlist_interface { @@ -139,7 +139,7 @@ struct sieve_opr_stringlist_interface { /* Number */ -void sieve_opr_number_emit(struct sieve_binary *sbin, sieve_size_t number); +void sieve_opr_number_emit(struct sieve_binary *sbin, sieve_number_t number); bool sieve_opr_number_dump_data (const struct sieve_dumptime_env *denv, const struct sieve_operand *operand, sieve_size_t *address, const char *field_name); @@ -148,10 +148,10 @@ bool sieve_opr_number_dump const char *field_name); bool sieve_opr_number_read_data (const struct sieve_runtime_env *renv, const struct sieve_operand *operand, - sieve_size_t *address, sieve_size_t *number); + sieve_size_t *address, sieve_number_t *number_r); bool sieve_opr_number_read (const struct sieve_runtime_env *renv, sieve_size_t *address, - sieve_size_t *number); + sieve_number_t *number_r); static inline bool sieve_operand_is_number (const struct sieve_operand *operand) @@ -170,15 +170,15 @@ bool sieve_opr_string_dump const char *field_name); bool sieve_opr_string_dump_ex (const struct sieve_dumptime_env *denv, sieve_size_t *address, - const char *field_name, bool *literal); + const char *field_name, bool *literal_r); bool sieve_opr_string_read_data (const struct sieve_runtime_env *renv, const struct sieve_operand *operand, - sieve_size_t *address, string_t **str); + sieve_size_t *address, string_t **str_r); bool sieve_opr_string_read - (const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str); + (const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str_r); bool sieve_opr_string_read_ex - (const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str, - bool *literal); + (const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str_r, + bool *literal_r); static inline bool sieve_operand_is_string (const struct sieve_operand *operand) diff --git a/src/lib-sieve/sieve-commands.h b/src/lib-sieve/sieve-commands.h index 07012983a02eb5c6833a01efb5789a709ef84743..c3a112762927d521e8fd1877bbad1400aac64a8e 100644 --- a/src/lib-sieve/sieve-commands.h +++ b/src/lib-sieve/sieve-commands.h @@ -31,6 +31,18 @@ struct sieve_argument { struct sieve_command_context *context); }; +/* Utility macros */ + +#define sieve_argument_is_string_literal(arg) \ + ( (arg)->argument == &string_argument ) + +/* Error handling */ + +#define sieve_argument_validate_error(validator, arg_node, ...) \ + sieve_validator_error(validator, (arg_node)->source_line, __VA_ARGS__) +#define sieve_argument_validate_warning(validator, arg_node, ...) \ + sieve_validator_warning(validator, (arg_node)->source_line, __VA_ARGS__) + /* Literal arguments */ extern const struct sieve_argument number_argument; @@ -94,26 +106,45 @@ struct sieve_command_context { void *data; }; +/* Context API */ + struct sieve_command_context *sieve_command_context_create (struct sieve_ast_node *cmd_node, const struct sieve_command *command, struct sieve_command_registration *reg); const char *sieve_command_type_name(const struct sieve_command *command); -#define sieve_argument_is_string_literal(arg) \ - ( (arg)->argument == &string_argument ) +struct sieve_command_context *sieve_command_prev_context + (struct sieve_command_context *context); +struct sieve_command_context *sieve_command_parent_context + (struct sieve_command_context *context); + +struct sieve_ast_argument *sieve_command_add_dynamic_tag + (struct sieve_command_context *cmd, const struct sieve_argument *tag, + int id_code); +struct sieve_ast_argument *sieve_command_find_argument + (struct sieve_command_context *cmd, const struct sieve_argument *argument); + +void sieve_command_exit_block_unconditionally + (struct sieve_command_context *cmd); +bool sieve_command_block_exits_unconditionally + (struct sieve_command_context *cmd); + +/* Error handling */ #define sieve_command_validate_error(validator, context, ...) \ - sieve_validator_error(validator, (context)->ast_node, __VA_ARGS__) + sieve_validator_error(validator, (context)->ast_node->source_line, __VA_ARGS__) #define sieve_command_validate_warning(validator, context, ...) \ - sieve_validator_warning(validator, (context)->ast_node, __VA_ARGS__) + sieve_validator_warning(validator, (context)->ast_node->source_line, __VA_ARGS__) #define sieve_command_validate_critical(validator, context, ...) \ - sieve_validator_critical(validator, (context)->ast_node, __VA_ARGS__) + sieve_validator_critical(validator, (context)->ast_node->source_line, __VA_ARGS__) #define sieve_command_generate_error(gentr, context, ...) \ - sieve_generator_error(gentr, (context)->ast_node, __VA_ARGS__) + sieve_generator_error(gentr, (context)->ast_node->source_line, __VA_ARGS__) #define sieve_command_generate_critical(gentr, context, ...) \ - sieve_generator_critical(gentr, (context)->ast_node, __VA_ARGS__) + sieve_generator_critical(gentr, (context)->ast_node->source_line, __VA_ARGS__) + +/* Utility macros */ #define sieve_command_pool(context) \ sieve_ast_node_pool((context)->ast_node) @@ -129,22 +160,6 @@ const char *sieve_command_type_name(const struct sieve_command *command); #define sieve_command_is_first(context) \ ( sieve_ast_node_prev((context)->ast_node) == NULL ) -struct sieve_command_context *sieve_command_prev_context - (struct sieve_command_context *context); -struct sieve_command_context *sieve_command_parent_context - (struct sieve_command_context *context); - -struct sieve_ast_argument *sieve_command_add_dynamic_tag - (struct sieve_command_context *cmd, const struct sieve_argument *tag, - int id_code); -struct sieve_ast_argument *sieve_command_find_argument - (struct sieve_command_context *cmd, const struct sieve_argument *argument); - -void sieve_command_exit_block_unconditionally - (struct sieve_command_context *cmd); -bool sieve_command_block_exits_unconditionally - (struct sieve_command_context *cmd); - /* * Core commands */ diff --git a/src/lib-sieve/sieve-comparators.c b/src/lib-sieve/sieve-comparators.c index 706b8ca64bc3d17bb091d32b64c96e8a0a6501bf..038f858928ca63cecb5c8f860dd993a049fc7b99 100644 --- a/src/lib-sieve/sieve-comparators.c +++ b/src/lib-sieve/sieve-comparators.c @@ -152,7 +152,7 @@ static bool tag_comparator_validate * ":comparator" <comparator-name: string> */ if ( (*arg)->type != SAAT_STRING ) { - sieve_command_validate_error(validator, cmd, + sieve_argument_validate_error(validator, *arg, ":comparator tag requires one string argument, but %s was found", sieve_ast_argument_name(*arg) ); return FALSE; @@ -162,7 +162,7 @@ static bool tag_comparator_validate cmp = sieve_comparator_find(validator, sieve_ast_argument_strc(*arg)); if ( cmp == NULL ) { - sieve_command_validate_error(validator, cmd, + sieve_argument_validate_error(validator, *arg, "unknown comparator '%s'", str_sanitize(sieve_ast_argument_strc(*arg),80)); diff --git a/src/lib-sieve/sieve-error.c b/src/lib-sieve/sieve-error.c index ce2a2bc7047ff40f5c88bf5609f8910c5587f84f..c43d698c1ecc599bf08a59b758130f93f12552d9 100644 --- a/src/lib-sieve/sieve-error.c +++ b/src/lib-sieve/sieve-error.c @@ -352,6 +352,8 @@ static void sieve_logfile_vprintf const char *prefix, const char *fmt, va_list args) { string_t *outbuf; + ssize_t ret = 0, remain; + const char *data; if ( ehandler->stream == NULL ) return; @@ -363,8 +365,22 @@ static void sieve_logfile_vprintf str_vprintfa(outbuf, fmt, args); str_append(outbuf, ".\n"); - o_stream_send(ehandler->stream, str_data(outbuf), str_len(outbuf)); + remain = str_len(outbuf); + data = (const char *) str_data(outbuf); + + while ( remain > 0 ) { + if ( (ret=o_stream_send(ehandler->stream, data, remain)) < 0 ) + break; + + remain -= ret; + data += ret; + } } T_END; + + if ( ret < 0 ) { + sieve_sys_error( + "o_stream_send() failed on logfile %s: %m", ehandler->logfile); + } } inline static void sieve_logfile_printf @@ -431,7 +447,7 @@ static void sieve_logfile_start(struct sieve_logfile_ehandler *ehandler) } /* Open clean logfile (overwrites existing if rename() failed earlier) */ - fd = open(ehandler->logfile, O_CREAT | O_WRONLY, 0600); + fd = open(ehandler->logfile, O_CREAT | O_WRONLY | O_TRUNC, 0600); if (fd == -1) { sieve_sys_error("failed to open logfile %s (logging to STDERR): %m", ehandler->logfile); diff --git a/src/lib-sieve/sieve-generator.c b/src/lib-sieve/sieve-generator.c index fb5cf2c93bd29ff0e8c3cbd272de382340936113..1db9d9b1dc6c3e7c478e980ba3e361fa3185b3b3 100644 --- a/src/lib-sieve/sieve-generator.c +++ b/src/lib-sieve/sieve-generator.c @@ -141,35 +141,41 @@ struct sieve_binary *sieve_generator_get_binary */ void sieve_generator_warning -(struct sieve_generator *gentr, struct sieve_ast_node *node, +(struct sieve_generator *gentr, unsigned int source_line, const char *fmt, ...) { va_list args; va_start(args, fmt); - sieve_ast_error(gentr->ehandler, sieve_vwarning, node, fmt, args); + sieve_vwarning(gentr->ehandler, + sieve_error_script_location(gentr->genenv.script, source_line), + fmt, args); va_end(args); } void sieve_generator_error -(struct sieve_generator *gentr, struct sieve_ast_node *node, +(struct sieve_generator *gentr, unsigned int source_line, const char *fmt, ...) { va_list args; va_start(args, fmt); - sieve_ast_error(gentr->ehandler, sieve_verror, node, fmt, args); + sieve_verror(gentr->ehandler, + sieve_error_script_location(gentr->genenv.script, source_line), + fmt, args); va_end(args); } void sieve_generator_critical -(struct sieve_generator *gentr, struct sieve_ast_node *node, +(struct sieve_generator *gentr, unsigned int source_line, const char *fmt, ...) { va_list args; va_start(args, fmt); - sieve_ast_error(gentr->ehandler, sieve_vcritical, node, fmt, args); + sieve_vwarning(gentr->ehandler, + sieve_error_script_location(gentr->genenv.script, source_line), + fmt, args); va_end(args); } @@ -376,7 +382,7 @@ bool sieve_generator_run /* Load extensions linked to the AST and emit a list in code */ extensions = sieve_ast_extensions_get(gentr->genenv.ast, &ext_count); - (void) sieve_binary_emit_integer(*sbin, ext_count); + (void) sieve_binary_emit_unsigned(*sbin, ext_count); for ( i = 0; i < ext_count; i++ ) { const struct sieve_extension *ext = extensions[i]; diff --git a/src/lib-sieve/sieve-generator.h b/src/lib-sieve/sieve-generator.h index 5ab6f651a1191e6f9da69685b6616dc9f2a1ce11..bc7921b46b62e19d6fe751ca2ce3f6428fc3f665 100644 --- a/src/lib-sieve/sieve-generator.h +++ b/src/lib-sieve/sieve-generator.h @@ -41,13 +41,13 @@ struct sieve_binary *sieve_generator_get_binary */ void sieve_generator_warning -(struct sieve_generator *gentr, struct sieve_ast_node *node, +(struct sieve_generator *gentr, unsigned int source_line, const char *fmt, ...) ATTR_FORMAT(3, 4);; void sieve_generator_error -(struct sieve_generator *gentr, struct sieve_ast_node *node, +(struct sieve_generator *gentr, unsigned int source_line, const char *fmt, ...) ATTR_FORMAT(3, 4); void sieve_generator_critical -(struct sieve_generator *gentr, struct sieve_ast_node *node, +(struct sieve_generator *gentr, unsigned int source_line, const char *fmt, ...) ATTR_FORMAT(3, 4); /* diff --git a/src/lib-sieve/sieve-interpreter.c b/src/lib-sieve/sieve-interpreter.c index 40f9582754be4acd58db95ac5fdd961a283949bf..d02a8195cfaba6249606e614920b108a8a007250 100644 --- a/src/lib-sieve/sieve-interpreter.c +++ b/src/lib-sieve/sieve-interpreter.c @@ -100,15 +100,15 @@ struct sieve_interpreter *sieve_interpreter_create } /* Load other extensions listed in code */ - if ( sieve_binary_read_integer(sbin, &interp->pc, &ext_count) ) { + if ( sieve_binary_read_unsigned(sbin, &interp->pc, &ext_count) ) { for ( i = 0; i < ext_count; i++ ) { unsigned int code = 0; const struct sieve_extension *ext; if ( !sieve_binary_read_extension(sbin, &interp->pc, &code, &ext) ) { - success = FALSE; - break; - } + success = FALSE; + break; + } if ( ext->interpreter_load != NULL && !ext->interpreter_load(&interp->runenv, &interp->pc) ) { @@ -182,8 +182,8 @@ const char *sieve_runtime_location(const struct sieve_runtime_env *runenv) { const char *op = runenv->interp->current_op == NULL ? "<<NOOP>>" : runenv->interp->current_op->mnemonic; - return t_strdup_printf("%s: #%08x: %s", sieve_script_name(runenv->script), - runenv->interp->current_op_addr, op); + return t_strdup_printf("%s: #%08llx: %s", sieve_script_name(runenv->script), + (unsigned long long) runenv->interp->current_op_addr, op); } void sieve_runtime_error @@ -237,7 +237,7 @@ void _sieve_runtime_trace va_list args; va_start(args, fmt); - str_printfa(outbuf, "%08x: ", runenv->interp->current_op_addr); + str_printfa(outbuf, "%08llx: ", (unsigned long long) runenv->interp->current_op_addr); str_vprintfa(outbuf, fmt, args); str_append_c(outbuf, '\n'); va_end(args); @@ -252,8 +252,9 @@ void _sieve_runtime_trace_error va_list args; va_start(args, fmt); - str_printfa(outbuf, "%08x: [[ERROR: %s: ", runenv->interp->pc - , runenv->interp->current_op->mnemonic); + str_printfa(outbuf, "%08llx: [[ERROR: %s: ", + (unsigned long long) runenv->interp->pc, + runenv->interp->current_op->mnemonic); str_vprintfa(outbuf, fmt, args); str_append(outbuf, "]]\n"); va_end(args); diff --git a/src/lib-sieve/sieve-match-types.c b/src/lib-sieve/sieve-match-types.c index 23d8c65b3089ad596d5f39352689e6e4034845a0..f30c95c2e0c1386e5d8660c291a7fbc4d7f320da 100644 --- a/src/lib-sieve/sieve-match-types.c +++ b/src/lib-sieve/sieve-match-types.c @@ -366,6 +366,7 @@ static bool tag_match_type_is_instance_of /* Create context */ mtctx = p_new(sieve_command_pool(cmd), struct sieve_match_type_context, 1); mtctx->match_type = mtch; + mtctx->match_type_arg = arg; mtctx->command_ctx = cmd; mtctx->comparator = NULL; /* Can be filled in later */ @@ -498,7 +499,7 @@ const struct sieve_operand match_type_operand = { */ bool sieve_match_substring_validate_context -(struct sieve_validator *validator, struct sieve_ast_argument *arg ATTR_UNUSED, +(struct sieve_validator *validator, struct sieve_ast_argument *arg, struct sieve_match_type_context *ctx, struct sieve_ast_argument *key_arg ATTR_UNUSED) { @@ -508,7 +509,7 @@ bool sieve_match_substring_validate_context return TRUE; if ( (cmp->flags & SIEVE_COMPARATOR_FLAG_SUBSTRING_MATCH) == 0 ) { - sieve_command_validate_error(validator, ctx->command_ctx, + sieve_argument_validate_error(validator, arg, "the specified %s comparator does not support " "sub-string matching as required by the :%s match type", cmp->object.identifier, ctx->match_type->object.identifier ); diff --git a/src/lib-sieve/sieve-match-types.h b/src/lib-sieve/sieve-match-types.h index 775d67a6bce48de43a3e5602a26b4888342f42e5..a501952fe80d4218beb200f5ffb9549087d89553 100644 --- a/src/lib-sieve/sieve-match-types.h +++ b/src/lib-sieve/sieve-match-types.h @@ -75,6 +75,8 @@ struct sieve_match_type { struct sieve_match_type_context { struct sieve_command_context *command_ctx; + struct sieve_ast_argument *match_type_arg; + const struct sieve_match_type *match_type; /* Only filled in when match_type->validate_context() is called */ diff --git a/src/lib-sieve/sieve-validator.c b/src/lib-sieve/sieve-validator.c index c134acf7afcd268ddf5b821cbcd6bae8aa483a6f..c8093812a206eee9a58c620c2c13390753ab14a5 100644 --- a/src/lib-sieve/sieve-validator.c +++ b/src/lib-sieve/sieve-validator.c @@ -98,35 +98,42 @@ struct sieve_validator { */ void sieve_validator_warning -(struct sieve_validator *validator, struct sieve_ast_node *node, +(struct sieve_validator *validator, unsigned int source_line, const char *fmt, ...) { va_list args; va_start(args, fmt); - sieve_ast_error(validator->ehandler, sieve_vwarning, node, fmt, args); + sieve_vwarning(validator->ehandler, + sieve_error_script_location(validator->script, source_line), + fmt, args); va_end(args); + } void sieve_validator_error -(struct sieve_validator *validator, struct sieve_ast_node *node, +(struct sieve_validator *validator, unsigned int source_line, const char *fmt, ...) { va_list args; va_start(args, fmt); - sieve_ast_error(validator->ehandler, sieve_verror, node, fmt, args); + sieve_verror(validator->ehandler, + sieve_error_script_location(validator->script, source_line), + fmt, args); va_end(args); } void sieve_validator_critical -(struct sieve_validator *validator, struct sieve_ast_node *node, +(struct sieve_validator *validator, unsigned int source_line, const char *fmt, ...) { va_list args; va_start(args, fmt); - sieve_ast_error(validator->ehandler, sieve_vcritical, node, fmt, args); + sieve_vcritical(validator->ehandler, + sieve_error_script_location(validator->script, source_line), + fmt, args); va_end(args); } @@ -668,7 +675,7 @@ bool sieve_validate_positional_argument (sieve_ast_argument_type(arg) != SAAT_STRING || req_type != SAAT_STRING_LIST) ) { - sieve_command_validate_error(validator, cmd, + sieve_argument_validate_error(validator, arg, "the %s %s expects %s as argument %d (%s), but %s was found", cmd->command->identifier, sieve_command_type_name(cmd->command), sieve_ast_argument_type_name(req_type), @@ -688,7 +695,7 @@ bool sieve_validate_tag_parameter (sieve_ast_argument_type(param) != SAAT_STRING || req_type != SAAT_STRING_LIST) ) { - sieve_command_validate_error(validator, cmd, + sieve_argument_validate_error(validator, param, "the :%s tag for the %s %s requires %s as parameter, " "but %s was found", sieve_ast_argument_tag(tag), cmd->command->identifier, sieve_command_type_name(cmd->command), @@ -724,7 +731,7 @@ static bool sieve_validate_command_arguments sieve_validator_find_tag(validator, cmd, arg, &id_code); if ( tag == NULL ) { - sieve_command_validate_error(validator, cmd, + sieve_argument_validate_error(validator, arg, "unknown tagged argument ':%s' for the %s %s " "(reported only once at first occurence)", sieve_ast_argument_tag(arg), cmd->command->identifier, @@ -756,7 +763,7 @@ static bool sieve_validate_command_arguments t_strdup_printf("%s argument (:%s)", tag->identifier, tag_id) : t_strdup_printf(":%s argument", tag->identifier); - sieve_command_validate_error(validator, cmd, + sieve_argument_validate_error(validator, arg, "encountered duplicate %s for the %s %s", tag_desc, cmd->command->identifier, sieve_command_type_name(cmd->command)); @@ -784,7 +791,7 @@ static bool sieve_validate_command_arguments while ( arg != NULL ) { if ( sieve_ast_argument_type(arg) == SAAT_TAG ) { - sieve_command_validate_error(validator, cmd, + sieve_argument_validate_error(validator, arg, "encountered an unexpected tagged argument ':%s' " "while validating positional arguments for the %s %s", sieve_ast_argument_tag(arg), cmd->command->identifier, @@ -858,7 +865,8 @@ static bool sieve_validate_command_subtests case 0: if ( sieve_ast_test_count(cmd->ast_node) > 0 ) { sieve_command_validate_error(validator, cmd, - "the %s %s accepts no sub-tests, but tests are specified anyway", + "the %s %s accepts no sub-tests, but tests are specified anyway " + "(forgot semicolon?)", cmd->command->identifier, sieve_command_type_name(cmd->command)); return FALSE; @@ -968,7 +976,7 @@ static bool sieve_validate_command (command->type == SCT_TEST && ast_type == SAT_COMMAND) ) { sieve_validator_error( - valdtr, cmd_node, "attempted to use %s '%s' as %s", + valdtr, cmd_node->source_line, "attempted to use %s '%s' as %s", sieve_command_type_name(command), cmd_node->identifier, sieve_ast_type_name(ast_type)); @@ -1011,7 +1019,7 @@ static bool sieve_validate_command } else { sieve_validator_error( - valdtr, cmd_node, + valdtr, cmd_node->source_line, "unknown %s '%s' (only reported once at first occurence)", sieve_ast_type_name(ast_type), cmd_node->identifier); diff --git a/src/lib-sieve/sieve-validator.h b/src/lib-sieve/sieve-validator.h index 041336c7fd9caa0b74e7322822cf2195d31b4af6..a48dbd8c72b9d60aff27416f7b568eca04e108e7 100644 --- a/src/lib-sieve/sieve-validator.h +++ b/src/lib-sieve/sieve-validator.h @@ -52,13 +52,13 @@ struct sieve_script *sieve_validator_script */ void sieve_validator_warning - (struct sieve_validator *validator, struct sieve_ast_node *node, + (struct sieve_validator *validator, unsigned int source_line, const char *fmt, ...) ATTR_FORMAT(3, 4); void sieve_validator_error - (struct sieve_validator *validator, struct sieve_ast_node *node, + (struct sieve_validator *validator, unsigned int source_line, const char *fmt, ...) ATTR_FORMAT(3, 4); void sieve_validator_critical - (struct sieve_validator *validator, struct sieve_ast_node *node, + (struct sieve_validator *validator, unsigned int source_line, const char *fmt, ...) ATTR_FORMAT(3, 4); /* diff --git a/src/lib-sieve/tst-address.c b/src/lib-sieve/tst-address.c index 9a44da4300cf60e0e818b45ecbd78108ef5000d0..e6d01d0bbfb5426eae22e40102b70d5c2f3d142a 100644 --- a/src/lib-sieve/tst-address.c +++ b/src/lib-sieve/tst-address.c @@ -147,7 +147,7 @@ static bool tst_address_validate */ header = arg; if ( !sieve_ast_stringlist_map(&header, NULL, _header_is_allowed) ) { - sieve_command_validate_error(validator, tst, + sieve_argument_validate_error(validator, header, "specified header '%s' is not allowed for the address test", str_sanitize(sieve_ast_strlist_strc(header), 64)); return FALSE; diff --git a/src/lib-sieve/tst-size.c b/src/lib-sieve/tst-size.c index 8ff7e355d9083ec039c53ee7a45e62b005784ab1..c4249429db11ab0b2380483012df5f11ae16bbb0 100644 --- a/src/lib-sieve/tst-size.c +++ b/src/lib-sieve/tst-size.c @@ -87,7 +87,7 @@ static bool tst_size_validate_over_tag struct tst_size_context_data *ctx_data = (struct tst_size_context_data *) tst->data; if ( ctx_data->type != SIZE_UNASSIGNED ) { - sieve_command_validate_error(validator, tst, TST_SIZE_ERROR_DUP_TAG); + sieve_argument_validate_error(validator, *arg, TST_SIZE_ERROR_DUP_TAG); return FALSE; } @@ -106,7 +106,7 @@ static bool tst_size_validate_under_tag struct tst_size_context_data *ctx_data = (struct tst_size_context_data *) tst->data; if ( ctx_data->type != SIZE_UNASSIGNED ) { - sieve_command_validate_error(validator, tst, TST_SIZE_ERROR_DUP_TAG); + sieve_argument_validate_error(validator, *arg, TST_SIZE_ERROR_DUP_TAG); return FALSE; } @@ -224,7 +224,7 @@ static bool tst_size_operation_dump */ static inline bool tst_size_get -(const struct sieve_runtime_env *renv, sieve_size_t *size) +(const struct sieve_runtime_env *renv, sieve_number_t *size) { uoff_t psize; @@ -240,7 +240,7 @@ static int tst_size_operation_execute (const struct sieve_operation *op, const struct sieve_runtime_env *renv, sieve_size_t *address) { - sieve_size_t mail_size, limit; + sieve_number_t mail_size, limit; /* Read size limit */ if ( !sieve_opr_number_read(renv, address, &limit) ) { diff --git a/src/testsuite/testsuite-objects.c b/src/testsuite/testsuite-objects.c index 3b4bd6cda5a4ba78c988f202350b4cfcfb6f39a0..3371c8815a2aeeaf6e41902bc1a7e5f3463f7a6f 100644 --- a/src/testsuite/testsuite-objects.c +++ b/src/testsuite/testsuite-objects.c @@ -207,7 +207,7 @@ bool testsuite_object_argument_activate object = testsuite_object_find(valdtr, objname); if ( object == NULL ) { - sieve_command_validate_error(valdtr, cmd, + sieve_argument_validate_error(valdtr, arg, "unknown testsuite object '%s'", objname); return FALSE; } @@ -218,7 +218,7 @@ bool testsuite_object_argument_activate if ( member != NULL ) { if ( object->get_member_id == NULL || (member_id=object->get_member_id(member)) == -1 ) { - sieve_command_validate_error(valdtr, cmd, + sieve_argument_validate_error(valdtr, arg, "member '%s' does not exist for testsuite object '%s'", member, objname); return FALSE; } diff --git a/src/testsuite/tst-test-error.c b/src/testsuite/tst-test-error.c index 607ceb7dbaf1c18ef1f9e4dc4ea7c854f6f87988..e7d23afe1ca380ac4f4746b8bb0e1c8ef782879e 100644 --- a/src/testsuite/tst-test-error.c +++ b/src/testsuite/tst-test-error.c @@ -229,7 +229,7 @@ static int tst_test_error_operation_execute /* Handle optional operands */ do { - sieve_size_t number; + sieve_number_t number; if ( (ret=sieve_match_read_optional_operands (renv, address, &opt_code, &cmp, &mtch)) <= 0 ) diff --git a/tests/address.svtest b/tests/address.svtest index ef6773b6340950cb7cdbd3e418dccbb1bd8a513e..8842c058c99141051f02faae1d8f4d57f531b253 100644 --- a/tests/address.svtest +++ b/tests/address.svtest @@ -58,3 +58,29 @@ test "Invalid address list" { } } +/* + * Strange + */ + +test_set "message" text: +From: SPAM@MYDOMAIN +To: stephan@renane-it.nl +Subject: Spam + +Spam! +. +; + +test "Questionable address" { + if address :domain :is "from" "MYDOMAIN" { + if address :localpart :is "from" "SPAM" { + + } elsif header :contains "subject" "Cron" { + test_fail "message erroneously recognized as cron"; + } else { + test_fail "message erroneously recognized as normal"; + } + } else { + test_fail "message domain not recognized"; + } +}