struct sieve_variable *ext_include_variable_import_global (struct sieve_validator *valdtr, struct sieve_command *cmd, const char *variable) { const struct sieve_extension *this_ext = cmd->ext; struct sieve_ast *ast = cmd->ast_node->ast; struct ext_include_ast_context *ctx = ext_include_get_ast_context(this_ext, ast); struct ext_include_context *ectx = ext_include_get_context(this_ext); struct sieve_variable_scope *local_scope; struct sieve_variable_scope *global_scope = ctx->global_vars; struct sieve_variable *global_var = NULL, *local_var; /* Sanity safeguard */ i_assert ( ctx->global_vars != NULL ); if ( !sieve_variable_identifier_is_valid(variable) ) { sieve_command_validate_error(valdtr, cmd, "invalid variable identifier '%s'", str_sanitize(variable,80)); return NULL; } /* Get/Declare the variable in the global scope */ global_var = sieve_variable_scope_get_variable(global_scope, variable, TRUE); /* Check whether scope is over its size limit */ if ( global_var == NULL ) { sieve_command_validate_error(valdtr, cmd, "declaration of new global variable '%s' exceeds the limit " "(max variables: %u)", variable, sieve_variables_get_max_scope_size()); return NULL; } /* Import the global variable into the local script scope */ local_scope = sieve_ext_variables_get_local_scope(ectx->var_ext, valdtr); local_var = sieve_variable_scope_get_variable(local_scope, variable, FALSE); if ( local_var != NULL && local_var->ext != this_ext ) { /* FIXME: indicate location of conflicting set statement */ sieve_command_validate_error(valdtr, cmd, "declaration of new global variable '%s' conflicts with earlier local " "use", variable); return NULL; } return sieve_variable_scope_import(local_scope, global_var); }
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; }
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; }
static bool cmd_global_validate (struct sieve_validator *valdtr, struct sieve_command *cmd) { const struct sieve_extension *this_ext = cmd->ext; struct sieve_ast_argument *arg = cmd->first_positional; struct sieve_command *prev = sieve_command_prev(cmd); /* DEPRECATED: Check valid command placement */ if ( !sieve_command_is(cmd, cmd_global) ) { if ( !sieve_command_is_toplevel(cmd) || ( !sieve_command_is_first(cmd) && prev != NULL && !sieve_command_is(prev, cmd_require) && !sieve_command_is(prev, cmd_import) && !sieve_command_is(prev, cmd_export) ) ) { sieve_command_validate_error(valdtr, cmd, "the DEPRECATED %s command can only be placed at top level " "at the beginning of the file after any require or " "import/export commands", sieve_command_identifier(cmd)); return FALSE; } } /* Check for use of variables extension */ if ( !ext_include_validator_have_variables(this_ext, valdtr) ) { sieve_command_validate_error(valdtr, cmd, "%s command requires that variables extension is active", sieve_command_identifier(cmd)); return FALSE; } /* Register global variable */ if ( sieve_ast_argument_type(arg) == SAAT_STRING ) { /* Single string */ const char *identifier = sieve_ast_argument_strc(arg); struct sieve_variable *var; if ( (var=ext_include_variable_import_global (valdtr, cmd, identifier)) == NULL ) return FALSE; arg->argument = _create_variable_argument(cmd, var); } else if ( sieve_ast_argument_type(arg) == SAAT_STRING_LIST ) { /* String list */ struct sieve_ast_argument *stritem = sieve_ast_strlist_first(arg); while ( stritem != NULL ) { const char *identifier = sieve_ast_argument_strc(stritem); struct sieve_variable *var; if ( (var=ext_include_variable_import_global (valdtr, cmd, identifier)) == NULL ) return FALSE; stritem->argument = _create_variable_argument(cmd, var); stritem = sieve_ast_strlist_next(stritem); } } else { /* Something else */ sieve_argument_validate_error(valdtr, arg, "the %s command accepts a single string or string list argument, " "but %s was found", sieve_command_identifier(cmd), sieve_ast_argument_name(arg)); return FALSE; } /* Join global commands with predecessors if possible */ if ( sieve_commands_equal(prev, cmd) ) { /* Join this command's string list with the previous one */ prev->first_positional = sieve_ast_stringlist_join (prev->first_positional, cmd->first_positional); if ( prev->first_positional == NULL ) { /* Not going to happen unless MAXINT stringlist items are specified */ sieve_command_validate_error(valdtr, cmd, "compiler reached AST limit (script too complex)"); return FALSE; } /* Detach this command node */ sieve_ast_node_detach(cmd->ast_node); } return TRUE; }