diff --git a/src/lib-sieve/plugins/date/ext-date-common.c b/src/lib-sieve/plugins/date/ext-date-common.c index 936b24c53f2d2f1359170b233e76775b0cc9c435..ff3fa129057dce74cff43263155deb9cae86836d 100644 --- a/src/lib-sieve/plugins/date/ext-date-common.c +++ b/src/lib-sieve/plugins/date/ext-date-common.c @@ -282,23 +282,28 @@ static const struct ext_date_part *date_parts[] = { unsigned int date_parts_count = N_ELEMENTS(date_parts); -const char *ext_date_part_extract -(const char *part, struct tm *tm, int zone_offset) +const struct ext_date_part *ext_date_part_find(const char *part) { unsigned int i; for ( i = 0; i < date_parts_count; i++ ) { if ( strcasecmp(date_parts[i]->identifier, part) == 0 ) { - if ( date_parts[i]->get_string != NULL ) - return date_parts[i]->get_string(tm, zone_offset); - - return NULL; + return date_parts[i]; } } return NULL; } +const char *ext_date_part_extract +(const struct ext_date_part *dpart, struct tm *tm, int zone_offset) +{ + if ( dpart == NULL || dpart->get_string == NULL ) + return NULL; + + return dpart->get_string(tm, zone_offset); +} + /* * Date part implementations */ @@ -486,7 +491,7 @@ struct ext_date_stringlist { struct sieve_stringlist *field_values; int time_zone; - const char *date_part; + const struct ext_date_part *date_part; time_t local_time; int local_zone; @@ -496,7 +501,7 @@ struct ext_date_stringlist { struct sieve_stringlist *ext_date_stringlist_create (const struct sieve_runtime_env *renv, struct sieve_stringlist *field_values, - int time_zone, const char *date_part) + int time_zone, const struct ext_date_part *dpart) { struct ext_date_stringlist *strlist; @@ -507,7 +512,7 @@ struct sieve_stringlist *ext_date_stringlist_create strlist->strlist.reset = ext_date_stringlist_reset; strlist->field_values = field_values; strlist->time_zone = time_zone; - strlist->date_part = date_part; + strlist->date_part = dpart; strlist->local_time = ext_date_get_current_date(renv, &strlist->local_zone); diff --git a/src/lib-sieve/plugins/date/ext-date-common.h b/src/lib-sieve/plugins/date/ext-date-common.h index 918d9f57cd5a25c35cab0f536505f455ed2f7f15..a0a6dd3527f99fd2a5aa98dcc2894776fa6177db 100644 --- a/src/lib-sieve/plugins/date/ext-date-common.h +++ b/src/lib-sieve/plugins/date/ext-date-common.h @@ -60,8 +60,10 @@ struct ext_date_part { const char *(*get_string)(struct tm *tm, int zone_offset); }; +const struct ext_date_part *ext_date_part_find(const char *part); + const char *ext_date_part_extract - (const char *part, struct tm *tm, int zone_offset); + (const struct ext_date_part *dpart, struct tm *tm, int zone_offset); /* * Date stringlist @@ -74,7 +76,7 @@ enum ext_date_timezone_special { struct sieve_stringlist *ext_date_stringlist_create (const struct sieve_runtime_env *renv, struct sieve_stringlist *field_values, - int time_zone, const char *date_part); + int time_zone, const struct ext_date_part *dpart); diff --git a/src/lib-sieve/plugins/date/tst-date.c b/src/lib-sieve/plugins/date/tst-date.c index d84581276991902a2be11dede2928563380dfa94..981ba943f5490ec3f19115b9208068d9d0792acd 100644 --- a/src/lib-sieve/plugins/date/tst-date.c +++ b/src/lib-sieve/plugins/date/tst-date.c @@ -260,7 +260,7 @@ static bool tst_date_validate return FALSE; if ( !sieve_command_verify_headers_argument(valdtr, arg) ) - return FALSE; + return FALSE; arg = sieve_ast_argument_next(arg); } @@ -275,6 +275,16 @@ static bool tst_date_validate if ( !sieve_validator_argument_activate(valdtr, tst, arg, FALSE) ) return FALSE; + if ( sieve_argument_is_string_literal(arg) ) { + const char * part = sieve_ast_argument_strc(arg); + + if ( ext_date_part_find(part) == NULL ) { + sieve_argument_validate_warning + (valdtr, arg, "specified date part `%s' is not known", + str_sanitize(part, 80)); + } + } + arg = sieve_ast_argument_next(arg); /* Check key list */ @@ -349,7 +359,7 @@ static bool tst_date_operation_dump if ( !sieve_opr_string_dump_ex(denv, address, "zone", "ORIGINAL") ) return FALSE; break; - default: + default: return FALSE; } } @@ -381,6 +391,7 @@ static int tst_date_operation_execute struct sieve_stringlist *hdr_list = NULL, *hdr_value_list; struct sieve_stringlist *value_list, *key_list; bool zone_specified = FALSE, zone_literal = TRUE; + const struct ext_date_part *dpart; int time_zone; int match, ret; @@ -433,11 +444,19 @@ static int tst_date_operation_execute } else if ( !ext_date_parse_timezone(str_c(zone), &time_zone) ) { if ( !zone_literal ) sieve_runtime_warning(renv, NULL, - "specified :zone argument '%s' is not a valid timezone " + "specified :zone argument `%s' is not a valid timezone " "(using local zone)", str_sanitize(str_c(zone), 40)); time_zone = EXT_DATE_TIMEZONE_LOCAL; } + if ( (dpart=ext_date_part_find(str_c(date_part))) == NULL ) { + sieve_runtime_warning(renv, NULL, + "specified date part argument `%s' is not known", + str_sanitize(str_c(date_part), 40)); + sieve_interpreter_set_test_result(renv->interp, FALSE); + return SIEVE_EXEC_OK; + } + /* * Perform test */ @@ -449,7 +468,7 @@ static int tst_date_operation_execute /* Create value stringlist */ hdr_value_list = sieve_message_header_stringlist_create(renv, hdr_list, FALSE); value_list = ext_date_stringlist_create - (renv, hdr_value_list, time_zone, str_c(date_part)); + (renv, hdr_value_list, time_zone, dpart); } else if ( sieve_operation_is(op, currentdate_operation) ) { /* Use time stamp recorded at the time the script first started */ @@ -457,8 +476,7 @@ static int tst_date_operation_execute sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "currentdatedate test"); /* Create value stringlist */ - value_list = ext_date_stringlist_create - (renv, NULL, time_zone, str_c(date_part)); + value_list = ext_date_stringlist_create(renv, NULL, time_zone, dpart); } else { i_unreached(); }