diff --git a/TODO b/TODO index f4c28665a32c1a27422156a569a993955cabef01..da882720d27c553c5a812c45667d0828e39f25e5 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,6 @@ Current activities: * Improve error handling and logging - - Improve runtime error handling - Avoid reporting user-caused errors to the master log. - Review logging and error handling; add more warning/info/debug messages where useful. diff --git a/src/lib-sieve/cmd-discard.c b/src/lib-sieve/cmd-discard.c index 089cbc59f491812349a4fe1c9fa55e1c10cf8026..0fcece096d739658271490763af9e6b2bbfb3931 100644 --- a/src/lib-sieve/cmd-discard.c +++ b/src/lib-sieve/cmd-discard.c @@ -113,8 +113,11 @@ static int cmd_discard_operation_execute sieve_runtime_trace(renv, SIEVE_TRLVL_ACTIONS, "discard action; cancel implicit keep"); - return ( sieve_result_add_action - (renv, NULL, &act_discard, NULL, source_line, NULL, 0) >= 0 ); + if ( sieve_result_add_action + (renv, NULL, &act_discard, NULL, source_line, NULL, 0) < 0 ) + return SIEVE_EXEC_FAILURE; + + return SIEVE_EXEC_OK; } /* diff --git a/src/lib-sieve/cmd-keep.c b/src/lib-sieve/cmd-keep.c index 27f3782c98a0f03f783e8a103a91f2bfc4ec0990..7f56149306cbd7cc7b6e390acfe1fddfdae0a850 100644 --- a/src/lib-sieve/cmd-keep.c +++ b/src/lib-sieve/cmd-keep.c @@ -95,8 +95,8 @@ static int cmd_keep_operation_execute source_line = sieve_runtime_get_command_location(renv); /* Optional operands (side effects only) */ - if ( (ret=sieve_action_opr_optional_read(renv, address, NULL, &slist)) != 0 ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( sieve_action_opr_optional_read(renv, address, NULL, &ret, &slist) != 0 ) + return ret; /* * Perform operation @@ -107,9 +107,10 @@ static int cmd_keep_operation_execute /* Add keep action to result. */ - ret = sieve_result_add_keep(renv, slist, source_line); + if ( sieve_result_add_keep(renv, slist, source_line) < 0 ) + return SIEVE_EXEC_FAILURE; - return ( ret >= 0 ); + return SIEVE_EXEC_OK; } diff --git a/src/lib-sieve/cmd-redirect.c b/src/lib-sieve/cmd-redirect.c index 4d439b4a1e1dc4c93da8280f82955a5a72502c40..dcf991647718aa1e270bb4e16aa592f0c1b19fac 100644 --- a/src/lib-sieve/cmd-redirect.c +++ b/src/lib-sieve/cmd-redirect.c @@ -195,7 +195,7 @@ static int cmd_redirect_operation_execute string_t *redirect; unsigned int source_line; pool_t pool; - int ret = 0; + int ret; /* * Read data @@ -205,12 +205,12 @@ static int cmd_redirect_operation_execute source_line = sieve_runtime_get_command_location(renv); /* Optional operands (side effects only) */ - if ( (ret=sieve_action_opr_optional_read(renv, address, NULL, &slist)) < 0 ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( sieve_action_opr_optional_read(renv, address, NULL, &ret, &slist) != 0 ) + return ret; /* Read the address */ - if ( !sieve_opr_string_read(renv, address, "address", &redirect) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_string_read(renv, address, "address", &redirect)) <= 0 ) + return ret; /* * Perform operation @@ -232,11 +232,12 @@ static int cmd_redirect_operation_execute act = p_new(pool, struct act_redirect_context, 1); act->to_address = p_strdup(pool, str_c(redirect)); - ret = sieve_result_add_action + if ( sieve_result_add_action (renv, NULL, &act_redirect, slist, source_line, (void *) act, - svinst->max_redirects); + svinst->max_redirects) < 0 ) + return SIEVE_EXEC_FAILURE; - return ( ret >= 0 ); + return SIEVE_EXEC_OK; } /* diff --git a/src/lib-sieve/ext-envelope.c b/src/lib-sieve/ext-envelope.c index f50698ba5ae79dafdb0b595eecc14ecacc66bc13..2de4996200e70f208f95d92c6478b91fb5e674ff 100644 --- a/src/lib-sieve/ext-envelope.c +++ b/src/lib-sieve/ext-envelope.c @@ -299,6 +299,7 @@ static struct sieve_address_list *sieve_envelope_address_list_create addrlist = t_new(struct sieve_envelope_address_list, 1); addrlist->addrlist.strlist.runenv = renv; + addrlist->addrlist.strlist.exec_status = SIEVE_EXEC_OK; addrlist->addrlist.strlist.next_item = sieve_envelope_address_list_next_string_item; addrlist->addrlist.strlist.reset = sieve_envelope_address_list_reset; @@ -582,26 +583,26 @@ static int ext_envelope_operation_execute SIEVE_ADDRESS_PART_DEFAULT(all_address_part); struct sieve_stringlist *env_part_list, *value_list, *key_list; struct sieve_address_list *addr_list; - int ret; + int match, ret; /* * Read operands */ /* Read optional operands */ - if ( (ret=sieve_addrmatch_opr_optional_read - (renv, address, NULL, &addrp, &mcht, &cmp)) < 0 ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( sieve_addrmatch_opr_optional_read + (renv, address, NULL, &ret, &addrp, &mcht, &cmp) < 0 ) + return ret; /* Read envelope-part */ - if ( (env_part_list=sieve_opr_stringlist_read(renv, address, "envelope-part")) - == NULL ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_stringlist_read + (renv, address, "envelope-part", &env_part_list)) <= 0 ) + return ret; /* Read key-list */ - if ( (key_list=sieve_opr_stringlist_read(renv, address, "key-list")) - == NULL ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_stringlist_read(renv, address, "key-list", &key_list)) + <= 0 ) + return ret; /* * Perform test @@ -614,15 +615,11 @@ static int ext_envelope_operation_execute value_list = sieve_address_part_stringlist_create(renv, &addrp, addr_list); /* Perform match */ - ret = sieve_match(renv, &mcht, &cmp, value_list, key_list); - - /* Set test result for subsequent conditional jump */ - if ( ret >= 0 ) { - sieve_interpreter_set_test_result(renv->interp, ret > 0); - return SIEVE_EXEC_OK; - } + if ( (match=sieve_match(renv, &mcht, &cmp, value_list, key_list, &ret)) < 0 ) + return ret; - sieve_runtime_trace_error(renv, "invalid string-list item"); - return SIEVE_EXEC_BIN_CORRUPT; + /* Set test result for subsequent conditional jump */ + sieve_interpreter_set_test_result(renv->interp, match > 0); + return SIEVE_EXEC_OK; } diff --git a/src/lib-sieve/ext-fileinto.c b/src/lib-sieve/ext-fileinto.c index da5607a7c9ef8a7026138622ba8a76d127bea3f6..80b4b8b9eeceb69dd6af389979605e86732d767e 100644 --- a/src/lib-sieve/ext-fileinto.c +++ b/src/lib-sieve/ext-fileinto.c @@ -166,12 +166,12 @@ static int ext_fileinto_operation_execute source_line = sieve_runtime_get_command_location(renv); /* Optional operands (side effects only) */ - if ( (ret=sieve_action_opr_optional_read(renv, address, NULL, &slist)) < 0 ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( sieve_action_opr_optional_read(renv, address, NULL, &ret, &slist) != 0 ) + return ret; /* Folder operand */ - if ( !sieve_opr_string_read(renv, address, "folder", &folder) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_string_read(renv, address, "folder", &folder)) <= 0 ) + return ret; /* * Perform operation @@ -187,10 +187,11 @@ static int ext_fileinto_operation_execute } /* Add action to result */ - ret = sieve_act_store_add_to_result - (renv, slist, str_c(folder), source_line); + if ( sieve_act_store_add_to_result + (renv, slist, str_c(folder), source_line) < 0 ) + return SIEVE_EXEC_FAILURE; - return ( ret >= 0 ); + return SIEVE_EXEC_OK; } diff --git a/src/lib-sieve/ext-reject.c b/src/lib-sieve/ext-reject.c index 5ca7ed783a9fcac865b5667446eda42a6720f9b0..8663da25cf80cdd17d849760fd149707412513f6 100644 --- a/src/lib-sieve/ext-reject.c +++ b/src/lib-sieve/ext-reject.c @@ -279,12 +279,12 @@ static int ext_reject_operation_execute source_line = sieve_runtime_get_command_location(renv); /* Optional operands (side effects only) */ - if ( (ret=sieve_action_opr_optional_read(renv, address, NULL, &slist)) < 0 ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( sieve_action_opr_optional_read(renv, address, NULL, &ret, &slist) != 0 ) + return ret; /* Read rejection reason */ - if ( !sieve_opr_string_read(renv, address, "reason", &reason) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_string_read(renv, address, "reason", &reason)) <= 0 ) + return ret; /* * Perform operation @@ -307,10 +307,11 @@ static int ext_reject_operation_execute act->reason = p_strdup(pool, str_c(reason)); act->ereject = ( sieve_operation_is(oprtn, ereject_operation) ); - ret = sieve_result_add_action - (renv, this_ext, &act_reject, slist, source_line, (void *) act, 0); + if ( sieve_result_add_action + (renv, this_ext, &act_reject, slist, source_line, (void *) act, 0) < 0 ) + return SIEVE_EXEC_FAILURE; - return ( ret >= 0 ); + return SIEVE_EXEC_OK; } /* diff --git a/src/lib-sieve/plugins/body/tst-body.c b/src/lib-sieve/plugins/body/tst-body.c index f3033bc87a5af181305a285055b5b15e1c3a9947..36b4a6cf843ea7cf62594062264d89b9266f4ee4 100644 --- a/src/lib-sieve/plugins/body/tst-body.c +++ b/src/lib-sieve/plugins/body/tst-body.c @@ -255,13 +255,13 @@ static bool ext_body_operation_dump /* Handle any optional arguments */ for (;;) { - int ret; + int opt; - if ( (ret=sieve_match_opr_optional_dump(denv, address, &opt_code)) + if ( (opt=sieve_match_opr_optional_dump(denv, address, &opt_code)) < 0 ) return FALSE; - if ( ret == 0 ) break; + if ( opt == 0 ) break; switch ( opt_code ) { case OPT_BODY_TRANSFORM: @@ -302,7 +302,6 @@ static bool ext_body_operation_dump static int ext_body_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { - int ret; int opt_code = 0; struct sieve_comparator cmp = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); @@ -312,6 +311,7 @@ static int ext_body_operation_execute struct sieve_stringlist *ctype_list, *value_list, *key_list; bool mvalues_active; const char * const *content_types = NULL; + int match, ret; /* * Read operands @@ -321,46 +321,44 @@ static int ext_body_operation_execute ctype_list = NULL; for (;;) { - bool opok = TRUE; + int opt; - if ( (ret=sieve_match_opr_optional_read - (renv, address, &opt_code, &cmp, &mcht)) < 0 ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (opt=sieve_match_opr_optional_read + (renv, address, &opt_code, &ret, &cmp, &mcht)) < 0 ) + return ret; - if ( ret == 0 ) break; + if ( opt == 0 ) break; switch ( opt_code ) { case OPT_BODY_TRANSFORM: if ( !sieve_binary_read_byte(renv->sblock, address, &transform) || transform > TST_BODY_TRANSFORM_TEXT ) { sieve_runtime_trace_error(renv, "invalid body transform type"); - opok = FALSE; + return SIEVE_EXEC_BIN_CORRUPT; } - if ( opok && transform == TST_BODY_TRANSFORM_CONTENT ) { - ctype_list = sieve_opr_stringlist_read - (renv, address, "content-type-list"); - opok = ( ctype_list != NULL ); - } + if ( transform == TST_BODY_TRANSFORM_CONTENT && + (ret=sieve_opr_stringlist_read + (renv, address, "content-type-list", &ctype_list)) <= 0 ) + return ret; break; default: sieve_runtime_trace_error(renv, "unknown optional operand"); - opok = FALSE; + return SIEVE_EXEC_BIN_CORRUPT; } - - if ( !opok) return SIEVE_EXEC_BIN_CORRUPT; } /* Read key-list */ - if ( (key_list=sieve_opr_stringlist_read(renv, address, "key-list")) == NULL ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_stringlist_read(renv, address, "key-list", &key_list)) + <= 0 ) + return ret; - if ( ctype_list != NULL && !sieve_stringlist_read_all - (ctype_list, pool_datastack_create(), &content_types) ) { + if ( ctype_list != NULL && sieve_stringlist_read_all + (ctype_list, pool_datastack_create(), &content_types) < 0 ) { sieve_runtime_trace_error(renv, "failed to read content-type-list operand"); - return SIEVE_EXEC_BIN_CORRUPT; + return ctype_list->exec_status; } /* @@ -378,17 +376,15 @@ static int ext_body_operation_execute mvalues_active = sieve_match_values_set_enabled(renv, FALSE); /* Perform match */ - ret = sieve_match(renv, &mcht, &cmp, value_list, key_list); + match = sieve_match(renv, &mcht, &cmp, value_list, key_list, &ret); /* Restore match values processing */ (void)sieve_match_values_set_enabled(renv, mvalues_active); - /* Set test result for subsequent conditional jump */ - if ( ret >= 0 ) { - sieve_interpreter_set_test_result(renv->interp, ret > 0); - return SIEVE_EXEC_OK; - } + if ( match < 0 ) + return ret; - sieve_runtime_trace_error(renv, "invalid string-list item"); - return SIEVE_EXEC_BIN_CORRUPT; + /* Set test result for subsequent conditional jump */ + sieve_interpreter_set_test_result(renv->interp, match > 0); + return SIEVE_EXEC_OK; } diff --git a/src/lib-sieve/plugins/date/ext-date-common.c b/src/lib-sieve/plugins/date/ext-date-common.c index 7891b17e5c1977661fb60a3a31de693ce516b1d5..ce69112500f436e98295975354be8284e24c4ef0 100644 --- a/src/lib-sieve/plugins/date/ext-date-common.c +++ b/src/lib-sieve/plugins/date/ext-date-common.c @@ -502,6 +502,7 @@ struct sieve_stringlist *ext_date_stringlist_create strlist = t_new(struct ext_date_stringlist, 1); strlist->strlist.runenv = renv; + strlist->strlist.exec_status = SIEVE_EXEC_OK; strlist->strlist.next_item = ext_date_stringlist_next_item; strlist->strlist.reset = ext_date_stringlist_reset; strlist->field_values = field_values; diff --git a/src/lib-sieve/plugins/date/tst-date.c b/src/lib-sieve/plugins/date/tst-date.c index 90b62c3b5eaf07be99a10edf7efbd00a6b83659b..201cf404717ca1db7c9042796fad6ddad28a7dbd 100644 --- a/src/lib-sieve/plugins/date/tst-date.c +++ b/src/lib-sieve/plugins/date/tst-date.c @@ -336,16 +336,16 @@ static bool tst_date_operation_dump /* Handle any optional arguments */ for (;;) { - int ret; + int opt; - if ( (ret=sieve_match_opr_optional_dump(denv, address, &opt_code)) < 0 ) + if ( (opt=sieve_match_opr_optional_dump(denv, address, &opt_code)) < 0 ) return FALSE; - if ( ret == 0 ) break; + if ( opt == 0 ) break; switch ( opt_code ) { case OPT_DATE_ZONE: - if ( !sieve_operand_read(denv->sblock, address, &operand) ) { + if ( !sieve_operand_read(denv->sblock, address, "zone", &operand) ) { sieve_code_dumpf(denv, "ERROR: INVALID OPERAND"); return FALSE; } @@ -386,33 +386,34 @@ static int tst_date_operation_execute SIEVE_MATCH_TYPE_DEFAULT(is_match_type); struct sieve_comparator cmp = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); - struct sieve_operand operand; + struct sieve_operand oprnd; string_t *date_part = NULL, *zone = NULL; struct sieve_stringlist *hdr_list = NULL, *hdr_value_list; struct sieve_stringlist *value_list, *key_list; bool zone_specified = FALSE; int time_zone; - int ret; + int match, ret; /* Read optional operands */ for (;;) { - int ret; + int opt; - if ( (ret=sieve_match_opr_optional_read - (renv, address, &opt_code, &cmp, &mcht)) < 0 ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (opt=sieve_match_opr_optional_read + (renv, address, &opt_code, &ret, &cmp, &mcht)) < 0 ) + return ret; - if ( ret == 0 ) break; + if ( opt == 0 ) break; switch ( opt_code ) { case OPT_DATE_ZONE: - if ( !sieve_operand_runtime_read(renv, address, "zone", &operand) ) - return SIEVE_EXEC_BIN_CORRUPT; - - if ( !sieve_operand_is_omitted(&operand) ) { - if ( !sieve_opr_string_read_data - (renv, &operand, address, "zone", &zone) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_operand_runtime_read(renv, address, "zone", &oprnd)) + <= 0 ) + return ret; + + if ( !sieve_operand_is_omitted(&oprnd) ) { + if ( (ret=sieve_opr_string_read_data + (renv, &oprnd, address, "zone", &zone)) <= 0 ) + return ret; } zone_specified = TRUE; @@ -425,19 +426,20 @@ static int tst_date_operation_execute if ( sieve_operation_is(op, date_operation) ) { /* Read header name as stringlist */ - if ( (hdr_list=sieve_opr_stringlist_read(renv, address, "header-name")) - == NULL ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_stringlist_read + (renv, address, "header-name", &hdr_list)) <= 0 ) + return ret; } /* Read date part */ - if ( !sieve_opr_string_read(renv, address, "date-part", &date_part) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_string_read(renv, address, "date-part", &date_part)) + <= 0 ) + return ret; /* Read key-list */ - if ( (key_list=sieve_opr_stringlist_read(renv, address, "key-list")) - == NULL ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_stringlist_read(renv, address, "key-list", &key_list)) + <= 0 ) + return ret; /* Determine what time zone to use in the result */ if ( !zone_specified ) { @@ -475,14 +477,10 @@ static int tst_date_operation_execute } /* Perform match */ - ret = sieve_match(renv, &mcht, &cmp, value_list, key_list); - - /* Set test result for subsequent conditional jump */ - if ( ret >= 0 ) { - sieve_interpreter_set_test_result(renv->interp, ret > 0); - return SIEVE_EXEC_OK; - } + if ( (match=sieve_match(renv, &mcht, &cmp, value_list, key_list, &ret)) < 0 ) + return ret; - sieve_runtime_trace_error(renv, "invalid string-list item"); - return SIEVE_EXEC_BIN_CORRUPT; + /* Set test result for subsequent conditional jump */ + sieve_interpreter_set_test_result(renv->interp, match > 0); + return SIEVE_EXEC_OK; } diff --git a/src/lib-sieve/plugins/enotify/cmd-notify.c b/src/lib-sieve/plugins/enotify/cmd-notify.c index 69a4f0530627c26b6a1769cebf018019800b9668..b331e76aca5ffe23ebd49462df1df4dd0a7ffe3a 100644 --- a/src/lib-sieve/plugins/enotify/cmd-notify.c +++ b/src/lib-sieve/plugins/enotify/cmd-notify.c @@ -356,13 +356,13 @@ static bool cmd_notify_operation_dump /* Dump optional operands */ for (;;) { - int ret; + int opt; bool opok = TRUE; - if ( (ret=sieve_opr_optional_dump(denv, address, &opt_code)) < 0 ) + if ( (opt=sieve_opr_optional_dump(denv, address, &opt_code)) < 0 ) return FALSE; - if ( ret == 0 ) break; + if ( opt == 0 ) break; switch ( opt_code ) { case CMD_NOTIFY_OPT_IMPORTANCE: @@ -400,12 +400,13 @@ static int cmd_notify_operation_execute struct sieve_enotify_action *act; void *method_context; pool_t pool; - int opt_code = 0, result = SIEVE_EXEC_OK; + int opt_code = 0; sieve_number_t importance = 2; struct sieve_stringlist *options = NULL; const struct sieve_enotify_method *method; string_t *method_uri, *message = NULL, *from = NULL; unsigned int source_line; + int ret; /* * Read operands @@ -418,40 +419,38 @@ static int cmd_notify_operation_execute /* Optional operands */ for (;;) { - bool opok = TRUE; - int ret; + int opt; - if ( (ret=sieve_opr_optional_read(renv, address, &opt_code)) < 0 ) + if ( (opt=sieve_opr_optional_read(renv, address, &opt_code)) < 0 ) return SIEVE_EXEC_BIN_CORRUPT; - if ( ret == 0 ) break; + if ( opt == 0 ) break; switch ( opt_code ) { case CMD_NOTIFY_OPT_IMPORTANCE: - opok = sieve_opr_number_read(renv, address, "importance", &importance); + ret = sieve_opr_number_read(renv, address, "importance", &importance); break; case CMD_NOTIFY_OPT_FROM: - opok = sieve_opr_string_read(renv, address, "from", &from); + ret = sieve_opr_string_read(renv, address, "from", &from); break; case CMD_NOTIFY_OPT_MESSAGE: - opok = sieve_opr_string_read(renv, address, "message", &message); + ret = sieve_opr_string_read(renv, address, "message", &message); break; case CMD_NOTIFY_OPT_OPTIONS: - options = sieve_opr_stringlist_read(renv, address, "options"); - opok = ( options != NULL ); + ret = sieve_opr_stringlist_read(renv, address, "options", &options); break; default: sieve_runtime_trace_error(renv, "unknown optional operand"); return SIEVE_EXEC_BIN_CORRUPT; } - if ( !opok ) return SIEVE_EXEC_BIN_CORRUPT; + if ( ret <= 0 ) return ret; } /* Method operand */ - if ( !sieve_opr_string_read(renv, address, "method", &method_uri) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_string_read(renv, address, "method", &method_uri)) <= 0 ) + return ret; /* * Perform operation @@ -475,9 +474,9 @@ static int cmd_notify_operation_execute /* Check operands */ - if ( (result=ext_enotify_runtime_check_operands + if ( (ret=ext_enotify_runtime_check_operands (renv, source_line, method_uri, message, from, options, &method, - &method_context)) ) + &method_context)) > 0 ) { /* Add notify action to the result */ @@ -491,11 +490,14 @@ static int cmd_notify_operation_execute if ( from != NULL ) act->from = p_strdup(pool, str_c(from)); - return ( sieve_result_add_action - (renv, this_ext, &act_notify, slist, source_line, (void *) act, 0) >= 0 ); + if ( sieve_result_add_action + (renv, this_ext, &act_notify, slist, source_line, (void *) act, 0) < 0 ) + return SIEVE_EXEC_FAILURE; + + return SIEVE_EXEC_OK; } - return result; + return ret; } /* diff --git a/src/lib-sieve/plugins/enotify/tst-notify-method-capability.c b/src/lib-sieve/plugins/enotify/tst-notify-method-capability.c index 8ee7fb53fb500a3efacdddc8a1f4983ed23f5022..73c982929720fb9609001e30e6f2b3cbc70cf274 100644 --- a/src/lib-sieve/plugins/enotify/tst-notify-method-capability.c +++ b/src/lib-sieve/plugins/enotify/tst-notify-method-capability.c @@ -155,13 +155,11 @@ static bool tst_notifymc_generate static bool tst_notifymc_operation_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address) { - int opt_code = 0; - sieve_code_dumpf(denv, "NOTIFY_METHOD_CAPABILITY"); sieve_code_descend(denv); /* Handle any optional arguments */ - if ( sieve_match_opr_optional_dump(denv, address, &opt_code) != 0 ) + if ( sieve_match_opr_optional_dump(denv, address, NULL) != 0 ) return FALSE; return @@ -177,8 +175,6 @@ static bool tst_notifymc_operation_dump static int tst_notifymc_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { - int ret; - int opt_code = 0; struct sieve_match_type mcht = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); struct sieve_comparator cmp = @@ -186,35 +182,31 @@ static int tst_notifymc_operation_execute string_t *notify_uri, *notify_capability; struct sieve_stringlist *value_list, *key_list; const char *cap_value; + int match, ret; /* * Read operands */ /* Handle match-type and comparator operands */ - if ( (ret=sieve_match_opr_optional_read - (renv, address, &opt_code, &cmp, &mcht)) < 0 ) - return SIEVE_EXEC_BIN_CORRUPT; - - /* Check whether we neatly finished the list of optional operands*/ - if ( ret > 0 ) { - sieve_runtime_trace_error(renv, "invalid optional operand"); - return SIEVE_EXEC_BIN_CORRUPT; - } + if ( sieve_match_opr_optional_read + (renv, address, NULL, &ret, &cmp, &mcht) < 0 ) + return ret; /* Read notify uri */ - if ( !sieve_opr_string_read(renv, address, "notify-uri", ¬ify_uri) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_string_read(renv, address, "notify-uri", ¬ify_uri)) + <= 0 ) + return ret; /* Read notify capability */ - if ( !sieve_opr_string_read - (renv, address, "notify-capability", ¬ify_capability) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_string_read + (renv, address, "notify-capability", ¬ify_capability)) <= 0 ) + return ret; /* Read key-list */ - if ( (key_list=sieve_opr_stringlist_read(renv, address, "key-list")) - == NULL ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_stringlist_read(renv, address, "key-list", &key_list)) + <= 0) + return ret; /* * Perform operation @@ -229,16 +221,14 @@ static int tst_notifymc_operation_execute value_list = sieve_single_stringlist_create_cstr(renv, cap_value, TRUE); /* Perform match */ - ret = sieve_match(renv, &mcht, &cmp, value_list, key_list); + if ( (match=sieve_match(renv, &mcht, &cmp, value_list, key_list, &ret)) + < 0 ) + return ret; } else { - ret = 0; - } - - if ( ret >= 0 ) { - sieve_interpreter_set_test_result(renv->interp, ret > 0); - return SIEVE_EXEC_OK; + match = 0; } - - sieve_runtime_trace_error(renv, "invalid string list item"); - return SIEVE_EXEC_BIN_CORRUPT; + + /* Set test result for subsequent conditional jump */ + sieve_interpreter_set_test_result(renv->interp, match > 0); + return SIEVE_EXEC_OK; } diff --git a/src/lib-sieve/plugins/enotify/tst-valid-notify-method.c b/src/lib-sieve/plugins/enotify/tst-valid-notify-method.c index 493bc3dc81e5dfbb97c912dd98e655866bd00281..1774de2cc880bcf354709da2495b3e1cd98cb8f2 100644 --- a/src/lib-sieve/plugins/enotify/tst-valid-notify-method.c +++ b/src/lib-sieve/plugins/enotify/tst-valid-notify-method.c @@ -115,9 +115,9 @@ static int tst_vnotifym_operation_execute */ /* Read notify uris */ - if ( (notify_uris=sieve_opr_stringlist_read(renv, address, "notify-uris")) - == NULL ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_stringlist_read + (renv, address, "notify-uris", ¬ify_uris)) <= 0 ) + return ret; /* * Perform operation diff --git a/src/lib-sieve/plugins/environment/tst-environment.c b/src/lib-sieve/plugins/environment/tst-environment.c index 5f9496d0f19f2eef23f79a431e1a9bd6b3367ecf..b25ac49cb123a77f7873f0ed2fc6282baee9db56 100644 --- a/src/lib-sieve/plugins/environment/tst-environment.c +++ b/src/lib-sieve/plugins/environment/tst-environment.c @@ -133,13 +133,11 @@ static bool tst_environment_generate static bool tst_environment_operation_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address) { - int opt_code = 0; - sieve_code_dumpf(denv, "ENVIRONMENT"); sieve_code_descend(denv); /* Optional operands */ - if ( sieve_match_opr_optional_dump(denv, address, &opt_code) != 0 ) + if ( sieve_match_opr_optional_dump(denv, address, NULL) != 0 ) return FALSE; return @@ -155,8 +153,6 @@ static int tst_environment_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { const struct sieve_extension *this_ext = renv->oprtn->ext; - int ret; - int opt_code = 0; struct sieve_match_type mcht = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); struct sieve_comparator cmp = @@ -164,30 +160,25 @@ static int tst_environment_operation_execute string_t *name; struct sieve_stringlist *value_list, *key_list; const char *env_item; + int match, ret; /* * Read operands */ /* Handle match-type and comparator operands */ - if ( (ret=sieve_match_opr_optional_read - (renv, address, &opt_code, &cmp, &mcht)) < 0 ) - return SIEVE_EXEC_BIN_CORRUPT; - - /* Check whether we neatly finished the list of optional operands*/ - if ( ret > 0 ) { - sieve_runtime_trace_error(renv, "invalid optional operand"); - return SIEVE_EXEC_BIN_CORRUPT; - } + if ( sieve_match_opr_optional_read + (renv, address, NULL, &ret, &cmp, &mcht) < 0 ) + return ret; /* Read source */ - if ( !sieve_opr_string_read(renv, address, "name", &name) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_string_read(renv, address, "name", &name)) <= 0 ) + return ret; /* Read key-list */ - if ( (key_list=sieve_opr_stringlist_read(renv, address, "key-list")) - == NULL ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_stringlist_read(renv, address, "key-list", &key_list)) + <= 0 ) + return ret; /* * Perform operation @@ -203,16 +194,14 @@ static int tst_environment_operation_execute value_list = sieve_single_stringlist_create_cstr(renv, env_item, FALSE); /* Perform match */ - ret = sieve_match(renv, &mcht, &cmp, value_list, key_list); + if ( (match=sieve_match(renv, &mcht, &cmp, value_list, key_list, &ret)) + < 0 ) + return ret; } else { - ret = 0; - } - - if ( ret >= 0 ) { - sieve_interpreter_set_test_result(renv->interp, ret > 0); - return SIEVE_EXEC_OK; + match = 0; } - - sieve_runtime_trace_error(renv, "invalid key list item"); - return SIEVE_EXEC_BIN_CORRUPT; + + /* Set test result for subsequent conditional jump */ + sieve_interpreter_set_test_result(renv->interp, match > 0); + return SIEVE_EXEC_OK; } diff --git a/src/lib-sieve/plugins/imap4flags/cmd-flag.c b/src/lib-sieve/plugins/imap4flags/cmd-flag.c index 71471d352f708fee0695010f27dfe1569eab9508..59564da886a9c44040e255103cbefaef66d41aa8 100644 --- a/src/lib-sieve/plugins/imap4flags/cmd-flag.c +++ b/src/lib-sieve/plugins/imap4flags/cmd-flag.c @@ -144,28 +144,25 @@ static bool cmd_flag_generate bool cmd_flag_operation_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address) { - struct sieve_operand operand; + struct sieve_operand oprnd; sieve_code_dumpf(denv, "%s", sieve_operation_mnemonic(denv->oprtn)); sieve_code_descend(denv); sieve_code_mark(denv); - if ( !sieve_operand_read(denv->sblock, address, &operand) ) { + if ( !sieve_operand_read(denv->sblock, address, NULL, &oprnd) ) { sieve_code_dumpf(denv, "ERROR: INVALID OPERAND"); return FALSE; } - if ( sieve_operand_is_variable(&operand) ) { + if ( sieve_operand_is_variable(&oprnd) ) { return - sieve_opr_string_dump_data(denv, &operand, address, - "variable name") && - sieve_opr_stringlist_dump(denv, address, - "list of flags"); + sieve_opr_string_dump_data(denv, &oprnd, address, "variable name") && + sieve_opr_stringlist_dump(denv, address, "list of flags"); } return - sieve_opr_stringlist_dump_data(denv, &operand, address, - "list of flags"); + sieve_opr_stringlist_dump_data(denv, &oprnd, address, "list of flags"); } /* @@ -176,47 +173,49 @@ static int cmd_flag_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { const struct sieve_operation *op = renv->oprtn; - struct sieve_operand operand; + struct sieve_operand oprnd; struct sieve_stringlist *flag_list; struct sieve_variable_storage *storage; unsigned int var_index; ext_imapflag_flag_operation_t flag_op; + int ret; /* * Read operands */ /* Read bare operand (two types possible) */ - if ( !sieve_operand_runtime_read(renv, address, NULL, &operand) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_operand_runtime_read + (renv, address, NULL, &oprnd)) <= 0 ) + return ret; /* Variable operand (optional) */ - if ( sieve_operand_is_variable(&operand) ) { + if ( sieve_operand_is_variable(&oprnd) ) { /* Read the variable operand */ - if ( !sieve_variable_operand_read_data - (renv, &operand, address, "variable", &storage, &var_index) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_variable_operand_read_data + (renv, &oprnd, address, "variable", &storage, &var_index)) <= 0 ) + return ret; /* Read flag list */ - if ( (flag_list=sieve_opr_stringlist_read(renv, address, "flag-list")) - == NULL ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_stringlist_read(renv, address, "flag-list", &flag_list)) + <= 0 ) + return ret; /* Flag-list operand */ - } else if ( sieve_operand_is_stringlist(&operand) ) { + } else if ( sieve_operand_is_stringlist(&oprnd) ) { storage = NULL; var_index = 0; /* Read flag list */ - if ( (flag_list=sieve_opr_stringlist_read_data - (renv, &operand, address, "flag-list")) == NULL ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_stringlist_read_data + (renv, &oprnd, address, "flag-list", &flag_list)) <= 0 ) + return ret; /* Invalid */ } else { - sieve_runtime_trace_error - (renv, "expected variable or string-list (flag-list) operand " - "but found %s", sieve_operand_name(&operand)); + sieve_runtime_trace_operand_error + (renv, &oprnd, "expected variable or string-list (flag-list) operand " + "but found %s", sieve_operand_name(&oprnd)); return SIEVE_EXEC_BIN_CORRUPT; } diff --git a/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c b/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c index 51ba9602defe2dd7a33c7c05ecacfac2311f2b35..63003e25a1e910a39cdef2684a98e7aa4031118c 100644 --- a/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c +++ b/src/lib-sieve/plugins/imap4flags/ext-imap4flags-common.c @@ -592,6 +592,7 @@ static struct sieve_stringlist *ext_imap4flags_stringlist_create struct ext_imap4flags_stringlist *strlist; strlist = t_new(struct ext_imap4flags_stringlist, 1); + strlist->strlist.exec_status = SIEVE_EXEC_OK; strlist->strlist.runenv = renv; strlist->strlist.next_item = ext_imap4flags_stringlist_next_item; strlist->strlist.reset = ext_imap4flags_stringlist_reset; @@ -608,6 +609,7 @@ static struct sieve_stringlist *ext_imap4flags_stringlist_create_single struct ext_imap4flags_stringlist *strlist; strlist = t_new(struct ext_imap4flags_stringlist, 1); + strlist->strlist.exec_status = SIEVE_EXEC_OK; strlist->strlist.runenv = renv; strlist->strlist.next_item = ext_imap4flags_stringlist_next_item; strlist->strlist.reset = ext_imap4flags_stringlist_reset; diff --git a/src/lib-sieve/plugins/imap4flags/tag-flags.c b/src/lib-sieve/plugins/imap4flags/tag-flags.c index 2cf116e61fbf238133c4cbd3ece9ec5215ddc514..fc7e708344462c578dbccdf9b07148abfa4b8d1e 100644 --- a/src/lib-sieve/plugins/imap4flags/tag-flags.c +++ b/src/lib-sieve/plugins/imap4flags/tag-flags.c @@ -57,7 +57,7 @@ const struct sieve_argument_def tag_flags_implicit = { static bool seff_flags_dump_context (const struct sieve_side_effect *seffect, const struct sieve_dumptime_env *denv, sieve_size_t *address); -static bool seff_flags_read_context +static int seff_flags_read_context (const struct sieve_side_effect *seffect, const struct sieve_runtime_env *renv, sieve_size_t *address, void **context); @@ -197,19 +197,19 @@ static bool seff_flags_dump_context (const struct sieve_side_effect *seffect ATTR_UNUSED, const struct sieve_dumptime_env *denv, sieve_size_t *address) { - struct sieve_operand operand; + struct sieve_operand oprnd; - if ( !sieve_operand_read(denv->sblock, address, &operand) ) { + if ( !sieve_operand_read(denv->sblock, address, "flags", &oprnd) ) { sieve_code_dumpf(denv, "ERROR: INVALID OPERAND"); return FALSE; } - if ( sieve_operand_is_omitted(&operand) ) { + if ( sieve_operand_is_omitted(&oprnd) ) { sieve_code_dumpf(denv, "flags: INTERNAL"); return TRUE; } - return sieve_opr_stringlist_dump_data(denv, &operand, address, "flags"); + return sieve_opr_stringlist_dump_data(denv, &oprnd, address, "flags"); } static struct seff_flags_context *seff_flags_get_implicit_context @@ -252,46 +252,46 @@ static struct seff_flags_context *seff_flags_get_implicit_context return ctx; } -static bool seff_flags_read_context +static int seff_flags_read_context (const struct sieve_side_effect *seffect, const struct sieve_runtime_env *renv, sieve_size_t *address, void **se_context) { - int ret; - struct sieve_operand operand; + struct sieve_operand oprnd; pool_t pool = sieve_result_pool(renv->result); struct seff_flags_context *ctx; string_t *flags_item; struct sieve_stringlist *flag_list; - - ctx = p_new(pool, struct seff_flags_context, 1); - p_array_init(&ctx->keywords, pool, 2); + int ret; t_push(); /* Check whether explicit flag list operand is present */ - if ( !sieve_operand_runtime_read(renv, address, NULL, &operand) ) { + if ( (ret=sieve_operand_runtime_read(renv, address, "flags", &oprnd)) <= 0 ) { t_pop(); - return FALSE; + return ret; } - if ( sieve_operand_is_omitted(&operand) ) { + if ( sieve_operand_is_omitted(&oprnd) ) { /* Flag list is omitted, use current value of internal * variable to construct side effect context. */ *se_context = seff_flags_get_implicit_context (SIEVE_OBJECT_EXTENSION(seffect), renv->result); t_pop(); - return TRUE; + return SIEVE_EXEC_OK; } /* Read flag-list */ - if ( (flag_list=sieve_opr_stringlist_read_data - (renv, &operand, address, NULL)) == NULL ) { + if ( (ret=sieve_opr_stringlist_read_data + (renv, &oprnd, address, NULL, &flag_list)) <= 0 ) { t_pop(); - return FALSE; + return ret; } + ctx = p_new(pool, struct seff_flags_context, 1); + p_array_init(&ctx->keywords, pool, 2); + /* Unpack */ flags_item = NULL; while ( (ret=sieve_stringlist_next_item(flag_list, &flags_item)) > 0 ) { @@ -328,7 +328,7 @@ static bool seff_flags_read_context t_pop(); - return ( ret >= 0 ); + return SIEVE_EXEC_OK; } /* Result verification */ diff --git a/src/lib-sieve/plugins/imap4flags/tst-hasflag.c b/src/lib-sieve/plugins/imap4flags/tst-hasflag.c index b6ea02ed51ef11b86d09fd57053a20beb2eb0f7e..a3e6837a1649b91a13fdd250f4000969828ae0ae 100644 --- a/src/lib-sieve/plugins/imap4flags/tst-hasflag.c +++ b/src/lib-sieve/plugins/imap4flags/tst-hasflag.c @@ -145,13 +145,13 @@ static bool tst_hasflag_operation_dump for (;;) { bool opok = TRUE; - int ret; + int opt; - if ( (ret=sieve_match_opr_optional_dump(denv, address, &opt_code)) + if ( (opt=sieve_match_opr_optional_dump(denv, address, &opt_code)) < 0 ) return FALSE; - if ( ret == 0 ) break; + if ( opt == 0 ) break; switch ( opt_code ) { case OPT_VARIABLES: @@ -181,7 +181,7 @@ static int tst_hasflag_operation_execute struct sieve_match_type mcht = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); struct sieve_stringlist *flag_list, *variables_list, *value_list, *key_list; - int ret; + int match, ret; /* * Read operands @@ -191,33 +191,32 @@ static int tst_hasflag_operation_execute variables_list = NULL; for (;;) { - bool opok = TRUE; + int opt; - if ( (ret=sieve_match_opr_optional_read - (renv, address, &opt_code, &cmp, &mcht)) < 0 ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (opt=sieve_match_opr_optional_read + (renv, address, &opt_code, &ret, &cmp, &mcht)) < 0 ) + return ret; - if ( ret == 0 ) break; + if ( opt == 0 ) break; switch ( opt_code ) { case OPT_VARIABLES: - variables_list = sieve_opr_stringlist_read - (renv, address, "variables-list"); - opok = ( variables_list != NULL ); + ret = sieve_opr_stringlist_read + (renv, address, "variables-list", &variables_list); break; default: sieve_runtime_trace_error(renv, "invalid optional operand"); - return SIEVE_EXEC_BIN_CORRUPT; + ret = SIEVE_EXEC_BIN_CORRUPT; } - if ( !opok ) return SIEVE_EXEC_BIN_CORRUPT; + if ( ret <= 0 ) return ret; } /* Fixed operands */ - if ( (flag_list=sieve_opr_stringlist_read(renv, address, "flag-list")) - == NULL ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_stringlist_read(renv, address, "flag-list", &flag_list)) + <= 0 ) + return ret; /* * Perform operation @@ -233,16 +232,13 @@ static int tst_hasflag_operation_execute else key_list = flag_list; - ret = sieve_match(renv, &mcht, &cmp, value_list, key_list); - - /* Assign test result */ - if ( ret >= 0 ) { - sieve_interpreter_set_test_result(renv->interp, ret > 0); - return SIEVE_EXEC_OK; - } - - sieve_runtime_trace_error(renv, "invalid string list item"); - return SIEVE_EXEC_BIN_CORRUPT; + /* Perform match */ + if ( (match=sieve_match(renv, &mcht, &cmp, value_list, key_list, &ret)) < 0 ) + return ret; + + /* Set test result for subsequent conditional jump */ + sieve_interpreter_set_test_result(renv->interp, match > 0); + return SIEVE_EXEC_OK; } diff --git a/src/lib-sieve/plugins/mailbox/tst-mailboxexists.c b/src/lib-sieve/plugins/mailbox/tst-mailboxexists.c index 972e987d7c5159b9542d659ba74b17dfbbbb3349..4c50b3f1962636eae687729f95c90f2aed36e1fc 100644 --- a/src/lib-sieve/plugins/mailbox/tst-mailboxexists.c +++ b/src/lib-sieve/plugins/mailbox/tst-mailboxexists.c @@ -111,15 +111,16 @@ static int tst_mailboxexists_operation_execute string_t *mailbox_item; bool trace = FALSE; bool all_exist = TRUE; + int ret; /* * Read operands */ /* Read notify uris */ - if ( (mailbox_names=sieve_opr_stringlist_read(renv, address, "mailbox-names")) - == NULL ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_stringlist_read + (renv, address, "mailbox-names", &mailbox_names)) <= 0 ) + return ret; /* * Perform operation diff --git a/src/lib-sieve/plugins/notify/cmd-denotify.c b/src/lib-sieve/plugins/notify/cmd-denotify.c index 0a920006ddec43ae4032d0a84c6d77385bafeb9f..5c68d9de330c6d25691bb97730c0fb8a3711ed21 100644 --- a/src/lib-sieve/plugins/notify/cmd-denotify.c +++ b/src/lib-sieve/plugins/notify/cmd-denotify.c @@ -239,13 +239,13 @@ static bool cmd_denotify_operation_dump sieve_code_descend(denv); for (;;) { - int ret; + int opt; bool opok = TRUE; - if ( (ret=sieve_opr_optional_dump(denv, address, &opt_code)) < 0 ) + if ( (opt=sieve_opr_optional_dump(denv, address, &opt_code)) < 0 ) return FALSE; - if ( ret == 0 ) break; + if ( opt == 0 ) break; switch ( opt_code ) { case OPT_MATCH_KEY: @@ -274,7 +274,6 @@ static bool cmd_denotify_operation_dump static int cmd_denotify_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { - bool result = TRUE; int opt_code = 0; struct sieve_match_type mcht = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); @@ -294,31 +293,29 @@ static int cmd_denotify_operation_execute /* Optional operands */ for (;;) { - bool opok = TRUE; - int ret; + int opt; - if ( (ret=sieve_opr_optional_read(renv, address, &opt_code)) < 0 ) + if ( (opt=sieve_opr_optional_read(renv, address, &opt_code)) < 0 ) return SIEVE_EXEC_BIN_CORRUPT; - if ( ret == 0 ) break; + if ( opt == 0 ) break; switch ( opt_code ) { case OPT_MATCH_TYPE: - opok = sieve_opr_match_type_read(renv, address, &mcht); + ret = sieve_opr_match_type_read(renv, address, &mcht); break; case OPT_MATCH_KEY: - match_key = sieve_opr_stringlist_read(renv, address, "match key"); - opok = ( match_key != NULL ); + ret = sieve_opr_stringlist_read(renv, address, "match key", &match_key); break; case OPT_IMPORTANCE: - opok = sieve_opr_number_read(renv, address, "importance", &importance); + ret = sieve_opr_number_read(renv, address, "importance", &importance); break; default: sieve_runtime_trace_error(renv, "unknown optional operand"); return SIEVE_EXEC_BIN_CORRUPT; } - if ( !opok ) return SIEVE_EXEC_BIN_CORRUPT; + if ( ret <= 0 ) return ret; } /* @@ -337,46 +334,40 @@ static int cmd_denotify_operation_execute sieve_runtime_trace(renv, SIEVE_TRLVL_ACTIONS, "denotify action"); /* Either do string matching or just kill all notify actions */ - if ( match_key != NULL ) { - + if ( match_key != NULL ) { /* Initialize match */ mctx = sieve_match_begin(renv, &mcht, &cmp); - /* Iterate through all actions */ + /* Iterate through all notify actions and delete those that match */ rictx = sieve_result_iterate_init(renv->result); - while ( result && - (action=sieve_result_iterate_next(rictx, NULL)) != NULL ) { + while ( (action=sieve_result_iterate_next(rictx, NULL)) != NULL ) { if ( sieve_action_is(action, act_notify_old) ) { struct ext_notify_action *nact = (struct ext_notify_action *) action->context; if ( importance == 0 || nact->importance == importance ) { - if ( (ret=sieve_match_value - (mctx, nact->id, strlen(nact->id), match_key)) < 0 ) { - result = FALSE; + int match; + + if ( (match=sieve_match_value + (mctx, nact->id, strlen(nact->id), match_key)) < 0 ) break; - } - if ( ret > 0 ) + if ( match > 0 ) sieve_result_iterate_delete(rictx); } } } /* Finish match */ - (void)sieve_match_end(&mctx); - - if ( !result ) { - sieve_runtime_trace_error(renv, "invalid string-list item"); - return SIEVE_EXEC_BIN_CORRUPT; - } + if ( sieve_match_end(&mctx, &ret) < 0 ) + return ret; + } else { - /* Iterate through all actions */ + /* Delete all notify actions */ rictx = sieve_result_iterate_init(renv->result); - while ( result && - (action=sieve_result_iterate_next(rictx, NULL)) != NULL ) { + while ( (action=sieve_result_iterate_next(rictx, NULL)) != NULL ) { if ( sieve_action_is(action, act_notify_old) ) { struct ext_notify_action *nact = diff --git a/src/lib-sieve/plugins/notify/cmd-notify.c b/src/lib-sieve/plugins/notify/cmd-notify.c index e0e03ba76b7eee27b80dfb8fab9d9d4cd687bbf5..b50620b08ab178b58c3bb27b8fa19d88bc857310 100644 --- a/src/lib-sieve/plugins/notify/cmd-notify.c +++ b/src/lib-sieve/plugins/notify/cmd-notify.c @@ -374,13 +374,13 @@ static bool cmd_notify_operation_dump /* Dump optional operands */ for (;;) { - int ret; + int opt; bool opok = TRUE; - if ( (ret=sieve_opr_optional_dump(denv, address, &opt_code)) < 0 ) + if ( (opt=sieve_opr_optional_dump(denv, address, &opt_code)) < 0 ) return FALSE; - if ( ret == 0 ) break; + if ( opt == 0 ) break; switch ( opt_code ) { case OPT_IMPORTANCE: @@ -421,6 +421,7 @@ static int cmd_notify_operation_execute struct sieve_stringlist *options = NULL; string_t *message = NULL, *id = NULL; unsigned int source_line; + int ret; /* * Read operands @@ -433,34 +434,32 @@ static int cmd_notify_operation_execute /* Optional operands */ for (;;) { - bool opok = TRUE; - int ret; + int opt; - if ( (ret=sieve_opr_optional_read(renv, address, &opt_code)) < 0 ) + if ( (opt=sieve_opr_optional_read(renv, address, &opt_code)) < 0 ) return SIEVE_EXEC_BIN_CORRUPT; - if ( ret == 0 ) break; + if ( opt == 0 ) break; switch ( opt_code ) { case OPT_IMPORTANCE: - opok = sieve_opr_number_read(renv, address, "importance", &importance); + ret = sieve_opr_number_read(renv, address, "importance", &importance); break; case OPT_ID: - opok = sieve_opr_string_read(renv, address, "id", &id); + ret = sieve_opr_string_read(renv, address, "id", &id); break; case OPT_MESSAGE: - opok = sieve_opr_string_read(renv, address, "from", &message); + ret = sieve_opr_string_read(renv, address, "from", &message); break; case OPT_OPTIONS: - options = sieve_opr_stringlist_read(renv, address, "options"); - opok = ( options != NULL ); + ret = sieve_opr_stringlist_read(renv, address, "options", &options); break; default: sieve_runtime_trace_error(renv, "unknown optional operand"); return SIEVE_EXEC_BIN_CORRUPT; } - if ( !opok ) return SIEVE_EXEC_BIN_CORRUPT; + if ( ret <= 0 ) return ret; } /* @@ -562,9 +561,10 @@ static int cmd_notify_operation_execute return SIEVE_EXEC_BIN_CORRUPT; } - return ( sieve_result_add_action + if ( sieve_result_add_action (renv, this_ext, &act_notify_old, NULL, source_line, (void *) act, 0) - >= 0 ); + < 0 ) + return SIEVE_EXEC_FAILURE; } return SIEVE_EXEC_OK; diff --git a/src/lib-sieve/plugins/regex/mcht-regex.c b/src/lib-sieve/plugins/regex/mcht-regex.c index dd98841c9ae721752ebe5b3c8c52fd6c10b601bd..ea70c23dea2b310b08df90362b1c4abd565f17bf 100644 --- a/src/lib-sieve/plugins/regex/mcht-regex.c +++ b/src/lib-sieve/plugins/regex/mcht-regex.c @@ -267,7 +267,7 @@ static int mcht_regex_match_keys bool trace = sieve_runtime_trace_active(renv, SIEVE_TRLVL_MATCHING); struct mcht_regex_context *ctx = (struct mcht_regex_context *) mctx->data; const struct sieve_comparator *cmp = mctx->comparator; - int result = 0; + int match; if ( !ctx->all_compiled ) { string_t *key_item = NULL; @@ -280,7 +280,8 @@ static int mcht_regex_match_keys p_array_init(&ctx->reg_expressions, mctx->pool, 16); i = 0; - while ( result == 0 && + match = 0; + while ( match == 0 && (ret=sieve_stringlist_next_item(key_list, &key_item)) > 0 ) { T_BEGIN { @@ -316,13 +317,13 @@ static int mcht_regex_match_keys } if ( rkey->status > 0 ) { - result = mcht_regex_match_key(mctx, val, &rkey->regexp); + match = mcht_regex_match_key(mctx, val, &rkey->regexp); if ( trace ) { sieve_runtime_trace(renv, 0, "with regex `%s' [id=%d] => %d", str_sanitize(str_c(key_item), 80), - array_count(&ctx->reg_expressions)-1, result); + array_count(&ctx->reg_expressions)-1, match); } } } T_END; @@ -330,7 +331,12 @@ static int mcht_regex_match_keys i++; } - if ( ret < 0 ) result = -1; + if ( ret == 0 ) { + ctx->all_compiled = TRUE; + } else if ( ret < 0 ) { + mctx->exec_status = key_list->exec_status; + match = -1; + } } else { const struct mcht_regex_key *rkeys; @@ -340,24 +346,23 @@ static int mcht_regex_match_keys rkeys = array_get(&ctx->reg_expressions, &count); - i = 0; - while ( result == 0 && i < count ) { + i = 0; + match = 0; + while ( match == 0 && i < count ) { if ( rkeys[i].status > 0 ) { - result = mcht_regex_match_key(mctx, val, &rkeys[i].regexp); + match = mcht_regex_match_key(mctx, val, &rkeys[i].regexp); if ( trace ) { sieve_runtime_trace(renv, 0, - "with compiled regex [id=%d] => %d", i, result); + "with compiled regex [id=%d] => %d", i, match); } } i++; } - - if ( i == count ) ctx->all_compiled = TRUE; } - return result; + return match; } void mcht_regex_match_deinit diff --git a/src/lib-sieve/plugins/relational/mcht-count.c b/src/lib-sieve/plugins/relational/mcht-count.c index 98b417319c76f54b577737d08681a4eb41e626e0..e4c45809a289646ea2260f5645a2c9ec4bf3771c 100644 --- a/src/lib-sieve/plugins/relational/mcht-count.c +++ b/src/lib-sieve/plugins/relational/mcht-count.c @@ -71,10 +71,12 @@ static int mcht_count_match bool trace = sieve_runtime_trace_active(renv, SIEVE_TRLVL_MATCHING); int count; string_t *key_item; - int ret; + int match, ret; - if ( (count=sieve_stringlist_get_length(value_list)) < 0 ) + if ( (count=sieve_stringlist_get_length(value_list)) < 0 ) { + mctx->exec_status = value_list->exec_status; return -1; + } sieve_stringlist_reset(key_list); @@ -90,11 +92,11 @@ static int mcht_count_match /* Match to all key values */ key_item = NULL; - ret = 0; - while ( ret == 0 && + match = 0; + while ( match == 0 && (ret=sieve_stringlist_next_item(key_list, &key_item)) > 0 ) { - ret = mcht_value_match_key + match = mcht_value_match_key (mctx, str_c(value), str_len(value), str_c(key_item), str_len(key_item)); if ( trace ) { @@ -105,7 +107,12 @@ static int mcht_count_match sieve_runtime_trace_ascend(renv); - return ret; + if ( ret < 0 ) { + mctx->exec_status = key_list->exec_status; + match = -1; + } + + return match; } diff --git a/src/lib-sieve/plugins/spamvirustest/tst-spamvirustest.c b/src/lib-sieve/plugins/spamvirustest/tst-spamvirustest.c index cda0a3e3a33b44f6c4cdca0334ed42340834d8d7..8a977724405913480b1d84400e330d64970c2c99 100644 --- a/src/lib-sieve/plugins/spamvirustest/tst-spamvirustest.c +++ b/src/lib-sieve/plugins/spamvirustest/tst-spamvirustest.c @@ -213,12 +213,12 @@ static bool tst_spamvirustest_operation_dump /* Optional operands */ for (;;) { - int ret; + int opt; - if ( (ret=sieve_match_opr_optional_dump(denv, address, &opt_code)) < 0 ) + if ( (opt=sieve_match_opr_optional_dump(denv, address, &opt_code)) < 0 ) return FALSE; - if ( ret == 0 ) break; + if ( opt == 0 ) break; switch ( opt_code ) { case OPT_SPAMTEST_PERCENT: @@ -250,17 +250,17 @@ static int tst_spamvirustest_operation_execute bool percent = FALSE; struct sieve_stringlist *value_list, *key_list; const char *score_value; - int ret; + int match, ret; /* Read optional operands */ for (;;) { - int ret; + int opt; - if ( (ret=sieve_match_opr_optional_read - (renv, address, &opt_code, &cmp, &mcht)) < 0 ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (opt=sieve_match_opr_optional_read + (renv, address, &opt_code, &ret, &cmp, &mcht)) < 0 ) + return ret; - if ( ret == 0 ) break; + if ( opt == 0 ) break; switch ( opt_code ) { case OPT_SPAMTEST_PERCENT: @@ -273,8 +273,8 @@ static int tst_spamvirustest_operation_execute } /* Read value part */ - if ( (key_list=sieve_opr_stringlist_read(renv, address, "value")) == NULL ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_stringlist_read(renv, address, "value", &key_list)) <= 0 ) + return ret; /* Perform test */ @@ -294,14 +294,10 @@ static int tst_spamvirustest_operation_execute value_list = sieve_single_stringlist_create_cstr(renv, score_value, TRUE); /* Perform match */ - ret = sieve_match(renv, &mcht, &cmp, value_list, key_list); + if ( (match=sieve_match(renv, &mcht, &cmp, value_list, key_list, &ret)) < 0 ) + return ret; /* Set test result for subsequent conditional jump */ - if ( ret >= 0 ) { - sieve_interpreter_set_test_result(renv->interp, ret > 0); - return SIEVE_EXEC_OK; - } - - sieve_runtime_trace_error(renv, "invalid string-list item"); - return SIEVE_EXEC_BIN_CORRUPT; + sieve_interpreter_set_test_result(renv->interp, match > 0); + return SIEVE_EXEC_OK; } diff --git a/src/lib-sieve/plugins/vacation/cmd-vacation.c b/src/lib-sieve/plugins/vacation/cmd-vacation.c index ec2d452f8ffdb77a58ebcf8cd4a77630a2bfe6f2..45736768e03400db214edd25a8537a57f589e0e8 100644 --- a/src/lib-sieve/plugins/vacation/cmd-vacation.c +++ b/src/lib-sieve/plugins/vacation/cmd-vacation.c @@ -491,13 +491,13 @@ static bool ext_vacation_operation_dump /* Dump optional operands */ for (;;) { - int ret; + int opt; bool opok = TRUE; - if ( (ret=sieve_opr_optional_dump(denv, address, &opt_code)) < 0 ) + if ( (opt=sieve_opr_optional_dump(denv, address, &opt_code)) < 0 ) return FALSE; - if ( ret == 0 ) break; + if ( opt == 0 ) break; switch ( opt_code ) { case OPT_DAYS: @@ -546,6 +546,7 @@ static int ext_vacation_operation_execute string_t *reason, *subject = NULL, *from = NULL, *handle = NULL; unsigned int source_line; const char *from_normalized = NULL; + int ret; /* * Read code @@ -558,44 +559,43 @@ static int ext_vacation_operation_execute /* Optional operands */ for (;;) { - bool opok = TRUE; - int ret; + int opt; - if ( (ret=sieve_opr_optional_read(renv, address, &opt_code)) < 0 ) + if ( (opt=sieve_opr_optional_read(renv, address, &opt_code)) < 0 ) return SIEVE_EXEC_BIN_CORRUPT; - if ( ret == 0 ) break; + if ( opt == 0 ) break; switch ( opt_code ) { case OPT_DAYS: - opok = sieve_opr_number_read(renv, address, "days", &days); + ret = sieve_opr_number_read(renv, address, "days", &days); break; case OPT_SUBJECT: - opok = sieve_opr_string_read(renv, address, "subject", &subject); + ret = sieve_opr_string_read(renv, address, "subject", &subject); break; case OPT_FROM: - opok = sieve_opr_string_read(renv, address, "from", &from); + ret = sieve_opr_string_read(renv, address, "from", &from); break; case OPT_ADDRESSES: - addresses = sieve_opr_stringlist_read(renv, address, "addresses"); - opok = ( addresses != NULL ); + ret = sieve_opr_stringlist_read(renv, address, "addresses", &addresses); break; case OPT_MIME: mime = TRUE; + ret = SIEVE_EXEC_OK; break; default: sieve_runtime_trace_error(renv, "unknown optional operand"); - opok = FALSE; + ret = SIEVE_EXEC_BIN_CORRUPT; } - if ( !opok ) return SIEVE_EXEC_BIN_CORRUPT; + if ( ret <= 0 ) return ret; } /* Fixed operands */ - if ( !sieve_opr_string_read(renv, address, "reason", &reason) || - !sieve_opr_string_read(renv, address, "handle", &handle) ) { - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_string_read(renv, address, "reason", &reason)) <= 0 || + (ret=sieve_opr_string_read(renv, address, "handle", &handle)) <= 0 ) { + return ret; } /* @@ -678,8 +678,11 @@ static int ext_vacation_operation_execute act->addresses = array_idx(&norm_addresses, 0); } - return ( sieve_result_add_action - (renv, this_ext, &act_vacation, slist, source_line, (void *) act, 0) >= 0 ); + if ( sieve_result_add_action + (renv, this_ext, &act_vacation, slist, source_line, (void *) act, 0) < 0 ) + return SIEVE_EXEC_FAILURE; + + return SIEVE_EXEC_OK; } /* diff --git a/src/lib-sieve/plugins/variables/cmd-set.c b/src/lib-sieve/plugins/variables/cmd-set.c index aafcb523e134436502cae8621c3ae379205c59cb..d2ec4cb486dfee874d2c9abe84c44790662121d8 100644 --- a/src/lib-sieve/plugins/variables/cmd-set.c +++ b/src/lib-sieve/plugins/variables/cmd-set.c @@ -291,12 +291,12 @@ static int cmd_set_operation_execute * Read the normal operands */ - if ( !sieve_variable_operand_read - (renv, address, "variable", &storage, &var_index) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_variable_operand_read + (renv, address, "variable", &storage, &var_index)) <= 0 ) + return ret; - if ( !sieve_opr_string_read(renv, address, "string", &value) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_string_read(renv, address, "string", &value)) <= 0 ) + return ret; if ( !sieve_binary_read_byte(renv->sblock, address, &mdfs) ) { sieve_runtime_trace_error(renv, "invalid modifier count"); @@ -367,10 +367,10 @@ static int cmd_set_operation_execute } } T_END; - if ( ret <= 0 ) - return ret; + if ( ret <= 0 ) return ret; + if ( value == NULL ) return SIEVE_EXEC_FAILURE; - return ( value != NULL ); + return SIEVE_EXEC_OK; } diff --git a/src/lib-sieve/plugins/variables/ext-variables-namespaces.c b/src/lib-sieve/plugins/variables/ext-variables-namespaces.c index 2f8897de9922a67f1a765d1fe56c9addb7fccdeb..9ee1aec0a147240a7992db7927fe771d5ceb8383 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-namespaces.c +++ b/src/lib-sieve/plugins/variables/ext-variables-namespaces.c @@ -157,12 +157,12 @@ static bool arg_namespace_generate const struct sieve_operand_class sieve_variables_namespace_operand_class = { "variable-namespace" }; -static bool opr_namespace_variable_read - (const struct sieve_runtime_env *renv, const struct sieve_operand *operand, - sieve_size_t *address, string_t **str); static bool opr_namespace_variable_dump - (const struct sieve_dumptime_env *denv, const struct sieve_operand *operand, - sieve_size_t *address, const char *field_name); + (const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, + sieve_size_t *address); +static int opr_namespace_variable_read + (const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, + sieve_size_t *address, string_t **str_r); static const struct sieve_opr_string_interface namespace_variable_interface = { opr_namespace_variable_dump, @@ -186,39 +186,19 @@ void sieve_variables_opr_namespace_variable_emit sieve_opr_object_emit(sblock, ext, &nspc_def->obj_def); } -static bool opr_namespace_variable_read -(const struct sieve_runtime_env *renv, - const struct sieve_operand *operand ATTR_UNUSED, - sieve_size_t *address, string_t **str) -{ - struct sieve_variables_namespace nspc; - - if ( !sieve_opr_object_read - (renv, &sieve_variables_namespace_operand_class, address, &nspc.object) ) - return FALSE; - - nspc.def = (const struct sieve_variables_namespace_def *) nspc.object.def; - - if ( nspc.def == NULL || nspc.def->read_variable == NULL ) - return FALSE; - - return nspc.def->read_variable(renv, &nspc, address, str); -} - static bool opr_namespace_variable_dump -(const struct sieve_dumptime_env *denv, - const struct sieve_operand *operand ATTR_UNUSED, - sieve_size_t *address, const char *field_name) +(const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, + sieve_size_t *address) { struct sieve_variables_namespace nspc; - struct sieve_operand oprnd; + struct sieve_operand nsoprnd; - if ( !sieve_operand_read(denv->sblock, address, &oprnd) ) { + if ( !sieve_operand_read(denv->sblock, address, NULL, &nsoprnd) ) { return FALSE; } if ( !sieve_opr_object_read_data - (denv->sblock, &oprnd, &sieve_variables_namespace_operand_class, address, + (denv->sblock, &nsoprnd, &sieve_variables_namespace_operand_class, address, &nspc.object) ) { return FALSE; } @@ -228,7 +208,28 @@ static bool opr_namespace_variable_dump if ( nspc.def == NULL || nspc.def->dump_variable == NULL ) return FALSE; - return nspc.def->dump_variable(denv, &nspc, address, field_name); + return nspc.def->dump_variable(denv, &nspc, oprnd, address); +} + +static int opr_namespace_variable_read +(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, + sieve_size_t *address, string_t **str_r) +{ + struct sieve_variables_namespace nspc; + + if ( !sieve_opr_object_read + (renv, &sieve_variables_namespace_operand_class, address, &nspc.object) ) { + sieve_runtime_trace_operand_error(renv, oprnd, + "variable namespace operand corrupt: failed to read"); + return SIEVE_EXEC_BIN_CORRUPT; + } + + nspc.def = (const struct sieve_variables_namespace_def *) nspc.object.def; + + if ( nspc.def == NULL || nspc.def->read_variable == NULL ) + return SIEVE_EXEC_FAILURE; + + return nspc.def->read_variable(renv, &nspc, oprnd, address, str_r); } diff --git a/src/lib-sieve/plugins/variables/ext-variables-operands.c b/src/lib-sieve/plugins/variables/ext-variables-operands.c index 11ef017317fb658d08d794958a9141ef0adc1147..0e294d8e5ce19a8f36fda436f34260b29bbf464f 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-operands.c +++ b/src/lib-sieve/plugins/variables/ext-variables-operands.c @@ -28,12 +28,12 @@ * Variable operand */ -static bool opr_variable_read_value - (const struct sieve_runtime_env *renv, const struct sieve_operand *operand, - sieve_size_t *address, string_t **str); static bool opr_variable_dump - (const struct sieve_dumptime_env *denv, const struct sieve_operand *operand, - sieve_size_t *address, const char *field_name); + (const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, + sieve_size_t *address); +static int opr_variable_read_value + (const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, + sieve_size_t *address, string_t **str_r); const struct sieve_opr_string_interface variable_interface = { opr_variable_dump, @@ -66,10 +66,10 @@ void sieve_variables_opr_variable_emit } static bool opr_variable_dump -(const struct sieve_dumptime_env *denv, const struct sieve_operand *operand, - sieve_size_t *address, const char *field_name) +(const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, + sieve_size_t *address) { - const struct sieve_extension *this_ext = operand->ext; + const struct sieve_extension *this_ext = oprnd->ext; unsigned int index = 0; const struct sieve_extension *ext; unsigned int code = 1; /* Initially set to offset value */ @@ -84,9 +84,9 @@ static bool opr_variable_dump identifier = ext_variables_dump_get_identifier(this_ext, denv, ext, index); identifier = identifier == NULL ? "??" : identifier; - if ( field_name != NULL ) + if ( oprnd->field_name != NULL ) sieve_code_dumpf(denv, "%s: VAR[%s] ${%s}", - field_name, sieve_ext_variables_get_varid(ext, index), identifier); + oprnd->field_name, sieve_ext_variables_get_varid(ext, index), identifier); else sieve_code_dumpf(denv, "VAR[%s] ${%s}", sieve_ext_variables_get_varid(ext, index), identifier); @@ -94,104 +94,116 @@ static bool opr_variable_dump return TRUE; } -static bool opr_variable_read_value -(const struct sieve_runtime_env *renv, const struct sieve_operand *operand, - sieve_size_t *address, string_t **str) +static int opr_variable_read_value +(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, + sieve_size_t *address, string_t **str_r) { - const struct sieve_extension *this_ext = operand->ext; + const struct sieve_extension *this_ext = oprnd->ext; const struct sieve_extension *ext; unsigned int code = 1; /* Initially set to offset value */ struct sieve_variable_storage *storage; unsigned int index = 0; - if ( !sieve_binary_read_extension(renv->sblock, address, &code, &ext) ) - return FALSE; + if ( !sieve_binary_read_extension(renv->sblock, address, &code, &ext) ) { + sieve_runtime_trace_operand_error(renv, oprnd, + "variable operand corrupt: invalid extension byte"); + return SIEVE_EXEC_BIN_CORRUPT; + } storage = sieve_ext_variables_runtime_get_storage (this_ext, renv, ext); - if ( storage == NULL ) - return FALSE; + if ( storage == NULL ) { + sieve_runtime_trace_operand_error(renv, oprnd, + "variable operand corrupt: extension has no storage"); + return SIEVE_EXEC_BIN_CORRUPT; + } - if (sieve_binary_read_unsigned(renv->sblock, address, &index) ) { + if ( sieve_binary_read_unsigned(renv->sblock, address, &index) ) { /* Parameter str can be NULL if we are requested to only skip and not * actually read the argument. */ - if ( str != NULL ) { - if ( !sieve_variable_get(storage, index, str) ) - return FALSE; + if ( str_r != NULL ) { + if ( !sieve_variable_get(storage, index, str_r) ) + return SIEVE_EXEC_FAILURE; - if ( *str == NULL ) *str = t_str_new(0); + if ( *str_r == NULL ) *str_r = t_str_new(0); } - return TRUE; + + return SIEVE_EXEC_OK; } - return FALSE; + sieve_runtime_trace_operand_error(renv, oprnd, + "variable operand corrupt: invalid variable index"); + return SIEVE_EXEC_BIN_CORRUPT; } -bool sieve_variable_operand_read_data -(const struct sieve_runtime_env *renv, const struct sieve_operand *operand, - sieve_size_t *address, const char *field_name, - struct sieve_variable_storage **storage, unsigned int *var_index) +int sieve_variable_operand_read_data +(const struct sieve_runtime_env *renv, struct sieve_operand *oprnd, + sieve_size_t *address, const char *field_name, + struct sieve_variable_storage **storage_r, unsigned int *var_index_r) { const struct sieve_extension *ext; unsigned int code = 1; /* Initially set to offset value */ unsigned int idx = 0; + + oprnd->field_name = field_name; - if ( !sieve_operand_is_variable(operand) ) { - sieve_runtime_trace_operand_error - (renv, operand, field_name, "expected variable operand but found %s", - sieve_operand_name(operand)); - return FALSE; + if ( !sieve_operand_is_variable(oprnd) ) { + sieve_runtime_trace_operand_error(renv, oprnd, + "expected variable operand but found %s", sieve_operand_name(oprnd)); + return SIEVE_EXEC_BIN_CORRUPT; } if ( !sieve_binary_read_extension(renv->sblock, address, &code, &ext) ) { - sieve_runtime_trace_operand_error - (renv, operand, field_name, "variable operand: failed to read extension"); - return FALSE; + sieve_runtime_trace_operand_error(renv, oprnd, + "variable operand corrupt: invalid extension byte"); + return SIEVE_EXEC_BIN_CORRUPT; } - *storage = sieve_ext_variables_runtime_get_storage - (operand->ext, renv, ext); - if ( *storage == NULL ) { - sieve_runtime_trace_operand_error(renv, operand, field_name, - "variable operand: failed to get variable storage"); - return FALSE; + *storage_r = sieve_ext_variables_runtime_get_storage + (oprnd->ext, renv, ext); + if ( *storage_r == NULL ) { + sieve_runtime_trace_operand_error(renv, oprnd, + "variable operand corrupt: extension has no storage"); + return SIEVE_EXEC_BIN_CORRUPT; } if ( !sieve_binary_read_unsigned(renv->sblock, address, &idx) ) { - sieve_runtime_trace_operand_error - (renv, operand, field_name, "variable operand: failed to read index"); - return FALSE; + sieve_runtime_trace_operand_error(renv, oprnd, + "variable operand corrupt: invalid variable index"); + return SIEVE_EXEC_BIN_CORRUPT; } - *var_index = idx; - return TRUE; + *var_index_r = idx; + return SIEVE_EXEC_OK; } -bool sieve_variable_operand_read +int sieve_variable_operand_read (const struct sieve_runtime_env *renv, sieve_size_t *address, - const char *field_name, struct sieve_variable_storage **storage, - unsigned int *var_index) + const char *field_name, struct sieve_variable_storage **storage_r, + unsigned int *var_index_r) { struct sieve_operand operand; + int ret; - if ( !sieve_operand_runtime_read(renv, address, field_name, &operand) ) - return FALSE; + if ( (ret=sieve_operand_runtime_read(renv, address, field_name, &operand)) + <= 0) + return ret; return sieve_variable_operand_read_data - (renv, &operand, address, field_name, storage, var_index); + (renv, &operand, address, field_name, storage_r, var_index_r); } /* * Match value operand */ -static bool opr_match_value_read - (const struct sieve_runtime_env *renv, const struct sieve_operand *operand, - sieve_size_t *address, string_t **str); static bool opr_match_value_dump - (const struct sieve_dumptime_env *denv, const struct sieve_operand *operand, - sieve_size_t *address, const char *field_name); + (const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, + sieve_size_t *address); +static int opr_match_value_read + (const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, + sieve_size_t *address, string_t **str_r); const struct sieve_opr_string_interface match_value_interface = { opr_match_value_dump, @@ -215,16 +227,15 @@ void sieve_variables_opr_match_value_emit } static bool opr_match_value_dump -(const struct sieve_dumptime_env *denv, - const struct sieve_operand *operand ATTR_UNUSED, - sieve_size_t *address, const char *field_name) +(const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, + sieve_size_t *address) { unsigned int index = 0; if (sieve_binary_read_unsigned(denv->sblock, address, &index) ) { - if ( field_name != NULL ) + if ( oprnd->field_name != NULL ) sieve_code_dumpf - (denv, "%s: MATCHVAL %lu", field_name, (unsigned long) index); + (denv, "%s: MATCHVAL %lu", oprnd->field_name, (unsigned long) index); else sieve_code_dumpf(denv, "MATCHVAL %lu", (unsigned long) index); @@ -234,27 +245,29 @@ static bool opr_match_value_dump return FALSE; } -static bool opr_match_value_read -(const struct sieve_runtime_env *renv, - const struct sieve_operand *operand ATTR_UNUSED, - sieve_size_t *address, string_t **str) +static int opr_match_value_read +(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, + sieve_size_t *address, string_t **str_r) { unsigned int index = 0; - if (sieve_binary_read_unsigned(renv->sblock, address, &index) ) { + if ( sieve_binary_read_unsigned(renv->sblock, 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, index, str); + if ( str_r != NULL ) { + sieve_match_values_get(renv, index, str_r); - if ( *str == NULL ) - *str = t_str_new(0); - else if ( str_len(*str) > EXT_VARIABLES_MAX_VARIABLE_SIZE ) - str_truncate(*str, EXT_VARIABLES_MAX_VARIABLE_SIZE); + if ( *str_r == NULL ) + *str_r = t_str_new(0); + else if ( str_len(*str_r) > EXT_VARIABLES_MAX_VARIABLE_SIZE ) + str_truncate(*str_r, EXT_VARIABLES_MAX_VARIABLE_SIZE); } - return TRUE; + + return SIEVE_EXEC_OK; } - return FALSE; + sieve_runtime_trace_operand_error(renv, oprnd, + "match value operand corrupt: invalid index data"); + return SIEVE_EXEC_BIN_CORRUPT; } diff --git a/src/lib-sieve/plugins/variables/sieve-ext-variables.h b/src/lib-sieve/plugins/variables/sieve-ext-variables.h index 5ef1e9f1d51d5ba50e629d48b46bb2cbd3854aaa..6d1f74ecc9cf16fb2701d47fdc3c892b710aaaef 100644 --- a/src/lib-sieve/plugins/variables/sieve-ext-variables.h +++ b/src/lib-sieve/plugins/variables/sieve-ext-variables.h @@ -121,14 +121,14 @@ struct sieve_variables_namespace_def { struct sieve_ast_argument *arg, struct sieve_command *cmd, void *var_data); - bool (*read_variable) - (const struct sieve_runtime_env *renv, - const struct sieve_variables_namespace *nspc, sieve_size_t *address, - string_t **str); bool (*dump_variable) (const struct sieve_dumptime_env *denv, - const struct sieve_variables_namespace *nspc, sieve_size_t *address, - const char *field_name); + const struct sieve_variables_namespace *nspc, + const struct sieve_operand *oprnd, sieve_size_t *address); + int (*read_variable) + (const struct sieve_runtime_env *renv, + const struct sieve_variables_namespace *nspc, + const struct sieve_operand *oprnd, sieve_size_t *address, string_t **str); }; #define SIEVE_VARIABLES_DEFINE_NAMESPACE(OP) SIEVE_EXT_DEFINE_OBJECT(OP) @@ -251,14 +251,14 @@ void sieve_variables_opr_match_value_emit (struct sieve_binary_block *sblock, const struct sieve_extension *var_ext, unsigned int index); -bool sieve_variable_operand_read_data - (const struct sieve_runtime_env *renv, const struct sieve_operand *operand, +int sieve_variable_operand_read_data + (const struct sieve_runtime_env *renv, struct sieve_operand *operand, sieve_size_t *address, const char *field_name, - struct sieve_variable_storage **storage, unsigned int *var_index); -bool sieve_variable_operand_read + struct sieve_variable_storage **storage_r, unsigned int *var_index_r); +int sieve_variable_operand_read (const struct sieve_runtime_env *renv, sieve_size_t *address, - const char *field_name, struct sieve_variable_storage **storage, - unsigned int *var_index); + const char *field_name, struct sieve_variable_storage **storage_r, + unsigned int *var_index_r); static inline bool sieve_operand_is_variable (const struct sieve_operand *operand) diff --git a/src/lib-sieve/plugins/variables/tst-string.c b/src/lib-sieve/plugins/variables/tst-string.c index b4184f1ec005d6b9c66849392de01e70783bb1eb..5d7f0bdd6f5d506120182b4347049c8e0ae414a0 100644 --- a/src/lib-sieve/plugins/variables/tst-string.c +++ b/src/lib-sieve/plugins/variables/tst-string.c @@ -143,13 +143,11 @@ static bool tst_string_generate static bool tst_string_operation_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address) { - int opt_code = 0; - sieve_code_dumpf(denv, "STRING-TEST"); sieve_code_descend(denv); /* Optional operands */ - if ( sieve_match_opr_optional_dump(denv, address, &opt_code) != 0 ) + if ( sieve_match_opr_optional_dump(denv, address, NULL) != 0 ) return FALSE; return @@ -181,6 +179,7 @@ static struct sieve_stringlist *tst_string_stringlist_create strlist = t_new(struct tst_string_stringlist, 1); strlist->strlist.runenv = renv; + strlist->strlist.exec_status = SIEVE_EXEC_OK; strlist->strlist.next_item = tst_string_stringlist_next_item; strlist->strlist.reset = tst_string_stringlist_reset; strlist->strlist.get_length = tst_string_stringlist_get_length; @@ -227,36 +226,30 @@ static int tst_string_stringlist_get_length static int tst_string_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { - int ret; - int opt_code = 0; struct sieve_match_type mcht = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); struct sieve_comparator cmp = SIEVE_COMPARATOR_DEFAULT(i_octet_comparator); struct sieve_stringlist *source, *value_list, *key_list; + int match, ret; /* * Read operands */ /* Handle match-type and comparator operands */ - if ( (ret=sieve_match_opr_optional_read - (renv, address, &opt_code, &cmp, &mcht)) < 0 ) - return SIEVE_EXEC_BIN_CORRUPT; - - /* Check whether we neatly finished the list of optional operands*/ - if ( ret > 0 ) { - sieve_runtime_trace_error(renv, "invalid optional operand"); - return SIEVE_EXEC_BIN_CORRUPT; - } + if ( sieve_match_opr_optional_read + (renv, address, NULL, &ret, &cmp, &mcht) < 0 ) + return ret; /* Read source */ - if ( (source=sieve_opr_stringlist_read(renv, address, "source")) == NULL ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_stringlist_read(renv, address, "source", &source)) <= 0 ) + return ret; /* Read key-list */ - if ( (key_list=sieve_opr_stringlist_read(renv, address, "key-list")) == NULL ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_stringlist_read(renv, address, "key-list", &key_list)) + <= 0 ) + return ret; /* * Perform operation @@ -268,14 +261,10 @@ static int tst_string_operation_execute value_list = tst_string_stringlist_create(renv, source); /* Perform match */ - ret = sieve_match(renv, &mcht, &cmp, value_list, key_list); - - /* Set test result for subsequent conditional jump */ - if ( ret >= 0 ) { - sieve_interpreter_set_test_result(renv->interp, ret > 0); - return SIEVE_EXEC_OK; - } + if ( (match=sieve_match(renv, &mcht, &cmp, value_list, key_list, &ret)) < 0 ) + return ret; - sieve_runtime_trace_error(renv, "invalid string-list item"); - return SIEVE_EXEC_BIN_CORRUPT; + /* Set test result for subsequent conditional jump */ + sieve_interpreter_set_test_result(renv->interp, match > 0); + return SIEVE_EXEC_OK; } diff --git a/src/lib-sieve/sieve-actions.c b/src/lib-sieve/sieve-actions.c index 4aa3f59901d9c4ec13488d0d25f60b021be5b346..a2e8a439b04ddcf04b401e698cfd92cf6ea40160 100644 --- a/src/lib-sieve/sieve-actions.c +++ b/src/lib-sieve/sieve-actions.c @@ -90,10 +90,10 @@ int sieve_action_opr_optional_dump } while ( opok ) { - int ret; + int opt; - if ( (ret=sieve_opr_optional_dump(denv, address, opt_code)) <= 0 ) - return ret; + if ( (opt=sieve_opr_optional_dump(denv, address, opt_code)) <= 0 ) + return opt; if ( *opt_code == SIEVE_OPT_SIDE_EFFECT ) { opok = sieve_opr_side_effect_dump(denv, address); @@ -107,30 +107,40 @@ int sieve_action_opr_optional_dump int sieve_action_opr_optional_read (const struct sieve_runtime_env *renv, sieve_size_t *address, - signed int *opt_code, struct sieve_side_effects_list **list) + signed int *opt_code, int *exec_status, + struct sieve_side_effects_list **list) { signed int _opt_code = 0; bool final = FALSE; + int ret; if ( opt_code == NULL ) { opt_code = &_opt_code; final = TRUE; } + if ( exec_status != NULL ) + *exec_status = SIEVE_EXEC_OK; + for ( ;; ) { - int ret; + int opt; - if ( (ret=sieve_opr_optional_read(renv, address, opt_code)) <= 0 ) - return ret; + if ( (opt=sieve_opr_optional_read(renv, address, opt_code)) <= 0 ) { + if ( opt < 0 && exec_status != NULL ) + *exec_status = SIEVE_EXEC_BIN_CORRUPT; + return opt; + } if ( *opt_code == SIEVE_OPT_SIDE_EFFECT ) { struct sieve_side_effect seffect; - if ( list == NULL ) - return -1; + i_assert( list != NULL ); - if ( !sieve_opr_side_effect_read(renv, address, &seffect) ) + if ( (ret=sieve_opr_side_effect_read(renv, address, &seffect)) <= 0 ) { + if ( exec_status != NULL ) + *exec_status = ret; return -1; + } if ( *list == NULL ) *list = sieve_side_effects_list_create(renv->result); @@ -139,12 +149,15 @@ int sieve_action_opr_optional_read } else { if ( final ) { sieve_runtime_trace_error(renv, "invalid optional operand"); - return -1; + if ( exec_status != NULL ) + *exec_status = SIEVE_EXEC_BIN_CORRUPT; + return -1; } return 1; } } + i_unreached(); return -1; } diff --git a/src/lib-sieve/sieve-actions.h b/src/lib-sieve/sieve-actions.h index c858580e62dfda837d504bfb31fdf547284eb376..9ab035209314238380822d12d63f858c3102fea5 100644 --- a/src/lib-sieve/sieve-actions.h +++ b/src/lib-sieve/sieve-actions.h @@ -115,7 +115,7 @@ struct sieve_side_effect_def { bool (*dump_context) (const struct sieve_side_effect *seffect, const struct sieve_dumptime_env *renv, sieve_size_t *address); - bool (*read_context) + int (*read_context) (const struct sieve_side_effect *seffect, const struct sieve_runtime_env *renv, sieve_size_t *address, void **se_context); @@ -193,7 +193,8 @@ int sieve_action_opr_optional_dump int sieve_action_opr_optional_read (const struct sieve_runtime_env *renv, sieve_size_t *address, - signed int *opt_code, struct sieve_side_effects_list **list); + signed int *opt_code, int *exec_status, + struct sieve_side_effects_list **list); /* * Core actions diff --git a/src/lib-sieve/sieve-address-parts.c b/src/lib-sieve/sieve-address-parts.c index 5971dbf76b2fc663d2ae024f36b80960bef2057d..13b696a5469b00ada026f2b0120df950d587d7d8 100644 --- a/src/lib-sieve/sieve-address-parts.c +++ b/src/lib-sieve/sieve-address-parts.c @@ -360,10 +360,10 @@ int sieve_addrmatch_opr_optional_dump } while ( opok ) { - int ret; + int opt; - if ( (ret=sieve_opr_optional_dump(denv, address, opt_code)) <= 0 ) - return ret; + if ( (opt=sieve_opr_optional_dump(denv, address, opt_code)) <= 0 ) + return opt; switch ( *opt_code ) { case SIEVE_AM_OPT_COMPARATOR: @@ -385,42 +385,53 @@ int sieve_addrmatch_opr_optional_dump int sieve_addrmatch_opr_optional_read (const struct sieve_runtime_env *renv, sieve_size_t *address, - signed int *opt_code, struct sieve_address_part *addrp, + signed int *opt_code, int *exec_status, struct sieve_address_part *addrp, struct sieve_match_type *mtch, struct sieve_comparator *cmp) { signed int _opt_code = 0; - bool final = FALSE, opok = TRUE; + bool final = FALSE; + int status = SIEVE_EXEC_OK; if ( opt_code == NULL ) { opt_code = &_opt_code; final = TRUE; } - while ( opok ) { - int ret; + if ( exec_status != NULL ) + *exec_status = SIEVE_EXEC_OK; - if ( (ret=sieve_opr_optional_read(renv, address, opt_code)) <= 0 ) - return ret; + while ( status == SIEVE_EXEC_OK ) { + int opt; + + if ( (opt=sieve_opr_optional_read(renv, address, opt_code)) <= 0 ){ + if ( opt < 0 && exec_status != NULL ) + *exec_status = SIEVE_EXEC_BIN_CORRUPT; + return opt; + } switch ( *opt_code ) { case SIEVE_AM_OPT_COMPARATOR: - opok = sieve_opr_comparator_read(renv, address, cmp); + status = sieve_opr_comparator_read(renv, address, cmp); break; case SIEVE_AM_OPT_MATCH_TYPE: - opok = sieve_opr_match_type_read(renv, address, mtch); + status = sieve_opr_match_type_read(renv, address, mtch); break; case SIEVE_AM_OPT_ADDRESS_PART: - opok = sieve_opr_address_part_read(renv, address, addrp); + status = sieve_opr_address_part_read(renv, address, addrp); break; default: if ( final ) { sieve_runtime_trace_error(renv, "invalid optional operand"); + if ( exec_status != NULL ) + *exec_status = SIEVE_EXEC_BIN_CORRUPT; return -1; } return 1; } } + if ( exec_status != NULL ) + *exec_status = status; return -1; } diff --git a/src/lib-sieve/sieve-address-parts.h b/src/lib-sieve/sieve-address-parts.h index 8c8797e01d379339d746b57a20a3907b0b08a052..3e7a09524d06f5fbba6e450fe28e3e5ba845e5fa 100644 --- a/src/lib-sieve/sieve-address-parts.h +++ b/src/lib-sieve/sieve-address-parts.h @@ -89,23 +89,23 @@ static inline void sieve_opr_address_part_emit sieve_opr_object_emit(sblock, addrp->object.ext, addrp->object.def); } -static inline bool sieve_opr_address_part_read +static inline bool sieve_opr_address_part_dump + (const struct sieve_dumptime_env *denv, sieve_size_t *address) +{ + return sieve_opr_object_dump + (denv, &sieve_address_part_operand_class, address, NULL); +} + +static inline int sieve_opr_address_part_read (const struct sieve_runtime_env *renv, sieve_size_t *address, struct sieve_address_part *addrp) { if ( !sieve_opr_object_read (renv, &sieve_address_part_operand_class, address, &addrp->object) ) - return FALSE; + return SIEVE_EXEC_BIN_CORRUPT; addrp->def = (const struct sieve_address_part_def *) addrp->object.def; - return TRUE; -} - -static inline bool sieve_opr_address_part_dump - (const struct sieve_dumptime_env *denv, sieve_size_t *address) -{ - return sieve_opr_object_dump - (denv, &sieve_address_part_operand_class, address, NULL); + return SIEVE_EXEC_OK; } /* @@ -133,7 +133,7 @@ int sieve_addrmatch_opr_optional_dump int sieve_addrmatch_opr_optional_read (const struct sieve_runtime_env *renv, sieve_size_t *address, - signed int *opt_code, struct sieve_address_part *addrp, + signed int *opt_code, int *exec_status, struct sieve_address_part *addrp, struct sieve_match_type *mtch, struct sieve_comparator *cmp); #endif /* __SIEVE_ADDRESS_PARTS_H */ diff --git a/src/lib-sieve/sieve-address.c b/src/lib-sieve/sieve-address.c index e89b40a5e824eb27c527a2e1ae85d20992043616..0d983b750929a10467d193f05bb6f88d4e8da3e4 100644 --- a/src/lib-sieve/sieve-address.c +++ b/src/lib-sieve/sieve-address.c @@ -46,6 +46,7 @@ struct sieve_address_list *sieve_header_address_list_create addrlist = t_new(struct sieve_header_address_list, 1); addrlist->addrlist.strlist.runenv = renv; + addrlist->addrlist.strlist.exec_status = SIEVE_EXEC_OK; addrlist->addrlist.strlist.next_item = sieve_header_address_list_next_string_item; addrlist->addrlist.strlist.reset = sieve_header_address_list_reset; diff --git a/src/lib-sieve/sieve-code.c b/src/lib-sieve/sieve-code.c index d64f77d4b98a7ebf1d914c39cb9f2b4b240181ca..1c237a9de5b5138ad61cae3bb0dff4f75a22b44e 100644 --- a/src/lib-sieve/sieve-code.c +++ b/src/lib-sieve/sieve-code.c @@ -55,6 +55,7 @@ static struct sieve_stringlist *sieve_code_stringlist_create strlist = t_new(struct sieve_code_stringlist, 1); strlist->strlist.runenv = renv; + strlist->strlist.exec_status = SIEVE_EXEC_OK; strlist->strlist.next_item = sieve_code_stringlist_next_item; strlist->strlist.reset = sieve_code_stringlist_reset; strlist->strlist.get_length = sieve_code_stringlist_get_length; @@ -76,6 +77,7 @@ static int sieve_code_stringlist_next_item (struct sieve_code_stringlist *) _strlist; sieve_size_t address; *str_r = NULL; + int ret; /* Check for end of list */ if ( strlist->index >= strlist->length ) @@ -83,12 +85,14 @@ static int sieve_code_stringlist_next_item /* Read next item */ address = strlist->current_offset; - if ( sieve_opr_string_read(_strlist->runenv, &address, NULL, str_r) ) { + if ( (ret=sieve_opr_string_read(_strlist->runenv, &address, NULL, str_r)) + == SIEVE_EXEC_OK ) { strlist->index++; strlist->current_offset = address; return 1; } + _strlist->exec_status = ret; return -1; } @@ -193,17 +197,18 @@ sieve_size_t sieve_operand_emit } bool sieve_operand_read -(struct sieve_binary_block *sblock, sieve_size_t *address, - struct sieve_operand *operand) +(struct sieve_binary_block *sblock, sieve_size_t *address, + const char *field_name, struct sieve_operand *operand) { unsigned int code = sieve_operand_count; operand->address = *address; + operand->field_name = field_name; operand->ext = NULL; operand->def = NULL; if ( !sieve_binary_read_extension(sblock, address, &code, &operand->ext) ) - return NULL; + return FALSE; if ( operand->ext == NULL ) { if ( code < sieve_operand_count ) @@ -267,11 +272,11 @@ const struct sieve_operand_def omitted_operand = { /* Number */ static bool opr_number_dump - (const struct sieve_dumptime_env *denv, sieve_size_t *address, - const char *field_name); -static bool opr_number_read - (const struct sieve_runtime_env *renv, sieve_size_t *address, - sieve_number_t *number_r); + (const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, + sieve_size_t *address); +static int opr_number_read + (const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, + sieve_size_t *address, sieve_number_t *number_r); const struct sieve_opr_number_interface number_interface = { opr_number_dump, @@ -291,10 +296,10 @@ const struct sieve_operand_def number_operand = { /* String */ static bool opr_string_dump - (const struct sieve_dumptime_env *denv, const struct sieve_operand *opr, - sieve_size_t *address, const char *field_name); -static bool opr_string_read - (const struct sieve_runtime_env *renv, const struct sieve_operand *opr, + (const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, + sieve_size_t *address); +static int opr_string_read + (const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, sieve_size_t *address, string_t **str_r); const struct sieve_opr_string_interface string_interface ={ @@ -315,10 +320,11 @@ const struct sieve_operand_def string_operand = { /* String List */ static bool opr_stringlist_dump - (const struct sieve_dumptime_env *denv, sieve_size_t *address, - const char *field_name); -static struct sieve_stringlist *opr_stringlist_read - (const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, + sieve_size_t *address); +static int opr_stringlist_read + (const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, + sieve_size_t *address, struct sieve_stringlist **strlist_r); const struct sieve_opr_stringlist_interface stringlist_interface = { opr_stringlist_dump, @@ -337,12 +343,12 @@ const struct sieve_operand_def stringlist_operand = { /* Catenated String */ -static bool opr_catenated_string_read - (const struct sieve_runtime_env *renv, const struct sieve_operand *operand, - sieve_size_t *address, string_t **str); static bool opr_catenated_string_dump (const struct sieve_dumptime_env *denv, const struct sieve_operand *operand, - sieve_size_t *address, const char *field_name); + sieve_size_t *address); +static int opr_catenated_string_read + (const struct sieve_runtime_env *renv, const struct sieve_operand *operand, + sieve_size_t *address, string_t **str); const struct sieve_opr_string_interface catenated_string_interface = { opr_catenated_string_dump, @@ -377,20 +383,22 @@ void sieve_opr_number_emit } bool sieve_opr_number_dump_data -(const struct sieve_dumptime_env *denv, const struct sieve_operand *opr, +(const struct sieve_dumptime_env *denv, struct sieve_operand *oprnd, sieve_size_t *address, const char *field_name) { const struct sieve_opr_number_interface *intf; - if ( !sieve_operand_is_number(opr) ) + oprnd->field_name = field_name; + + if ( !sieve_operand_is_number(oprnd) ) return FALSE; - intf = (const struct sieve_opr_number_interface *) opr->def->interface; + intf = (const struct sieve_opr_number_interface *) oprnd->def->interface; if ( intf->dump == NULL ) return FALSE; - return intf->dump(denv, address, field_name); + return intf->dump(denv, oprnd, address); } bool sieve_opr_number_dump @@ -401,60 +409,61 @@ bool sieve_opr_number_dump sieve_code_mark(denv); - if ( !sieve_operand_read(denv->sblock, address, &operand) ) + if ( !sieve_operand_read(denv->sblock, address, field_name, &operand) ) return FALSE; return sieve_opr_number_dump_data(denv, &operand, address, field_name); } -bool sieve_opr_number_read_data -(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, +int sieve_opr_number_read_data +(const struct sieve_runtime_env *renv, struct sieve_operand *oprnd, sieve_size_t *address, const char *field_name, sieve_number_t *number_r) { const struct sieve_opr_number_interface *intf; + oprnd->field_name = field_name; + if ( !sieve_operand_is_number(oprnd) ) { - sieve_runtime_trace_operand_error(renv, oprnd, field_name, + sieve_runtime_trace_operand_error(renv, oprnd, "expected number operand but found %s", sieve_operand_name(oprnd)); - return FALSE; + return SIEVE_EXEC_BIN_CORRUPT; } intf = (const struct sieve_opr_number_interface *) oprnd->def->interface; - if ( intf->read == NULL ) - return FALSE; - - if ( !intf->read(renv, address, number_r) ) { - sieve_runtime_trace_operand_error(renv, oprnd, field_name, - "invalid number operand"); - return FALSE; + if ( intf->read == NULL ) { + sieve_runtime_trace_operand_error(renv, oprnd, + "number operand not implemented"); + return SIEVE_EXEC_FAILURE; } - return TRUE; + return intf->read(renv, oprnd, address, number_r); } -bool sieve_opr_number_read +int sieve_opr_number_read (const struct sieve_runtime_env *renv, sieve_size_t *address, const char *field_name, sieve_number_t *number_r) { struct sieve_operand operand; + int ret; - if ( !sieve_operand_runtime_read(renv, address, field_name, &operand) ) - return FALSE; + if ( (ret=sieve_operand_runtime_read(renv, address, field_name, &operand)) + <= 0) + return ret; return sieve_opr_number_read_data (renv, &operand, address, field_name, number_r); } static bool opr_number_dump -(const struct sieve_dumptime_env *denv, sieve_size_t *address, - const char *field_name) +(const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, + sieve_size_t *address) { sieve_number_t number = 0; if (sieve_binary_read_integer(denv->sblock, address, &number) ) { - if ( field_name != NULL ) - sieve_code_dumpf(denv, "%s: NUM %llu", field_name, + if ( oprnd->field_name != NULL ) + sieve_code_dumpf(denv, "%s: NUM %llu", oprnd->field_name, (unsigned long long) number); else sieve_code_dumpf(denv, "NUM %llu", (unsigned long long) number); @@ -465,11 +474,16 @@ static bool opr_number_dump return FALSE; } -static bool opr_number_read -(const struct sieve_runtime_env *renv, sieve_size_t *address, - sieve_number_t *number_r) +static int opr_number_read +(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, + sieve_size_t *address, sieve_number_t *number_r) { - return sieve_binary_read_integer(renv->sblock, address, number_r); + if ( !sieve_binary_read_integer(renv->sblock, address, number_r) ) { + sieve_runtime_trace_operand_error(renv, oprnd, "invalid number operand"); + return SIEVE_EXEC_BIN_CORRUPT; + } + + return SIEVE_EXEC_OK; } /* String */ @@ -481,25 +495,27 @@ void sieve_opr_string_emit(struct sieve_binary_block *sblock, string_t *str) } bool sieve_opr_string_dump_data -(const struct sieve_dumptime_env *denv, const struct sieve_operand *opr, +(const struct sieve_dumptime_env *denv, struct sieve_operand *oprnd, sieve_size_t *address, const char *field_name) { const struct sieve_opr_string_interface *intf; - if ( !sieve_operand_is_string(opr) ) { + oprnd->field_name = field_name; + + if ( !sieve_operand_is_string(oprnd) ) { sieve_code_dumpf(denv, "ERROR: INVALID STRING OPERAND %s", - sieve_operand_name(opr)); + sieve_operand_name(oprnd)); return FALSE; } - intf = (const struct sieve_opr_string_interface *) opr->def->interface; + intf = (const struct sieve_opr_string_interface *) oprnd->def->interface; if ( intf->dump == NULL ) { sieve_code_dumpf(denv, "ERROR: DUMP STRING OPERAND"); return FALSE; } - return intf->dump(denv, opr, address, field_name); + return intf->dump(denv, oprnd, address); } bool sieve_opr_string_dump @@ -510,7 +526,7 @@ bool sieve_opr_string_dump sieve_code_mark(denv); - if ( !sieve_operand_read(denv->sblock, address, &operand) ) { + if ( !sieve_operand_read(denv->sblock, address, field_name, &operand) ) { sieve_code_dumpf(denv, "ERROR: INVALID OPERAND"); return FALSE; } @@ -525,7 +541,7 @@ bool sieve_opr_string_dump_ex struct sieve_operand operand; sieve_code_mark(denv); - if ( !sieve_operand_read(denv->sblock, address, &operand) ) { + if ( !sieve_operand_read(denv->sblock, address, field_name, &operand) ) { sieve_code_dumpf(denv, "ERROR: INVALID OPERAND"); return FALSE; } @@ -535,49 +551,55 @@ bool sieve_opr_string_dump_ex 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 *oprnd, +int sieve_opr_string_read_data +(const struct sieve_runtime_env *renv, struct sieve_operand *oprnd, sieve_size_t *address, const char *field_name, string_t **str_r) { const struct sieve_opr_string_interface *intf; + + oprnd->field_name = field_name; if ( !sieve_operand_is_string(oprnd) ) { - sieve_runtime_trace_operand_error(renv, oprnd, field_name, + sieve_runtime_trace_operand_error(renv, oprnd, "expected string operand but found %s", sieve_operand_name(oprnd)); - return FALSE; + return SIEVE_EXEC_BIN_CORRUPT; } intf = (const struct sieve_opr_string_interface *) oprnd->def->interface; if ( intf->read == NULL ) { - sieve_runtime_trace_operand_error(renv, oprnd, field_name, - "invalid string operand"); - return FALSE; + sieve_runtime_trace_operand_error(renv, oprnd, + "string operand not implemented"); + return SIEVE_EXEC_FAILURE; } return intf->read(renv, oprnd, address, str_r); } -bool sieve_opr_string_read +int sieve_opr_string_read (const struct sieve_runtime_env *renv, sieve_size_t *address, const char *field_name, string_t **str_r) { struct sieve_operand operand; + int ret; - if ( !sieve_operand_runtime_read(renv, address, field_name, &operand) ) - return FALSE; + if ( (ret=sieve_operand_runtime_read(renv, address, field_name, &operand)) + <= 0 ) + return ret; return sieve_opr_string_read_data(renv, &operand, address, field_name, str_r); } -bool sieve_opr_string_read_ex +int sieve_opr_string_read_ex (const struct sieve_runtime_env *renv, sieve_size_t *address, const char *field_name, string_t **str_r, bool *literal_r) { struct sieve_operand operand; + int ret; - if ( !sieve_operand_runtime_read(renv, address, field_name, &operand) ) - return FALSE; + if ( (ret=sieve_operand_runtime_read(renv, address, field_name, &operand)) + <= 0 ) + return ret; *literal_r = sieve_operand_is(&operand, string_operand); @@ -606,14 +628,13 @@ static void _dump_string } bool opr_string_dump -(const struct sieve_dumptime_env *denv, - const struct sieve_operand *opr ATTR_UNUSED, sieve_size_t *address, - const char *field_name) +(const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, + sieve_size_t *address) { string_t *str; if ( sieve_binary_read_string(denv->sblock, address, &str) ) { - _dump_string(denv, str, field_name); + _dump_string(denv, str, oprnd->field_name); return TRUE; } @@ -621,12 +642,17 @@ bool opr_string_dump return FALSE; } -static bool opr_string_read -(const struct sieve_runtime_env *renv, - const struct sieve_operand *opr ATTR_UNUSED, sieve_size_t *address, - string_t **str_r) +static int opr_string_read +(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, + sieve_size_t *address, string_t **str_r) { - return sieve_binary_read_string(renv->sblock, address, str_r); + if ( !sieve_binary_read_string(renv->sblock, address, str_r) ) { + sieve_runtime_trace_operand_error(renv, oprnd, + "invalid string operand"); + return SIEVE_EXEC_BIN_CORRUPT; + } + + return SIEVE_EXEC_OK; } /* String list */ @@ -662,28 +688,30 @@ void sieve_opr_stringlist_emit_end } bool sieve_opr_stringlist_dump_data -(const struct sieve_dumptime_env *denv, const struct sieve_operand *opr, +(const struct sieve_dumptime_env *denv, struct sieve_operand *oprnd, sieve_size_t *address, const char *field_name) { - if ( opr == NULL || opr->def == NULL ) + if ( oprnd == NULL || oprnd->def == NULL ) return FALSE; - if ( opr->def->class == &stringlist_class ) { + oprnd->field_name = field_name; + + if ( oprnd->def->class == &stringlist_class ) { const struct sieve_opr_stringlist_interface *intf = - (const struct sieve_opr_stringlist_interface *) opr->def->interface; + (const struct sieve_opr_stringlist_interface *) oprnd->def->interface; if ( intf->dump == NULL ) return FALSE; - return intf->dump(denv, address, field_name); - } else if ( opr->def->class == &string_class ) { + return intf->dump(denv, oprnd, address); + } else if ( oprnd->def->class == &string_class ) { const struct sieve_opr_string_interface *intf = - (const struct sieve_opr_string_interface *) opr->def->interface; + (const struct sieve_opr_string_interface *) oprnd->def->interface; if ( intf->dump == NULL ) return FALSE; - return intf->dump(denv, opr, address, field_name); + return intf->dump(denv, oprnd, address); } return FALSE; @@ -697,70 +725,83 @@ bool sieve_opr_stringlist_dump sieve_code_mark(denv); - if ( !sieve_operand_read(denv->sblock, address, &operand) ) { + if ( !sieve_operand_read(denv->sblock, address, field_name, &operand) ) { return FALSE; } return sieve_opr_stringlist_dump_data(denv, &operand, address, field_name); } -struct sieve_stringlist *sieve_opr_stringlist_read_data -(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, - sieve_size_t *address, const char *field_name) +int sieve_opr_stringlist_read_data +(const struct sieve_runtime_env *renv, struct sieve_operand *oprnd, + sieve_size_t *address, const char *field_name, + struct sieve_stringlist **strlist_r) { if ( oprnd == NULL || oprnd->def == NULL ) - return NULL; + return SIEVE_EXEC_FAILURE; + + oprnd->field_name = field_name; if ( oprnd->def->class == &stringlist_class ) { const struct sieve_opr_stringlist_interface *intf = (const struct sieve_opr_stringlist_interface *) oprnd->def->interface; - struct sieve_stringlist *strlist; + int ret; - if ( intf->read == NULL ) - return NULL; - - if ( (strlist=intf->read(renv, address)) == NULL ) { - sieve_runtime_trace_operand_error(renv, oprnd, field_name, - "invalid stringlist operand"); - return NULL; + if ( intf->read == NULL ) { + sieve_runtime_trace_operand_error(renv, oprnd, + "stringlist operand not implemented"); + return SIEVE_EXEC_FAILURE; } - return strlist; + if ( (ret=intf->read(renv, oprnd, address, strlist_r)) <= 0 ) + return ret; + + return SIEVE_EXEC_OK; } else if ( oprnd->def->class == &string_class ) { /* Special case, accept single string as string list as well. */ const struct sieve_opr_string_interface *intf = (const struct sieve_opr_string_interface *) oprnd->def->interface; + int ret; - if ( intf->read == NULL || !intf->read(renv, oprnd, address, NULL) ) { - sieve_runtime_trace_operand_error(renv, oprnd, field_name, - "invalid stringlist string operand"); - return NULL; + if ( intf->read == NULL ) { + sieve_runtime_trace_operand_error(renv, oprnd, + "stringlist string operand not implemented"); + return SIEVE_EXEC_FAILURE; } - - return sieve_code_stringlist_create(renv, oprnd->address, 1, *address); + + if ( (ret=intf->read(renv, oprnd, address, NULL)) <= 0 ) + return ret; + + if ( strlist_r != NULL ) + *strlist_r = sieve_code_stringlist_create + (renv, oprnd->address, 1, *address); + return SIEVE_EXEC_OK; } - sieve_runtime_trace_operand_error(renv, oprnd, field_name, + sieve_runtime_trace_operand_error(renv, oprnd, "expected stringlist or string operand but found %s", sieve_operand_name(oprnd)); - return NULL; + return SIEVE_EXEC_BIN_CORRUPT; } -struct sieve_stringlist *sieve_opr_stringlist_read +int sieve_opr_stringlist_read (const struct sieve_runtime_env *renv, sieve_size_t *address, - const char *field_name) + const char *field_name, struct sieve_stringlist **strlist_r) { struct sieve_operand operand; + int ret; - if ( !sieve_operand_runtime_read(renv, address, field_name, &operand) ) - return NULL; + if ( (ret=sieve_operand_runtime_read(renv, address, field_name, &operand)) + <= 0 ) + return ret; - return sieve_opr_stringlist_read_data(renv, &operand, address, field_name); + return sieve_opr_stringlist_read_data + (renv, &operand, address, field_name, strlist_r); } static bool opr_stringlist_dump -(const struct sieve_dumptime_env *denv, sieve_size_t *address, - const char *field_name) +(const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, + sieve_size_t *address) { sieve_size_t pc = *address; sieve_size_t end; @@ -775,33 +816,41 @@ static bool opr_stringlist_dump if ( !sieve_binary_read_unsigned(denv->sblock, address, &length) ) return FALSE; - return sieve_code_stringlist_dump(denv, address, length, end, field_name); + return sieve_code_stringlist_dump + (denv, address, length, end, oprnd->field_name); } -static struct sieve_stringlist *opr_stringlist_read -(const struct sieve_runtime_env *renv, sieve_size_t *address ) +static int opr_stringlist_read +(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, + sieve_size_t *address, struct sieve_stringlist **strlist_r) { - struct sieve_stringlist *strlist; sieve_size_t pc = *address; sieve_size_t end; unsigned int length = 0; sieve_offset_t end_offset; - if ( !sieve_binary_read_offset(renv->sblock, address, &end_offset) ) - return NULL; + if ( !sieve_binary_read_offset(renv->sblock, address, &end_offset) ) { + sieve_runtime_trace_operand_error(renv, oprnd, + "stringlist corrupt: invalid end offset"); + return SIEVE_EXEC_BIN_CORRUPT; + } end = pc + end_offset; - if ( !sieve_binary_read_unsigned(renv->sblock, address, &length) ) - return NULL; - - strlist = sieve_code_stringlist_create - (renv, *address, (unsigned int) length, end); + if ( !sieve_binary_read_unsigned(renv->sblock, address, &length) ) { + sieve_runtime_trace_operand_error(renv, oprnd, + "stringlist corrupt: invalid length data"); + return SIEVE_EXEC_BIN_CORRUPT; + } + + if ( strlist_r != NULL ) + *strlist_r = sieve_code_stringlist_create + (renv, *address, (unsigned int) length, end); /* Skip over the string list for now */ *address = end; - return strlist; + return SIEVE_EXEC_OK; } /* Catenated String */ @@ -814,19 +863,18 @@ void sieve_opr_catenated_string_emit } static bool opr_catenated_string_dump -(const struct sieve_dumptime_env *denv, - const struct sieve_operand *operand ATTR_UNUSED, sieve_size_t *address, - const char *field_name) +(const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, + sieve_size_t *address) { unsigned int elements = 0; unsigned int i; - if (!sieve_binary_read_unsigned(denv->sblock, address, &elements) ) + if ( !sieve_binary_read_unsigned(denv->sblock, address, &elements) ) return FALSE; - if ( field_name != NULL ) + if ( oprnd->field_name != NULL ) sieve_code_dumpf(denv, "%s: CAT-STR [%ld]:", - field_name, (long) elements); + oprnd->field_name, (long) elements); else sieve_code_dumpf(denv, "CAT-STR [%ld]:", (long) elements); @@ -840,24 +888,27 @@ static bool opr_catenated_string_dump return TRUE; } -static bool opr_catenated_string_read -(const struct sieve_runtime_env *renv, - const struct sieve_operand *operand ATTR_UNUSED, sieve_size_t *address, - string_t **str) +static int opr_catenated_string_read +(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, + sieve_size_t *address, string_t **str) { unsigned int elements = 0; unsigned int i; + int ret; - if ( !sieve_binary_read_unsigned(renv->sblock, address, &elements) ) - return FALSE; + if ( !sieve_binary_read_unsigned(renv->sblock, address, &elements) ) { + sieve_runtime_trace_operand_error(renv, oprnd, + "catenated string corrupt: invalid element count data"); + return SIEVE_EXEC_BIN_CORRUPT; + } /* Parameter str can be NULL if we are requested to only skip and not * actually read the argument. */ if ( str == NULL ) { for ( i = 0; i < (unsigned int) elements; i++ ) { - if ( !sieve_opr_string_read(renv, address, NULL, NULL) ) - return FALSE; + if ( (ret=sieve_opr_string_read(renv, address, NULL, NULL)) <= 0 ) + return ret; } } else { string_t *strelm; @@ -866,8 +917,8 @@ static bool opr_catenated_string_read *str = t_str_new(128); for ( i = 0; i < (unsigned int) elements; i++ ) { - if ( !sieve_opr_string_read(renv, address, NULL, elm) ) - return FALSE; + if ( (ret=sieve_opr_string_read(renv, address, NULL, elm)) <= 0 ) + return ret; if ( elm != NULL ) { str_append_str(*str, strelm); @@ -880,7 +931,7 @@ static bool opr_catenated_string_read } } - return TRUE; + return SIEVE_EXEC_OK; } /* diff --git a/src/lib-sieve/sieve-code.h b/src/lib-sieve/sieve-code.h index 7f8ce700e84879b20082acb6b89a2d31a681f936..302baa5fc39e15e180e2ada2caf03935dae363a6 100644 --- a/src/lib-sieve/sieve-code.h +++ b/src/lib-sieve/sieve-code.h @@ -36,6 +36,7 @@ struct sieve_operand { const struct sieve_operand_def *def; const struct sieve_extension *ext; sieve_size_t address; + const char *field_name; }; #define sieve_operand_name(opr) \ @@ -48,19 +49,18 @@ sieve_size_t sieve_operand_emit const struct sieve_operand_def *oprnd); bool sieve_operand_read (struct sieve_binary_block *sblock, sieve_size_t *address, - struct sieve_operand *oprnd); + const char *field_name, struct sieve_operand *oprnd); -static inline bool sieve_operand_runtime_read +static inline int sieve_operand_runtime_read (const struct sieve_runtime_env *renv, sieve_size_t *address, const char *field_name, struct sieve_operand *operand) { - if ( !sieve_operand_read(renv->sblock, address, operand) ) { - sieve_runtime_trace_operand_error - (renv, operand, field_name, "invalid operand"); - return FALSE; + if ( !sieve_operand_read(renv->sblock, address, field_name, operand) ) { + sieve_runtime_trace_operand_error(renv, operand, "invalid operand"); + return SIEVE_EXEC_BIN_CORRUPT; } - return TRUE; + return SIEVE_EXEC_OK; } /* @@ -137,28 +137,29 @@ extern const unsigned int sieve_operand_count; struct sieve_opr_number_interface { bool (*dump) - (const struct sieve_dumptime_env *denv, sieve_size_t *address, - const char *field_name); - bool (*read) - (const struct sieve_runtime_env *renv, sieve_size_t *address, - sieve_number_t *number_r); + (const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, + sieve_size_t *address); + int (*read) + (const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, + sieve_size_t *address, sieve_number_t *number_r); }; struct sieve_opr_string_interface { bool (*dump) - (const struct sieve_dumptime_env *denv, const struct sieve_operand *operand, - sieve_size_t *address, const char *field_name); - bool (*read) - (const struct sieve_runtime_env *renv, const struct sieve_operand *operand, + (const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, + sieve_size_t *address); + int (*read) + (const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, sieve_size_t *address, string_t **str_r); }; struct sieve_opr_stringlist_interface { bool (*dump) - (const struct sieve_dumptime_env *denv, sieve_size_t *address, - const char *field_name); - struct sieve_stringlist *(*read) - (const struct sieve_runtime_env *renv, sieve_size_t *address); + (const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, + sieve_size_t *address); + int (*read) + (const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, + sieve_size_t *address, struct sieve_stringlist **strlist_r); }; /* @@ -181,15 +182,15 @@ static inline bool sieve_operand_is_omitted void sieve_opr_number_emit (struct sieve_binary_block *sblock, sieve_number_t number); bool sieve_opr_number_dump_data - (const struct sieve_dumptime_env *denv, const struct sieve_operand *operand, + (const struct sieve_dumptime_env *denv, struct sieve_operand *operand, sieve_size_t *address, const char *field_name); bool sieve_opr_number_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address, const char *field_name); -bool sieve_opr_number_read_data - (const struct sieve_runtime_env *renv, const struct sieve_operand *operand, +int sieve_opr_number_read_data + (const struct sieve_runtime_env *renv, struct sieve_operand *operand, sieve_size_t *address, const char *field_name, sieve_number_t *number_r); -bool sieve_opr_number_read +int sieve_opr_number_read (const struct sieve_runtime_env *renv, sieve_size_t *address, const char *field_name, sieve_number_t *number_r); @@ -205,7 +206,7 @@ static inline bool sieve_operand_is_number void sieve_opr_string_emit (struct sieve_binary_block *sblock, string_t *str); bool sieve_opr_string_dump_data - (const struct sieve_dumptime_env *denv, const struct sieve_operand *operand, + (const struct sieve_dumptime_env *denv, struct sieve_operand *operand, sieve_size_t *address, const char *field_name); bool sieve_opr_string_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address, @@ -213,13 +214,13 @@ 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_r); -bool sieve_opr_string_read_data - (const struct sieve_runtime_env *renv, const struct sieve_operand *operand, +int sieve_opr_string_read_data + (const struct sieve_runtime_env *renv, struct sieve_operand *operand, sieve_size_t *address, const char *field_name, string_t **str_r); -bool sieve_opr_string_read +int sieve_opr_string_read (const struct sieve_runtime_env *renv, sieve_size_t *address, const char *field_name, string_t **str_r); -bool sieve_opr_string_read_ex +int sieve_opr_string_read_ex (const struct sieve_runtime_env *renv, sieve_size_t *address, const char *field_name, string_t **str_r, bool *literal_r); @@ -240,17 +241,18 @@ void sieve_opr_stringlist_emit_item void sieve_opr_stringlist_emit_end (struct sieve_binary_block *sblock, void *context); bool sieve_opr_stringlist_dump_data - (const struct sieve_dumptime_env *denv, const struct sieve_operand *operand, + (const struct sieve_dumptime_env *denv, struct sieve_operand *operand, sieve_size_t *address, const char *field_name); bool sieve_opr_stringlist_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address, const char *field_name); -struct sieve_stringlist *sieve_opr_stringlist_read_data - (const struct sieve_runtime_env *renv, const struct sieve_operand *operand, - sieve_size_t *address, const char *field_name); -struct sieve_stringlist *sieve_opr_stringlist_read +int sieve_opr_stringlist_read_data + (const struct sieve_runtime_env *renv, struct sieve_operand *operand, + sieve_size_t *address, const char *field_name, + struct sieve_stringlist **strlist_r); +int sieve_opr_stringlist_read (const struct sieve_runtime_env *renv, sieve_size_t *address, - const char *field_name); + const char *field_name, struct sieve_stringlist **strlist_r); static inline bool sieve_operand_is_stringlist (const struct sieve_operand *operand) diff --git a/src/lib-sieve/sieve-comparators.h b/src/lib-sieve/sieve-comparators.h index 512c072fc3a80cfd04c5630850207ce836a14ed0..d0058425d64fdd739d26243be0c99d6c1a1d07d1 100644 --- a/src/lib-sieve/sieve-comparators.h +++ b/src/lib-sieve/sieve-comparators.h @@ -126,24 +126,23 @@ static inline void sieve_opr_comparator_emit { sieve_opr_object_emit(sblock, cmp->object.ext, cmp->object.def); } +static inline bool sieve_opr_comparator_dump +(const struct sieve_dumptime_env *denv, sieve_size_t *address) +{ + return sieve_opr_object_dump + (denv, &sieve_comparator_operand_class, address, NULL); +} -static inline bool sieve_opr_comparator_read +static inline int sieve_opr_comparator_read (const struct sieve_runtime_env *renv, sieve_size_t *address, struct sieve_comparator *cmp) { if ( !sieve_opr_object_read (renv, &sieve_comparator_operand_class, address, &cmp->object) ) - return FALSE; + return SIEVE_EXEC_BIN_CORRUPT; cmp->def = (const struct sieve_comparator_def *) cmp->object.def; - return TRUE; -} - -static inline bool sieve_opr_comparator_dump -(const struct sieve_dumptime_env *denv, sieve_size_t *address) -{ - return sieve_opr_object_dump - (denv, &sieve_comparator_operand_class, address, NULL); + return SIEVE_EXEC_OK; } /* diff --git a/src/lib-sieve/sieve-match-types.h b/src/lib-sieve/sieve-match-types.h index 2a0e68f3c4a588d7a50da6a55b3f47170b6d4d3a..79d633c001f0306b0b6e92e7b61c2f14e523a5ad 100644 --- a/src/lib-sieve/sieve-match-types.h +++ b/src/lib-sieve/sieve-match-types.h @@ -204,23 +204,23 @@ static inline void sieve_opr_match_type_emit sieve_opr_object_emit(sblock, mcht->object.ext, mcht->object.def); } -static inline bool sieve_opr_match_type_read +static inline bool sieve_opr_match_type_dump +(const struct sieve_dumptime_env *denv, sieve_size_t *address) +{ + return sieve_opr_object_dump + (denv, &sieve_match_type_operand_class, address, NULL); +} + +static inline int sieve_opr_match_type_read (const struct sieve_runtime_env *renv, sieve_size_t *address, struct sieve_match_type *mcht) { if ( !sieve_opr_object_read (renv, &sieve_match_type_operand_class, address, &mcht->object) ) - return FALSE; + return SIEVE_EXEC_BIN_CORRUPT; mcht->def = (const struct sieve_match_type_def *) mcht->object.def; - return TRUE; -} - -static inline bool sieve_opr_match_type_dump -(const struct sieve_dumptime_env *denv, sieve_size_t *address) -{ - return sieve_opr_object_dump - (denv, &sieve_match_type_operand_class, address, NULL); + return SIEVE_EXEC_OK; } /* Common validation implementation */ diff --git a/src/lib-sieve/sieve-match.c b/src/lib-sieve/sieve-match.c index 19c0a2e36739fce0f6a9b5d6c5dcf954e3045b4e..9cf43775149944d9eec35832bcac354bc515f6e1 100644 --- a/src/lib-sieve/sieve-match.c +++ b/src/lib-sieve/sieve-match.c @@ -46,6 +46,7 @@ struct sieve_match_context *sieve_match_begin mctx->runenv = renv; mctx->match_type = mcht; mctx->comparator = cmp; + mctx->exec_status = SIEVE_EXEC_OK; mctx->trace = sieve_runtime_trace_active(renv, SIEVE_TRLVL_MATCHING); /* Trace */ @@ -70,7 +71,7 @@ int sieve_match_value { const struct sieve_match_type *mcht = mctx->match_type; const struct sieve_runtime_env *renv = mctx->runenv; - int result = 0; + int match, ret; if ( mctx->trace ) { sieve_runtime_trace(renv, 0, @@ -88,55 +89,62 @@ int sieve_match_value if ( mcht->def->match_keys != NULL ) { /* Call match-type's own key match handler */ - result = mcht->def->match_keys(mctx, value, value_size, key_list); + match = mcht->def->match_keys(mctx, value, value_size, key_list); } else { string_t *key_item = NULL; - int ret; /* Default key match loop */ - while ( result == 0 && + match = 0; + while ( match == 0 && (ret=sieve_stringlist_next_item(key_list, &key_item)) > 0 ) { T_BEGIN { - result = mcht->def->match_key + match = mcht->def->match_key (mctx, value, value_size, str_c(key_item), str_len(key_item)); if ( mctx->trace ) { sieve_runtime_trace(renv, 0, "with key `%s' => %d", str_sanitize(str_c(key_item), 80), - result); + match); } } T_END; } - if ( ret < 0 ) result = -1; + if ( ret < 0 ) { + mctx->exec_status = key_list->exec_status; + match = -1; + } } sieve_runtime_trace_ascend(renv); - if ( mctx->status < 0 || result < 0 ) - mctx->status = -1; + if ( mctx->match_status < 0 || match < 0 ) + mctx->match_status = -1; else - mctx->status = ( mctx->status > result ? mctx->status : result ); - return result; + mctx->match_status = + ( mctx->match_status > match ? mctx->match_status : match ); + return match; } -int sieve_match_end(struct sieve_match_context **mctx) +int sieve_match_end(struct sieve_match_context **mctx, int *exec_status) { const struct sieve_match_type *mcht = (*mctx)->match_type; const struct sieve_runtime_env *renv = (*mctx)->runenv; - int result = (*mctx)->status; + int match = (*mctx)->match_status; if ( mcht->def != NULL && mcht->def->match_deinit != NULL ) mcht->def->match_deinit(*mctx); + if ( exec_status != NULL ) + *exec_status = (*mctx)->exec_status; + pool_unref(&(*mctx)->pool); sieve_runtime_trace(renv, SIEVE_TRLVL_MATCHING, "finishing match with result: %s", - ( result > 0 ? "matched" : ( result < 0 ? "error" : "not matched" ) )); + ( match > 0 ? "matched" : ( match < 0 ? "error" : "not matched" ) )); sieve_runtime_trace_ascend(renv); - return result; + return match; } int sieve_match @@ -144,11 +152,12 @@ int sieve_match const struct sieve_match_type *mcht, const struct sieve_comparator *cmp, struct sieve_stringlist *value_list, - struct sieve_stringlist *key_list) + struct sieve_stringlist *key_list, + int *exec_status) { struct sieve_match_context *mctx; string_t *value_item = NULL; - int result, ret; + int match, ret; if ( (mctx=sieve_match_begin(renv, mcht, cmp)) == NULL ) return 0; @@ -162,24 +171,28 @@ int sieve_match if ( mcht->def->match != NULL ) { /* Call match-type's match handler */ - result = mctx->status = mcht->def->match(mctx, value_list, key_list); + match = mctx->match_status = + mcht->def->match(mctx, value_list, key_list); } else { /* Default value match loop */ - result = 0; - while ( result == 0 && + match = 0; + while ( match == 0 && (ret=sieve_stringlist_next_item(value_list, &value_item)) > 0 ) { - result = sieve_match_value + match = sieve_match_value (mctx, str_c(value_item), str_len(value_item), key_list); } - if ( ret < 0 ) result = -1; + if ( ret < 0 ) { + mctx->exec_status = value_list->exec_status; + match = -1; + } } - (void)sieve_match_end(&mctx); - return result; + (void)sieve_match_end(&mctx, exec_status); + return match; } /* @@ -189,13 +202,19 @@ int sieve_match int sieve_match_opr_optional_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address, int *opt_code) { - bool opok = TRUE; + int _opt_code = 0; + bool final = FALSE, opok = TRUE; + + if ( opt_code == NULL ) { + opt_code = &_opt_code; + final = TRUE; + } while ( opok ) { - int ret; + int opt; - if ( (ret=sieve_opr_optional_dump(denv, address, opt_code)) <= 0 ) - return ret; + if ( (opt=sieve_opr_optional_dump(denv, address, opt_code)) <= 0 ) + return opt; switch ( *opt_code ) { case SIEVE_MATCH_OPT_COMPARATOR: @@ -205,7 +224,7 @@ int sieve_match_opr_optional_dump opok = sieve_opr_match_type_dump(denv, address); break; default: - return 1; + return ( final ? -1 : 1 ); } } @@ -214,28 +233,49 @@ int sieve_match_opr_optional_dump int sieve_match_opr_optional_read (const struct sieve_runtime_env *renv, sieve_size_t *address, int *opt_code, - struct sieve_comparator *cmp, struct sieve_match_type *mcht) + int *exec_status, struct sieve_comparator *cmp, struct sieve_match_type *mcht) { - bool opok = TRUE; + int _opt_code = 0; + bool final = FALSE; + int status = SIEVE_EXEC_OK; - while ( opok ) { - int ret; + if ( opt_code == NULL ) { + opt_code = &_opt_code; + final = TRUE; + } - if ( (ret=sieve_opr_optional_read(renv, address, opt_code)) <= 0 ) - return ret; + if ( exec_status != NULL ) + *exec_status = SIEVE_EXEC_OK; + + while ( status == SIEVE_EXEC_OK ) { + int opt; + + if ( (opt=sieve_opr_optional_read(renv, address, opt_code)) <= 0 ){ + if ( opt < 0 && exec_status != NULL ) + *exec_status = SIEVE_EXEC_BIN_CORRUPT; + return opt; + } switch ( *opt_code ) { case SIEVE_MATCH_OPT_COMPARATOR: - opok = sieve_opr_comparator_read(renv, address, cmp); + status = sieve_opr_comparator_read(renv, address, cmp); break; case SIEVE_MATCH_OPT_MATCH_TYPE: - opok = sieve_opr_match_type_read(renv, address, mcht); + status = sieve_opr_match_type_read(renv, address, mcht); break; default: + if ( final ) { + sieve_runtime_trace_error(renv, "invalid optional operand"); + if ( exec_status != NULL ) + *exec_status = SIEVE_EXEC_BIN_CORRUPT; + return -1; + } return 1; } } + if ( exec_status != NULL ) + *exec_status = status; return -1; } diff --git a/src/lib-sieve/sieve-match.h b/src/lib-sieve/sieve-match.h index e32bae1eb45135d7aebc4c539f3d13878841f1bc..804d72acde204e911b90177ba46f7e34ee2dbaf9 100644 --- a/src/lib-sieve/sieve-match.h +++ b/src/lib-sieve/sieve-match.h @@ -20,7 +20,9 @@ struct sieve_match_context { void *data; - int status; + int match_status; + int exec_status; + unsigned int trace:1; }; @@ -36,7 +38,7 @@ struct sieve_match_context *sieve_match_begin int sieve_match_value (struct sieve_match_context *mctx, const char *value, size_t value_size, struct sieve_stringlist *key_list); -int sieve_match_end(struct sieve_match_context **mctx); +int sieve_match_end(struct sieve_match_context **mctx, int *exec_status); /* Default matching operation */ int sieve_match @@ -44,7 +46,8 @@ int sieve_match const struct sieve_match_type *mcht, const struct sieve_comparator *cmp, struct sieve_stringlist *value_list, - struct sieve_stringlist *key_list); + struct sieve_stringlist *key_list, + int *exec_status); /* * Read matching operands @@ -62,6 +65,7 @@ int sieve_match_opr_optional_dump int sieve_match_opr_optional_read (const struct sieve_runtime_env *renv, sieve_size_t *address, int *opt_code, - struct sieve_comparator *cmp, struct sieve_match_type *mcht); + int *exec_status, struct sieve_comparator *cmp, + struct sieve_match_type *mcht); #endif /* __SIEVE_MATCH_H */ diff --git a/src/lib-sieve/sieve-message.c b/src/lib-sieve/sieve-message.c index 30b7472695e99ba3724febdba5d4a0d368c195ad..ba346be20b50b155b545017f8f8cbf4e86a8aca2 100644 --- a/src/lib-sieve/sieve-message.c +++ b/src/lib-sieve/sieve-message.c @@ -226,6 +226,7 @@ struct sieve_stringlist *sieve_message_header_stringlist_create strlist = t_new(struct sieve_message_header_stringlist, 1); strlist->strlist.runenv = renv; + strlist->strlist.exec_status = SIEVE_EXEC_OK; strlist->strlist.next_item = sieve_message_header_stringlist_next_item; strlist->strlist.reset = sieve_message_header_stringlist_reset; strlist->field_names = field_names; diff --git a/src/lib-sieve/sieve-objects.c b/src/lib-sieve/sieve-objects.c index 614dd1b5efc6a1125942ae6ca5506a640a3cb5cc..bfbe1d54253bbebab1156f3d002bf36ce51f1977 100644 --- a/src/lib-sieve/sieve-objects.c +++ b/src/lib-sieve/sieve-objects.c @@ -69,7 +69,7 @@ bool sieve_opr_object_read { struct sieve_operand operand; - if ( !sieve_operand_read(renv->sblock, address, &operand) ) { + if ( !sieve_operand_read(renv->sblock, address, NULL, &operand) ) { return FALSE; } @@ -91,7 +91,7 @@ bool sieve_opr_object_dump sieve_code_mark(denv); - if ( !sieve_operand_read(denv->sblock, address, &operand) ) { + if ( !sieve_operand_read(denv->sblock, address, NULL, &operand) ) { return FALSE; } diff --git a/src/lib-sieve/sieve-runtime-trace.c b/src/lib-sieve/sieve-runtime-trace.c index 07e7a4746900b25167dc70a9cea9ff163a6398e1..49d60627682379e443e89975957396c6f2a33c64 100644 --- a/src/lib-sieve/sieve-runtime-trace.c +++ b/src/lib-sieve/sieve-runtime-trace.c @@ -61,15 +61,15 @@ void _sieve_runtime_trace_error void _sieve_runtime_trace_operand_error (const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, - const char *field_name, const char *fmt, va_list args) + const char *fmt, va_list args) { string_t *trline = _trace_line_new(renv, oprnd->address, sieve_runtime_get_source_location(renv, oprnd->address)); str_printfa(trline, "%s: #ERROR#: ", sieve_operation_mnemonic(renv->oprtn)); - if ( field_name != NULL ) - str_printfa(trline, "%s: ", field_name); + if ( oprnd->field_name != NULL ) + str_printfa(trline, "%s: ", oprnd->field_name); str_vprintfa(trline, fmt, args); diff --git a/src/lib-sieve/sieve-runtime-trace.h b/src/lib-sieve/sieve-runtime-trace.h index a22088eff0396ccafc805425269d03f65f91bd11..9f1dbd0ae731fadffd2965ec576883cf6dfe9a8d 100644 --- a/src/lib-sieve/sieve-runtime-trace.h +++ b/src/lib-sieve/sieve-runtime-trace.h @@ -55,7 +55,7 @@ void _sieve_runtime_trace_error void _sieve_runtime_trace_operand_error (const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, - const char *field_name, const char *fmt, va_list args); + const char *fmt, va_list args); static inline void sieve_runtime_trace_error (const struct sieve_runtime_env *renv, const char *fmt, ...) @@ -63,7 +63,7 @@ static inline void sieve_runtime_trace_error static inline void sieve_runtime_trace_operand_error (const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, - const char *field_name, const char *fmt, ...) ATTR_FORMAT(4, 5); + const char *fmt, ...) ATTR_FORMAT(3, 4); static inline void sieve_runtime_trace_error (const struct sieve_runtime_env *renv, const char *fmt, ...) @@ -78,13 +78,13 @@ static inline void sieve_runtime_trace_error static inline void sieve_runtime_trace_operand_error (const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, - const char *field_name, const char *fmt, ...) + const char *fmt, ...) { va_list args; va_start(args, fmt); if ( renv->trace != NULL ) - _sieve_runtime_trace_operand_error(renv, oprnd, field_name, fmt, args); + _sieve_runtime_trace_operand_error(renv, oprnd, fmt, args); va_end(args); } diff --git a/src/lib-sieve/sieve-stringlist.c b/src/lib-sieve/sieve-stringlist.c index d3f7bc38f84401ca374badca7af154bfcc0a444a..caed0f341cb95774efad12c47be461992d3530d9 100644 --- a/src/lib-sieve/sieve-stringlist.c +++ b/src/lib-sieve/sieve-stringlist.c @@ -9,7 +9,7 @@ * Default implementation */ -bool sieve_stringlist_read_all +int sieve_stringlist_read_all (struct sieve_stringlist *strlist, pool_t pool, const char * const **list_r) { @@ -32,7 +32,7 @@ bool sieve_stringlist_read_all (void)array_append_space(&items); *list_r = array_idx(&items, 0); - return ( ret >= 0 ); + return ( ret < 0 ? -1 : 1 ); } return strlist->read_all(strlist, pool, list_r); @@ -85,6 +85,7 @@ struct sieve_stringlist *sieve_single_stringlist_create strlist = t_new(struct sieve_single_stringlist, 1); strlist->strlist.runenv = renv; + strlist->strlist.exec_status = SIEVE_EXEC_OK; strlist->strlist.next_item = sieve_single_stringlist_next_item; strlist->strlist.reset = sieve_single_stringlist_reset; strlist->strlist.get_length = sieve_single_stringlist_get_length; diff --git a/src/lib-sieve/sieve-stringlist.h b/src/lib-sieve/sieve-stringlist.h index f5446a0891718069a69f47a82d32e06a26bdd14f..cf37f5a78a9fd655edc94ec3c0a9eb5ba0a986b1 100644 --- a/src/lib-sieve/sieve-stringlist.h +++ b/src/lib-sieve/sieve-stringlist.h @@ -13,7 +13,7 @@ struct sieve_stringlist { int (*get_length) (struct sieve_stringlist *strlist); - bool (*read_all) + int (*read_all) (struct sieve_stringlist *strlist, pool_t pool, const char * const **list_r); @@ -21,6 +21,8 @@ struct sieve_stringlist { (struct sieve_stringlist *strlist, bool trace); const struct sieve_runtime_env *runenv; + int exec_status; + unsigned int trace:1; }; @@ -48,7 +50,7 @@ static inline void sieve_stringlist_reset int sieve_stringlist_get_length (struct sieve_stringlist *strlist); -bool sieve_stringlist_read_all +int sieve_stringlist_read_all (struct sieve_stringlist *strlist, pool_t pool, const char * const **list_r); diff --git a/src/lib-sieve/tst-address.c b/src/lib-sieve/tst-address.c index 1e6567ce19719a35c9aacebef4027278373f8d05..ec2fee9c70d911a0f276f14bf94028a72088a175 100644 --- a/src/lib-sieve/tst-address.c +++ b/src/lib-sieve/tst-address.c @@ -234,22 +234,22 @@ static int tst_address_operation_execute SIEVE_ADDRESS_PART_DEFAULT(all_address_part); struct sieve_stringlist *hdr_list, *hdr_value_list, *value_list, *key_list; struct sieve_address_list *addr_list; - int ret; + int match, ret; /* Read optional operands */ - if ( (ret=sieve_addrmatch_opr_optional_read - (renv, address, NULL, &addrp, &mcht, &cmp)) < 0 ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( sieve_addrmatch_opr_optional_read + (renv, address, NULL, &ret, &addrp, &mcht, &cmp) < 0 ) + return ret; /* Read header-list */ - if ( (hdr_list=sieve_opr_stringlist_read(renv, address, "header-list")) - == NULL ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_stringlist_read(renv, address, "header-list", &hdr_list)) + <= 0 ) + return ret; /* Read key-list */ - if ( (key_list=sieve_opr_stringlist_read(renv, address, "key-list")) - == NULL ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_stringlist_read(renv, address, "key-list", &key_list)) + <= 0 ) + return ret; sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "address test"); @@ -259,14 +259,10 @@ static int tst_address_operation_execute value_list = sieve_address_part_stringlist_create(renv, &addrp, addr_list); /* Perform match */ - ret = sieve_match(renv, &mcht, &cmp, value_list, key_list); - - /* Set test result for subsequent conditional jump */ - if ( ret >= 0 ) { - sieve_interpreter_set_test_result(renv->interp, ret > 0); - return SIEVE_EXEC_OK; - } + if ( (match=sieve_match(renv, &mcht, &cmp, value_list, key_list, &ret)) < 0 ) + return ret; - sieve_runtime_trace_error(renv, "invalid string-list item"); - return SIEVE_EXEC_BIN_CORRUPT; + /* Set test result for subsequent conditional jump */ + sieve_interpreter_set_test_result(renv->interp, match > 0); + return SIEVE_EXEC_OK; } diff --git a/src/lib-sieve/tst-exists.c b/src/lib-sieve/tst-exists.c index 4aa6c55aaa10913f3257d6dd601646b50734977f..c35e2eac1cfc8b17ae9f1854a0684119a8495cc8 100644 --- a/src/lib-sieve/tst-exists.c +++ b/src/lib-sieve/tst-exists.c @@ -106,19 +106,19 @@ static bool tst_exists_operation_dump static int tst_exists_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { - int ret; struct sieve_stringlist *hdr_list; string_t *hdr_item; bool matched; + int ret; /* * Read operands */ /* Read header-list */ - if ( (hdr_list=sieve_opr_stringlist_read(renv, address, "header-list")) - == NULL ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_stringlist_read(renv, address, "header-list", &hdr_list)) + <= 0 ) + return ret; /* * Perfrom test diff --git a/src/lib-sieve/tst-header.c b/src/lib-sieve/tst-header.c index 9f1b85f8c761f66a02750964012de96756e0aa51..7e2fedfcf899d5222ba4b9b8e560b6f2f1a7184e 100644 --- a/src/lib-sieve/tst-header.c +++ b/src/lib-sieve/tst-header.c @@ -134,13 +134,11 @@ static bool tst_header_generate static bool tst_header_operation_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address) { - int opt_code = 0; - sieve_code_dumpf(denv, "HEADER"); sieve_code_descend(denv); /* Optional operands */ - if ( sieve_match_opr_optional_dump(denv, address, &opt_code) != 0 ) + if ( sieve_match_opr_optional_dump(denv, address, NULL) != 0 ) return FALSE; return @@ -155,38 +153,31 @@ static bool tst_header_operation_dump static int tst_header_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { - int opt_code = 0; struct sieve_comparator cmp = SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator); struct sieve_match_type mcht = SIEVE_COMPARATOR_DEFAULT(is_match_type); struct sieve_stringlist *hdr_list, *key_list, *value_list; - int ret; + int match, ret; /* * Read operands */ /* Handle match-type and comparator operands */ - if ( (ret=sieve_match_opr_optional_read - (renv, address, &opt_code, &cmp, &mcht)) < 0 ) - return SIEVE_EXEC_BIN_CORRUPT; - - /* Check whether we neatly finished the list of optional operands*/ - if ( ret > 0 ) { - sieve_runtime_trace_error(renv, "invalid optional operand"); - return SIEVE_EXEC_BIN_CORRUPT; - } + if ( sieve_match_opr_optional_read(renv, address, NULL, &ret, &cmp, &mcht) + < 0 ) + return ret; /* Read header-list */ - if ( (hdr_list=sieve_opr_stringlist_read(renv, address, "header-list")) - == NULL ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_stringlist_read(renv, address, "header-list", &hdr_list)) + <= 0 ) + return ret; /* Read key-list */ - if ( (key_list=sieve_opr_stringlist_read(renv, address, "key-list")) - == NULL ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_stringlist_read(renv, address, "key-list", &key_list)) + <= 0 ) + return ret; /* * Perform test @@ -198,14 +189,10 @@ static int tst_header_operation_execute value_list = sieve_message_header_stringlist_create(renv, hdr_list); /* Perform match */ - ret = sieve_match(renv, &mcht, &cmp, value_list, key_list); - - /* Set test result for subsequent conditional jump */ - if ( ret >= 0 ) { - sieve_interpreter_set_test_result(renv->interp, ret > 0); - return SIEVE_EXEC_OK; - } + if ( (match=sieve_match(renv, &mcht, &cmp, value_list, key_list, &ret)) < 0 ) + return ret; - sieve_runtime_trace_error(renv, "invalid string-list item"); - return SIEVE_EXEC_BIN_CORRUPT; + /* Set test result for subsequent conditional jump */ + sieve_interpreter_set_test_result(renv->interp, match > 0); + return SIEVE_EXEC_OK; } diff --git a/src/lib-sieve/tst-size.c b/src/lib-sieve/tst-size.c index f10238d12af64bbf43d334b8eb2d1407ac571abd..53602545548b2bd56894d68001a9c35d7856e3b8 100644 --- a/src/lib-sieve/tst-size.c +++ b/src/lib-sieve/tst-size.c @@ -246,14 +246,15 @@ static int tst_size_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { sieve_number_t mail_size, limit; + int ret; /* * Read operands */ /* Read size limit */ - if ( !sieve_opr_number_read(renv, address, "limit", &limit) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_number_read(renv, address, "limit", &limit)) <= 0 ) + return ret; /* * Perform test diff --git a/src/managesieve/cmd-putscript.c b/src/managesieve/cmd-putscript.c index 8448606765dc081d11204e99fbfc03f6cb44a7f9..724b57040f08cd1d037c8eb47648c480a1062ba1 100644 --- a/src/managesieve/cmd-putscript.c +++ b/src/managesieve/cmd-putscript.c @@ -348,7 +348,7 @@ static bool cmd_putscript_continue_script(struct client_command_context *cmd) break; } if (ret == -1 || ret == 0) - break; + break; } } diff --git a/src/sieve-tools/debug/cmd-debug-print.c b/src/sieve-tools/debug/cmd-debug-print.c index 2fb27867ef5a18e7803fcfa24a72695764f9b13c..04f464e82e9e28611707c1d74e1b35e39018c060 100644 --- a/src/sieve-tools/debug/cmd-debug-print.c +++ b/src/sieve-tools/debug/cmd-debug-print.c @@ -103,7 +103,7 @@ static int cmd_debug_print_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { string_t *message; - int ret = SIEVE_EXEC_OK; + int ret; /* * Read operands @@ -111,8 +111,8 @@ static int cmd_debug_print_operation_execute /* Read message */ - if ( sieve_opr_string_read(renv, address, "message", &message) < 0 ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_string_read(renv, address, "message", &message)) <= 0 ) + return ret; /* * Perform operation @@ -123,5 +123,5 @@ static int cmd_debug_print_operation_execute /* FIXME: give this proper source location */ sieve_runtime_log(renv, "DEBUG", "%s", str_c(message)); - return ret; + return SIEVE_EXEC_OK; } diff --git a/src/testsuite/cmd-test-binary.c b/src/testsuite/cmd-test-binary.c index a8aef73278275c241406c38f799ca419612bce92..0b8b6619f358ff517fdc4022867573b3c697221d 100644 --- a/src/testsuite/cmd-test-binary.c +++ b/src/testsuite/cmd-test-binary.c @@ -222,6 +222,7 @@ static int cmd_test_binary_operation_execute { const struct sieve_operation *oprtn = renv->oprtn; string_t *binary_name = NULL; + int ret; /* * Read operands @@ -229,8 +230,9 @@ static int cmd_test_binary_operation_execute /* Binary Name */ - if ( !sieve_opr_string_read(renv, address, "binary-name", &binary_name) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_string_read(renv, address, "binary-name", &binary_name)) + <= 0 ) + return ret; /* * Perform operation diff --git a/src/testsuite/cmd-test-config.c b/src/testsuite/cmd-test-config.c index 91d2ca61e2a31f66e0999992feb5c1db4d16c93c..92cc7630dd29714947c0cff54260d3ca4033288e 100644 --- a/src/testsuite/cmd-test-config.c +++ b/src/testsuite/cmd-test-config.c @@ -318,18 +318,19 @@ static int cmd_test_config_set_operation_execute { string_t *setting; string_t *value; + int ret; /* * Read operands */ /* Setting */ - if ( !sieve_opr_string_read(renv, address, "setting", &setting) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_string_read(renv, address, "setting", &setting)) <= 0 ) + return ret; /* Value */ - if ( !sieve_opr_string_read(renv, address, "value", &value) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_string_read(renv, address, "value", &value)) <= 0 ) + return ret; /* * Perform operation @@ -352,14 +353,15 @@ static int cmd_test_config_unset_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { string_t *setting; + int ret; /* * Read operands */ /* Setting */ - if ( !sieve_opr_string_read(renv, address, "setting", &setting) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_string_read(renv, address, "setting", &setting)) <= 0 ) + return ret; /* * Perform operation @@ -382,14 +384,16 @@ static int cmd_test_config_reload_operation_execute { const struct sieve_extension *ext; string_t *extension; + int ret; /* * Read operands */ /* Extension */ - if ( !sieve_opr_string_read(renv, address, "extension", &extension) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_string_read(renv, address, "extension", &extension)) + <= 0 ) + return ret; /* * Perform operation diff --git a/src/testsuite/cmd-test-fail.c b/src/testsuite/cmd-test-fail.c index 238acc05315cab80989161f521e181a77ebc5630..b504de77d60760fe82e27d7570093881cc24980b 100644 --- a/src/testsuite/cmd-test-fail.c +++ b/src/testsuite/cmd-test-fail.c @@ -131,9 +131,10 @@ static int cmd_test_fail_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { string_t *reason; + int ret; - if ( !sieve_opr_string_read(renv, address, "reason", &reason) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_string_read(renv, address, "reason", &reason)) <= 0 ) + return ret; sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "testsuite: test_fail command; FAIL current test"); diff --git a/src/testsuite/cmd-test-mailbox.c b/src/testsuite/cmd-test-mailbox.c index 8ab5cc345855e627c14c0aba455dbe6ac5124409..7a508b54525c8e490035347a9b21193329e5e5b7 100644 --- a/src/testsuite/cmd-test-mailbox.c +++ b/src/testsuite/cmd-test-mailbox.c @@ -223,6 +223,7 @@ static int cmd_test_mailbox_operation_execute { const struct sieve_operation *oprtn = renv->oprtn; string_t *mailbox = NULL; + int ret; /* * Read operands @@ -230,8 +231,8 @@ static int cmd_test_mailbox_operation_execute /* Index */ - if ( !sieve_opr_string_read(renv, address, "mailbox", &mailbox) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_string_read(renv, address, "mailbox", &mailbox)) <= 0 ) + return ret; /* * Perform operation diff --git a/src/testsuite/cmd-test-message.c b/src/testsuite/cmd-test-message.c index 2623e4e35e0094d72aab7d6e5df8d49f738090fe..7c5d2c911568373b61ab8f8f1dbd79489f342411 100644 --- a/src/testsuite/cmd-test-message.c +++ b/src/testsuite/cmd-test-message.c @@ -301,6 +301,7 @@ static int cmd_test_message_smtp_operation_execute sieve_number_t msg_index; unsigned int is_test = -1; bool result; + int ret; /* * Read operands @@ -315,8 +316,8 @@ static int cmd_test_message_smtp_operation_execute /* Index */ - if ( !sieve_opr_number_read(renv, address, "index", &msg_index) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_number_read(renv, address, "index", &msg_index)) <= 0 ) + return ret; /* * Perform operation @@ -360,6 +361,7 @@ static int cmd_test_message_mailbox_operation_execute sieve_number_t msg_index; unsigned int is_test = -1; bool result; + int ret; /* * Read operands @@ -372,12 +374,12 @@ static int cmd_test_message_mailbox_operation_execute } /* Folder */ - if ( !sieve_opr_string_read(renv, address, "folder", &folder) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_string_read(renv, address, "folder", &folder)) <= 0 ) + return ret; /* Index */ - if ( !sieve_opr_number_read(renv, address, "index", &msg_index) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_number_read(renv, address, "index", &msg_index)) <= 0 ) + return ret; /* * Perform operation diff --git a/src/testsuite/cmd-test-set.c b/src/testsuite/cmd-test-set.c index 32077d6c80f4c582b90bd9fecee5fa8184edfa09..527bc0d21e89b5437975719e097aa6c38c929cb4 100644 --- a/src/testsuite/cmd-test-set.c +++ b/src/testsuite/cmd-test-set.c @@ -128,6 +128,7 @@ static int cmd_test_set_operation_execute struct testsuite_object tobj; string_t *value; int member_id; + int ret; if ( !testsuite_object_read_member (renv->sblock, address, &tobj, &member_id) ) { @@ -135,8 +136,8 @@ static int cmd_test_set_operation_execute return SIEVE_EXEC_BIN_CORRUPT; } - if ( !sieve_opr_string_read(renv, address, "string", &value) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_string_read(renv, address, "string", &value)) <= 0 ) + return ret; if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) { sieve_runtime_trace(renv, 0, "testsuite: test_set command"); diff --git a/src/testsuite/cmd-test.c b/src/testsuite/cmd-test.c index 40fb7f5c958c4dc074be57ac2b187d2ed0d4622d..123be9ee169495c98a922090314042d6713e53bc 100644 --- a/src/testsuite/cmd-test.c +++ b/src/testsuite/cmd-test.c @@ -151,9 +151,11 @@ static int cmd_test_operation_execute (const struct sieve_runtime_env *renv, sieve_size_t *address) { string_t *test_name; + int ret; - if ( !sieve_opr_string_read(renv, address, "test name", &test_name) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_string_read(renv, address, "test name", &test_name)) + <= 0 ) + return ret; sieve_runtime_trace_sep(renv); sieve_runtime_trace(renv, SIEVE_TRLVL_NONE, diff --git a/src/testsuite/testsuite-log.c b/src/testsuite/testsuite-log.c index 97b54a19434bd0a01de3aa7cca65942236c1ca11..039d9d934a908dfbda1112d650fd224986ee46c0 100644 --- a/src/testsuite/testsuite-log.c +++ b/src/testsuite/testsuite-log.c @@ -204,6 +204,7 @@ struct sieve_stringlist *testsuite_log_stringlist_create strlist = t_new(struct testsuite_log_stringlist, 1); strlist->strlist.runenv = renv; + strlist->strlist.exec_status = SIEVE_EXEC_OK; strlist->strlist.next_item = testsuite_log_stringlist_next_item; strlist->strlist.reset = testsuite_log_stringlist_reset; diff --git a/src/testsuite/testsuite-objects.c b/src/testsuite/testsuite-objects.c index 9c0c11c1ef8773691efdbb063a2df599fdc5b51e..c02626403e75414537ff312ccf7d5ff986cf0eaa 100644 --- a/src/testsuite/testsuite-objects.c +++ b/src/testsuite/testsuite-objects.c @@ -124,13 +124,13 @@ bool testsuite_object_read (struct sieve_binary_block *sblock, sieve_size_t *address, struct testsuite_object *tobj) { - struct sieve_operand operand; + struct sieve_operand oprnd; - if ( !sieve_operand_read(sblock, address, &operand) ) + if ( !sieve_operand_read(sblock, address, NULL, &oprnd) ) return FALSE; if ( !sieve_opr_object_read_data - (sblock, &operand, &sieve_testsuite_object_operand_class, address, + (sblock, &oprnd, &sieve_testsuite_object_operand_class, address, &tobj->object) ) return FALSE; diff --git a/src/testsuite/testsuite-result.c b/src/testsuite/testsuite-result.c index e73d31244d05304187ac9cb105c680d298be5b1d..f7340397b64fcfe4432ee02f48678ed44a9d3dab 100644 --- a/src/testsuite/testsuite-result.c +++ b/src/testsuite/testsuite-result.c @@ -121,6 +121,7 @@ struct sieve_stringlist *testsuite_result_stringlist_create strlist = t_new(struct testsuite_result_stringlist, 1); strlist->strlist.runenv = renv; + strlist->strlist.exec_status = SIEVE_EXEC_OK; strlist->strlist.next_item = testsuite_result_stringlist_next_item; strlist->strlist.reset = testsuite_result_stringlist_reset; diff --git a/src/testsuite/testsuite-substitutions.c b/src/testsuite/testsuite-substitutions.c index bb6d79c4d32ee7163ada870bbc17b91794c105f3..d36f3e9a313c1242e34623a0a2adb13e48122af7 100644 --- a/src/testsuite/testsuite-substitutions.c +++ b/src/testsuite/testsuite-substitutions.c @@ -136,10 +136,10 @@ static bool arg_testsuite_substitution_generate */ static bool opr_substitution_dump - (const struct sieve_dumptime_env *denv, const struct sieve_operand *opr, - sieve_size_t *address, const char *field_name); -static bool opr_substitution_read_value - (const struct sieve_runtime_env *renv, const struct sieve_operand *opr, + (const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, + sieve_size_t *address); +static int opr_substitution_read_value + (const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd, sieve_size_t *address, string_t **str); const struct sieve_opr_string_interface testsuite_substitution_interface = { @@ -167,9 +167,8 @@ void testsuite_opr_substitution_emit } static bool opr_substitution_dump -(const struct sieve_dumptime_env *denv, - const struct sieve_operand *opr ATTR_UNUSED, sieve_size_t *address, - const char *field_name) +(const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd, + sieve_size_t *address) { unsigned int code = 0; const struct testsuite_substitution_def *tsub; @@ -185,41 +184,48 @@ static bool opr_substitution_dump if ( !sieve_binary_read_string(denv->sblock, address, ¶m) ) return FALSE; - if ( field_name != NULL ) + if ( oprnd->field_name != NULL ) sieve_code_dumpf(denv, "%s: TEST_SUBS %%{%s:%s}", - field_name, tsub->obj_def.identifier, str_c(param)); + oprnd->field_name, tsub->obj_def.identifier, str_c(param)); else sieve_code_dumpf(denv, "TEST_SUBS %%{%s:%s}", tsub->obj_def.identifier, str_c(param)); return TRUE; } -static bool opr_substitution_read_value +static int opr_substitution_read_value (const struct sieve_runtime_env *renv, - const struct sieve_operand *opr ATTR_UNUSED, sieve_size_t *address, - string_t **str) + const struct sieve_operand *oprnd ATTR_UNUSED, sieve_size_t *address, + string_t **str_r) { const struct testsuite_substitution_def *tsub; unsigned int code = 0; string_t *param; if ( !sieve_binary_read_unsigned(renv->sblock, address, &code) ) - return FALSE; + return SIEVE_EXEC_BIN_CORRUPT; tsub = testsuite_substitution_get(code); if ( tsub == NULL ) - return FALSE; + return SIEVE_EXEC_FAILURE; /* Parameter str can be NULL if we are requested to only skip and not * actually read the argument. */ - if ( str == NULL ) - return sieve_binary_read_string(renv->sblock, address, NULL); + if ( str_r == NULL ) { + if ( !sieve_binary_read_string(renv->sblock, address, NULL) ) + return SIEVE_EXEC_BIN_CORRUPT; + + return SIEVE_EXEC_OK; + } if ( !sieve_binary_read_string(renv->sblock, address, ¶m) ) - return FALSE; + return SIEVE_EXEC_BIN_CORRUPT; - return tsub->get_value(str_c(param), str); + if ( !tsub->get_value(str_c(param), str_r) ) + return SIEVE_EXEC_FAILURE; + + return SIEVE_EXEC_OK; } /* diff --git a/src/testsuite/tst-test-error.c b/src/testsuite/tst-test-error.c index 9d7f1e58afd34066e912487b1c0d51436d70e823..925ae552540559f712e86d2f77cba971d1a1d128 100644 --- a/src/testsuite/tst-test-error.c +++ b/src/testsuite/tst-test-error.c @@ -183,13 +183,13 @@ static bool tst_test_error_operation_dump /* Handle any optional arguments */ for (;;) { - int ret; + int opt; - if ( (ret=sieve_match_opr_optional_dump(denv, address, &opt_code)) + if ( (opt=sieve_match_opr_optional_dump(denv, address, &opt_code)) < 0 ) return FALSE; - if ( ret == 0 ) break; + if ( opt == 0 ) break; if ( opt_code == OPT_INDEX ) { if ( !sieve_opr_number_dump(denv, address, "index") ) @@ -214,7 +214,7 @@ static int tst_test_error_operation_execute struct sieve_match_type mcht = SIEVE_COMPARATOR_DEFAULT(is_match_type); struct sieve_stringlist *value_list, *key_list; int index = -1; - int ret; + int match, ret; /* * Read operands @@ -223,17 +223,17 @@ static int tst_test_error_operation_execute /* Read optional operands */ for (;;) { sieve_number_t number; - int ret; + int opt; - if ( (ret=sieve_match_opr_optional_read - (renv, address, &opt_code, &cmp, &mcht)) < 0 ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (opt=sieve_match_opr_optional_read + (renv, address, &opt_code, &ret, &cmp, &mcht)) < 0 ) + return ret; - if ( ret == 0 ) break; + if ( opt == 0 ) break; if ( opt_code == OPT_INDEX ) { - if ( !sieve_opr_number_read(renv, address, "index", &number) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_number_read(renv, address, "index", &number)) <= 0 ) + return ret; index = (int) number; } else { sieve_runtime_trace_error(renv, "invalid optional operand"); @@ -242,8 +242,9 @@ static int tst_test_error_operation_execute } /* Read key-list */ - if ( (key_list=sieve_opr_stringlist_read(renv, address, "key_list")) == NULL ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_stringlist_read(renv, address, "key_list", &key_list)) + <= 0 ) + return ret; /* * Perform operation @@ -260,16 +261,12 @@ static int tst_test_error_operation_execute value_list = testsuite_log_stringlist_create(renv, index); /* Perform match */ - ret = sieve_match(renv, &mcht, &cmp, value_list, key_list); + if ( (match=sieve_match(renv, &mcht, &cmp, value_list, key_list, &ret)) < 0 ) + return ret; /* Set test result for subsequent conditional jump */ - if ( ret >= 0 ) { - sieve_interpreter_set_test_result(renv->interp, ret > 0); - return SIEVE_EXEC_OK; - } - - sieve_runtime_trace_error(renv, "invalid string-list item"); - return SIEVE_EXEC_BIN_CORRUPT; + sieve_interpreter_set_test_result(renv->interp, match > 0); + return SIEVE_EXEC_OK; } diff --git a/src/testsuite/tst-test-multiscript.c b/src/testsuite/tst-test-multiscript.c index 156bf434ac6a4a5cb02793f6fbaad1f26c19ce1a..fab25e3f04f29af72b072d7842bd030896a21d24 100644 --- a/src/testsuite/tst-test-multiscript.c +++ b/src/testsuite/tst-test-multiscript.c @@ -118,9 +118,9 @@ static int tst_test_multiscript_operation_execute * Read operands */ - if ( (scripts_list=sieve_opr_stringlist_read(renv, address, "scripts")) - == NULL ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_stringlist_read(renv, address, "scripts", &scripts_list)) + <= 0 ) + return ret; /* * Perform operation diff --git a/src/testsuite/tst-test-result.c b/src/testsuite/tst-test-result.c index 9a9889bd9c70524712da11c188567c18d2d9dd99..178a8648c7f058219ec76cfc00fdbdab6c8a273e 100644 --- a/src/testsuite/tst-test-result.c +++ b/src/testsuite/tst-test-result.c @@ -188,13 +188,13 @@ static bool tst_test_result_operation_dump /* Handle any optional arguments */ for (;;) { - int ret; + int opt; - if ( (ret=sieve_match_opr_optional_dump(denv, address, &opt_code)) + if ( (opt=sieve_match_opr_optional_dump(denv, address, &opt_code)) < 0 ) return FALSE; - if ( ret == 0 ) break; + if ( opt == 0 ) break; if ( opt_code == OPT_INDEX ) { if ( !sieve_opr_number_dump(denv, address, "index") ) @@ -219,7 +219,7 @@ static int tst_test_result_operation_execute struct sieve_match_type mcht = SIEVE_MATCH_TYPE_DEFAULT(is_match_type); struct sieve_stringlist *value_list, *key_list; int index = 0; - int ret; + int match, ret; /* * Read operands @@ -228,17 +228,17 @@ static int tst_test_result_operation_execute /* Read optional operands */ for (;;) { sieve_number_t number; - int ret; + int opt; - if ( (ret=sieve_match_opr_optional_read - (renv, address, &opt_code, &cmp, &mcht)) < 0 ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (opt=sieve_match_opr_optional_read + (renv, address, &opt_code, &ret, &cmp, &mcht)) < 0 ) + return ret; - if ( ret == 0 ) break; + if ( opt == 0 ) break; if ( opt_code == OPT_INDEX ) { - if ( !sieve_opr_number_read(renv, address, "index", &number) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_number_read(renv, address, "index", &number)) <= 0 ) + return ret; index = (int) number; } else { sieve_runtime_trace_error(renv, "invalid optional operand"); @@ -247,8 +247,9 @@ static int tst_test_result_operation_execute } /* Read key-list */ - if ( (key_list=sieve_opr_stringlist_read(renv, address, "key-list")) == NULL ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_stringlist_read(renv, address, "key-list", &key_list)) + <= 0 ) + return ret; /* * Perform operation @@ -261,16 +262,12 @@ static int tst_test_result_operation_execute value_list = testsuite_result_stringlist_create(renv, index); /* Perform match */ - ret = sieve_match(renv, &mcht, &cmp, value_list, key_list); + if ( (match=sieve_match(renv, &mcht, &cmp, value_list, key_list, &ret)) < 0 ) + return ret; /* Set test result for subsequent conditional jump */ - if ( ret >= 0 ) { - sieve_interpreter_set_test_result(renv->interp, ret > 0); - return SIEVE_EXEC_OK; - } - - sieve_runtime_trace_error(renv, "invalid string-list item"); - return SIEVE_EXEC_BIN_CORRUPT; + sieve_interpreter_set_test_result(renv->interp, match > 0); + return SIEVE_EXEC_OK; } diff --git a/src/testsuite/tst-test-script-compile.c b/src/testsuite/tst-test-script-compile.c index 58ec3f413bd611a7f1d83918339bbe6bfc532f02..4d476011869de63d4625f8ff2c9409e2cb9289b5 100644 --- a/src/testsuite/tst-test-script-compile.c +++ b/src/testsuite/tst-test-script-compile.c @@ -109,13 +109,15 @@ static int tst_test_script_compile_operation_execute { string_t *script_name; bool result = TRUE; + int ret; /* * Read operands */ - if ( !sieve_opr_string_read(renv, address, "script-name", &script_name) ) - return SIEVE_EXEC_BIN_CORRUPT; + if ( (ret=sieve_opr_string_read(renv, address, "script-name", &script_name)) + <= 0 ) + return ret; /* * Perform operation diff --git a/src/testsuite/tst-test-script-run.c b/src/testsuite/tst-test-script-run.c index c59d91013e53e0ab953d5979a009f168d339c2e0..aaf9d471e685b4622654f8ecdd8b940ebe9c7709 100644 --- a/src/testsuite/tst-test-script-run.c +++ b/src/testsuite/tst-test-script-run.c @@ -111,12 +111,12 @@ static bool tst_test_script_run_operation_dump /* Dump optional operands */ for (;;) { - int ret; + int opt; - if ( (ret=sieve_opr_optional_dump(denv, address, &opt_code)) < 0 ) + if ( (opt=sieve_opr_optional_dump(denv, address, &opt_code)) < 0 ) return FALSE; - if ( ret == 0 ) break; + if ( opt == 0 ) break; switch ( opt_code ) { case OPT_APPEND_RESULT: @@ -148,12 +148,12 @@ static int tst_test_script_run_operation_execute /* Optional operands */ for (;;) { - int ret; + int opt; - if ( (ret=sieve_opr_optional_read(renv, address, &opt_code)) < 0 ) + if ( (opt=sieve_opr_optional_read(renv, address, &opt_code)) < 0 ) return SIEVE_EXEC_BIN_CORRUPT; - if ( ret == 0 ) break; + if ( opt == 0 ) break; switch ( opt_code ) { case OPT_APPEND_RESULT: