コード例 #1
0
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);
}
コード例 #2
0
ファイル: ext-fileinto.c プロジェクト: aclindsa/pigeonhole
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;
}
コード例 #3
0
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;
}
コード例 #4
0
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;
}
コード例 #5
0
ファイル: cmd-global.c プロジェクト: aclindsa/pigeonhole
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;
}