static bool cmd_fileinto_validate (struct sieve_validator *valdtr, struct sieve_command *cmd) { struct sieve_ast_argument *arg = cmd->first_positional; if ( !sieve_validate_positional_argument (valdtr, cmd, arg, "folder", 1, SAAT_STRING) ) { return FALSE; } if ( !sieve_validator_argument_activate(valdtr, cmd, arg, FALSE) ) return FALSE; /* Check name validity when folder argument is not a variable */ if ( sieve_argument_is_string_literal(arg) ) { const char *folder = sieve_ast_argument_strc(arg), *error; if ( !sieve_mailbox_check_name(folder, &error) ) { sieve_command_validate_error(valdtr, cmd, "invalid folder name `%s' specified for fileinto command: %s", str_sanitize(folder, 256), error); return FALSE; } } return TRUE; }
static int _ext_enotify_option_check (void *context, struct sieve_ast_argument *arg) { struct _ext_enotify_option_check_context *optn_context = (struct _ext_enotify_option_check_context *) context; struct sieve_validator *valdtr = optn_context->valdtr; const struct sieve_enotify_method *method = optn_context->method; struct sieve_enotify_env nenv; const char *option = sieve_ast_argument_strc(arg); const char *opt_name = NULL, *opt_value = NULL; bool check = TRUE; int result = 1; /* Compose log structure */ memset(&nenv, 0, sizeof(nenv)); nenv.svinst = optn_context->svinst; nenv.method = method; nenv.ehandler = sieve_prefix_ehandler_create (sieve_validator_error_handler(valdtr), sieve_error_script_location (sieve_validator_script(valdtr), arg->source_line), "notify command"); /* Parse option */ if ( !sieve_argument_is_string_literal(arg) ) { /* Variable string: partial option parse * * If the string item is not a string literal, it cannot be validated fully * at compile time. We can however check whether the '=' is in the string * specification and whether the part before the '=' is a valid option name. * In that case, the method option check function is called with the value * parameter equal to NULL, meaning that it should only check the validity * of the option itself and not the assigned value. */ if ( !ext_enotify_option_parse(NULL, option, TRUE, &opt_name, &opt_value) ) check = FALSE; } else { /* Literal string: full option parse */ if ( !ext_enotify_option_parse (&nenv, option, FALSE, &opt_name, &opt_value) ) result = -1; } /* Call method's option check function */ if ( result > 0 && check && method->def != NULL && method->def->compile_check_option != NULL ) { result = ( method->def->compile_check_option (&nenv, opt_name, opt_value) ? 1 : -1 ); } sieve_error_handler_unref(&nenv.ehandler); return result; }
static bool tag_comparator_validate (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd) { struct sieve_ast_argument *tag = *arg; const struct sieve_comparator *cmp; /* Skip tag */ *arg = sieve_ast_argument_next(*arg); /* Check syntax: * ":comparator" <comparator-name: string> */ if ( !sieve_validate_tag_parameter (valdtr, cmd, tag, *arg, NULL, 0, SAAT_STRING, FALSE) ) { return FALSE; } /* FIXME: We can currently only handle string literal argument, so * variables are not allowed. */ if ( !sieve_argument_is_string_literal(*arg) ) { sieve_argument_validate_error(valdtr, *arg, "this Sieve implementation currently only supports " "a literal string argument for the :comparator tag"); return FALSE; } /* Get comparator from registry */ cmp = sieve_comparator_create(valdtr, cmd, sieve_ast_argument_strc(*arg)); if ( cmp == NULL ) { sieve_argument_validate_error(valdtr, *arg, "unknown comparator '%s'", str_sanitize(sieve_ast_argument_strc(*arg),80)); return FALSE; } /* String argument not needed during code generation, so detach it from * argument list */ *arg = sieve_ast_arguments_detach(*arg, 1); /* Store comparator in context */ tag->argument->data = (void *) cmp; return TRUE; }
static bool cmd_vacation_validate_string_tag (struct sieve_validator *valdtr, struct sieve_ast_argument **arg, struct sieve_command *cmd) { struct sieve_ast_argument *tag = *arg; struct cmd_vacation_context_data *ctx_data = (struct cmd_vacation_context_data *) cmd->data; /* Detach the tag itself */ *arg = sieve_ast_arguments_detach(*arg,1); /* Check syntax: * :subject string * :from string * :handle string */ if ( !sieve_validate_tag_parameter (valdtr, cmd, tag, *arg, NULL, 0, SAAT_STRING, FALSE) ) { return FALSE; } if ( sieve_argument_is(tag, vacation_from_tag) ) { if ( sieve_argument_is_string_literal(*arg) ) { string_t *address = sieve_ast_argument_str(*arg); const char *error; bool result; T_BEGIN { result = sieve_address_validate(address, &error); if ( !result ) { sieve_argument_validate_error(valdtr, *arg, "specified :from address '%s' is invalid for vacation action: %s", str_sanitize(str_c(address), 128), error); } } T_END; if ( !result ) return FALSE; } ctx_data->from = sieve_ast_argument_str(*arg); /* Skip parameter */ *arg = sieve_ast_argument_next(*arg); } else if ( sieve_argument_is(tag, vacation_subject_tag) ) {
static int _arg_validate (void *context, struct sieve_ast_argument *item) { struct _arg_validate_context *actx = (struct _arg_validate_context *) context; if ( sieve_argument_is_string_literal(item) ) { string_t *arg = sieve_ast_argument_str(item); if ( !sieve_extprogram_arg_is_valid(arg) ) { sieve_argument_validate_error(actx->valdtr, item, "%s %s: specified external program argument `%s' is invalid", sieve_command_identifier(actx->cmd), sieve_command_type_name(actx->cmd), str_sanitize(str_c(arg), 128)); return FALSE; } } return TRUE; }
bool sieve_extprogram_command_validate (struct sieve_validator *valdtr, struct sieve_command *cmd) { struct sieve_ast_argument *arg = cmd->first_positional; struct sieve_ast_argument *stritem; struct _arg_validate_context actx; string_t *program_name; if ( arg == NULL ) { sieve_command_validate_error(valdtr, cmd, "the %s %s expects at least one positional argument, but none was found", sieve_command_identifier(cmd), sieve_command_type_name(cmd)); return FALSE; } /* <program-name: string> argument */ if ( !sieve_validate_positional_argument (valdtr, cmd, arg, "program-name", 1, SAAT_STRING) ) { return FALSE; } if ( !sieve_validator_argument_activate(valdtr, cmd, arg, FALSE) ) return FALSE; /* Variables are not allowed */ if ( !sieve_argument_is_string_literal(arg) ) { sieve_argument_validate_error(valdtr, arg, "the %s %s requires a constant string " "for its program-name argument", sieve_command_identifier(cmd), sieve_command_type_name(cmd)); return FALSE; } /* Check program name */ program_name = sieve_ast_argument_str(arg); if ( !sieve_extprogram_name_is_valid(program_name) ) { sieve_argument_validate_error(valdtr, arg, "%s %s: invalid program name '%s'", sieve_command_identifier(cmd), sieve_command_type_name(cmd), str_sanitize(str_c(program_name), 80)); return FALSE; } /* Optional <arguments: string-list> argument */ arg = sieve_ast_argument_next(arg); if ( arg == NULL ) return TRUE; if ( !sieve_validate_positional_argument (valdtr, cmd, arg, "arguments", 2, SAAT_STRING_LIST) ) { return FALSE; } if ( !sieve_validator_argument_activate(valdtr, cmd, arg, FALSE) ) return FALSE; /* Check arguments */ actx.valdtr = valdtr; actx.cmd = cmd; stritem = arg; if ( sieve_ast_stringlist_map (&stritem, (void *)&actx, _arg_validate) <= 0 ) { return FALSE; } if ( sieve_ast_argument_next(arg) != NULL ) { sieve_command_validate_error(valdtr, cmd, "the %s %s expects at most two positional arguments, but more were found", sieve_command_identifier(cmd), sieve_command_type_name(cmd)); return FALSE; } return TRUE; }
bool ext_imap4flags_command_validate (struct sieve_validator *valdtr, struct sieve_command *cmd) { struct sieve_ast_argument *arg = cmd->first_positional; struct sieve_ast_argument *arg2; const struct sieve_extension *var_ext; /* Check arguments */ if ( arg == NULL ) { sieve_command_validate_error(valdtr, cmd, "the %s %s expects at least one argument, but none was found", sieve_command_identifier(cmd), sieve_command_type_name(cmd)); return FALSE; } if ( sieve_ast_argument_type(arg) != SAAT_STRING && sieve_ast_argument_type(arg) != SAAT_STRING_LIST ) { sieve_argument_validate_error(valdtr, arg, "the %s %s expects either a string (variable name) or " "a string-list (list of flags) as first argument, but %s was found", sieve_command_identifier(cmd), sieve_command_type_name(cmd), sieve_ast_argument_name(arg)); return FALSE; } arg2 = sieve_ast_argument_next(arg); if ( arg2 != NULL ) { /* First, check syntax sanity */ if ( sieve_ast_argument_type(arg) != SAAT_STRING ) { if ( sieve_command_is(cmd, tst_hasflag) ) { if ( sieve_ast_argument_type(arg) != SAAT_STRING_LIST ) { sieve_argument_validate_error(valdtr, arg, "if a second argument is specified for the hasflag, the first " "must be a string-list (variable-list), but %s was found", sieve_ast_argument_name(arg)); return FALSE; } } else { sieve_argument_validate_error(valdtr, arg, "if a second argument is specified for the %s %s, the first " "must be a string (variable name), but %s was found", sieve_command_identifier(cmd), sieve_command_type_name(cmd), sieve_ast_argument_name(arg)); return FALSE; } } /* Then, check whether the second argument is permitted */ var_ext = sieve_ext_variables_get_extension(cmd->ext->svinst); if ( var_ext == NULL || !sieve_ext_variables_is_active(var_ext, valdtr) ) { sieve_argument_validate_error(valdtr,arg, "the %s %s only allows for the specification of a " "variable name when the variables extension is active", sieve_command_identifier(cmd), sieve_command_type_name(cmd)); return FALSE; } if ( !sieve_variable_argument_activate (var_ext, valdtr, cmd, arg, !sieve_command_is(cmd, tst_hasflag) ) ) return FALSE; if ( sieve_ast_argument_type(arg2) != SAAT_STRING && sieve_ast_argument_type(arg2) != SAAT_STRING_LIST ) { sieve_argument_validate_error(valdtr, arg2, "the %s %s expects a string list (list of flags) as " "second argument when two arguments are specified, " "but %s was found", sieve_command_identifier(cmd), sieve_command_type_name(cmd), sieve_ast_argument_name(arg2)); return FALSE; } } else arg2 = arg; if ( !sieve_validator_argument_activate(valdtr, cmd, arg2, FALSE) ) return FALSE; if ( !sieve_command_is(cmd, tst_hasflag) && sieve_argument_is_string_literal(arg2) ) { struct ext_imap4flags_iter fiter; const char *flag; /* Warn the user about validity of verifiable flags */ ext_imap4flags_iter_init(&fiter, sieve_ast_argument_str(arg)); while ( (flag=ext_imap4flags_iter_get_flag(&fiter)) != NULL ) { if ( !sieve_ext_imap4flags_flag_is_valid(flag) ) { sieve_argument_validate_warning(valdtr, arg, "IMAP flag '%s' specified for the %s command is invalid " "and will be ignored (only first invalid is reported)", str_sanitize(flag, 64), sieve_command_identifier(cmd)); break; } } } return TRUE; }
bool ext_enotify_compile_check_arguments (struct sieve_validator *valdtr, struct sieve_command *cmd, struct sieve_ast_argument *uri_arg, struct sieve_ast_argument *msg_arg, struct sieve_ast_argument *from_arg, struct sieve_ast_argument *options_arg) { const struct sieve_extension *this_ext = cmd->ext; struct sieve_instance *svinst = this_ext->svinst; const char *uri = sieve_ast_argument_strc(uri_arg); const char *scheme; const struct sieve_enotify_method *method; struct sieve_enotify_env nenv; bool result = TRUE; /* If the uri string is not a constant literal, we cannot determine which * method is used, so we bail out successfully and defer checking to runtime. */ if ( !sieve_argument_is_string_literal(uri_arg) ) return TRUE; /* Parse scheme part of URI */ if ( (scheme=ext_enotify_uri_scheme_parse(&uri)) == NULL ) { sieve_argument_validate_error(valdtr, uri_arg, "notify command: invalid scheme part for method URI '%s'", str_sanitize(sieve_ast_argument_strc(uri_arg), 80)); return FALSE; } /* Find used method with the parsed scheme identifier */ if ( (method=ext_enotify_method_find(this_ext, scheme)) == NULL ) { sieve_argument_validate_error(valdtr, uri_arg, "notify command: invalid method '%s'", scheme); return FALSE; } if ( method->def == NULL ) return TRUE; /* Compose log structure */ memset(&nenv, 0, sizeof(nenv)); nenv.svinst = svinst; nenv.method = method; /* Check URI itself */ if ( result && method->def->compile_check_uri != NULL ) { /* Set log location to location of URI argument */ nenv.ehandler = sieve_prefix_ehandler_create (sieve_validator_error_handler(valdtr), sieve_error_script_location (sieve_validator_script(valdtr), uri_arg->source_line), "notify command"); /* Execute method check function */ result = method->def->compile_check_uri (&nenv, sieve_ast_argument_strc(uri_arg), uri); } /* Check :message argument */ if ( result && msg_arg != NULL && sieve_argument_is_string_literal(msg_arg) && method->def->compile_check_message != NULL ) { /* Set log location to location of :message argument */ sieve_error_handler_unref(&nenv.ehandler); nenv.ehandler = sieve_prefix_ehandler_create (sieve_validator_error_handler(valdtr), sieve_error_script_location (sieve_validator_script(valdtr), msg_arg->source_line), "notify command"); /* Execute method check function */ result = method->def->compile_check_message (&nenv, sieve_ast_argument_str(msg_arg)); } /* Check :from argument */ if ( result && from_arg != NULL && sieve_argument_is_string_literal(from_arg) && method->def->compile_check_from != NULL ) { /* Set log location to location of :from argument */ sieve_error_handler_unref(&nenv.ehandler); nenv.ehandler = sieve_prefix_ehandler_create (sieve_validator_error_handler(valdtr), sieve_error_script_location (sieve_validator_script(valdtr), from_arg->source_line), "notify command"); /* Execute method check function */ result = method->def->compile_check_from (&nenv, sieve_ast_argument_str(from_arg)); } sieve_error_handler_unref(&nenv.ehandler); /* Check :options argument */ if ( result && options_arg != NULL ) { struct sieve_ast_argument *option = options_arg; struct _ext_enotify_option_check_context optn_context = { svinst, valdtr, method }; /* Parse and check options */ result = ( sieve_ast_stringlist_map (&option, (void *) &optn_context, _ext_enotify_option_check) > 0 ); /* Discard argument if options are not accepted by method */ if ( result && method->def->compile_check_option == NULL ) { sieve_argument_validate_warning(valdtr, options_arg, "notify command: method '%s' accepts no options", scheme); (void)sieve_ast_arguments_detach(options_arg,1); } } return result; }