diff --git a/src/lib-sieve/plugins/enotify/Makefile.am b/src/lib-sieve/plugins/enotify/Makefile.am index e733dd2e2e01a8fcb66017c10c1e97c7b9421433..084b975e76fdf1f5e97024ef048c90e4d64fc89c 100644 --- a/src/lib-sieve/plugins/enotify/Makefile.am +++ b/src/lib-sieve/plugins/enotify/Makefile.am @@ -10,9 +10,13 @@ AM_CPPFLAGS = \ commands = \ cmd-notify.c +tests = \ + tst-valid-notify-method.c + libsieve_ext_enotify_la_SOURCES = \ ext-enotify.c \ - $(commands) + $(commands) \ + $(tests) noinst_HEADERS = \ ext-enotify-common.h diff --git a/src/lib-sieve/plugins/enotify/ext-enotify-common.h b/src/lib-sieve/plugins/enotify/ext-enotify-common.h index d097b4faf0886e94c085bd6e90504e5f11668252..a235dabf850ccacd42ad3a9722f71c57040566ac 100644 --- a/src/lib-sieve/plugins/enotify/ext-enotify-common.h +++ b/src/lib-sieve/plugins/enotify/ext-enotify-common.h @@ -16,14 +16,22 @@ extern const struct sieve_extension enotify_extension; extern const struct sieve_command notify_command; +/* + * Tests + */ + +extern const struct sieve_command valid_notify_method_test; + /* * Operands */ extern const struct sieve_operation notify_operation; +extern const struct sieve_operation valid_notify_method_operation; enum ext_variables_opcode { - EXT_ENOTIFY_OPERATION_NOTIFY + EXT_ENOTIFY_OPERATION_NOTIFY, + EXT_ENOTIFY_OPERATION_VALID_NOTIFY_METHOD }; #endif /* __EXT_ENOTIFY_COMMON_H */ diff --git a/src/lib-sieve/plugins/enotify/ext-enotify.c b/src/lib-sieve/plugins/enotify/ext-enotify.c index cdcabeb3c9011d6617bbea5ff8338510b67e65da..8bf53c2526f5fb61b4112d54222d2d220e603009 100644 --- a/src/lib-sieve/plugins/enotify/ext-enotify.c +++ b/src/lib-sieve/plugins/enotify/ext-enotify.c @@ -31,7 +31,8 @@ */ const struct sieve_operation *ext_enotify_operations[] = { - ¬ify_operation + ¬ify_operation, + &valid_notify_method_operation }; /* @@ -49,7 +50,7 @@ const struct sieve_extension enotify_extension = { ext_enotify_load, ext_enotify_validator_load, NULL, NULL, NULL, NULL, NULL, - SIEVE_EXT_DEFINE_OPERATION(notify_operation), + SIEVE_EXT_DEFINE_OPERATIONS(ext_enotify_operations), SIEVE_EXT_DEFINE_NO_OPERANDS }; @@ -64,6 +65,7 @@ static bool ext_enotify_validator_load(struct sieve_validator *validator) { /* Register new commands */ sieve_validator_register_command(validator, ¬ify_command); + sieve_validator_register_command(validator, &valid_notify_method_test); return TRUE; } diff --git a/src/lib-sieve/plugins/enotify/tst-valid-notify-method.c b/src/lib-sieve/plugins/enotify/tst-valid-notify-method.c new file mode 100644 index 0000000000000000000000000000000000000000..2152ca03769a780c8a756e65395b56760c2f8472 --- /dev/null +++ b/src/lib-sieve/plugins/enotify/tst-valid-notify-method.c @@ -0,0 +1,133 @@ +/* Copyright (c) 2002-2008 Dovecot Sieve authors, see the included COPYING file + */ + +#include <stdio.h> + +#include "sieve-common.h" +#include "sieve-commands.h" +#include "sieve-code.h" +#include "sieve-comparators.h" +#include "sieve-match-types.h" +#include "sieve-validator.h" +#include "sieve-generator.h" +#include "sieve-interpreter.h" +#include "sieve-dump.h" +#include "sieve-match.h" + +#include "ext-enotify-common.h" + +/* + * Valid_notify_method test + * + * Syntax: + * valid_notify_method <notification-uris: string-list> + */ + +static bool tst_vnotifym_validate + (struct sieve_validator *validator, struct sieve_command_context *tst); +static bool tst_vnotifym_generate + (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); + +const struct sieve_command valid_notify_method_test = { + "valid_notify_method", + SCT_TEST, + 1, 0, FALSE, FALSE, + NULL, NULL, + tst_vnotifym_validate, + tst_vnotifym_generate, + NULL +}; + +/* + * Valid_notify_method operation + */ + +static bool tst_vnotifym_operation_dump + (const struct sieve_operation *op, + const struct sieve_dumptime_env *denv, sieve_size_t *address); +static int tst_vnotifym_operation_execute + (const struct sieve_operation *op, + const struct sieve_runtime_env *renv, sieve_size_t *address); + +const struct sieve_operation valid_notify_method_operation = { + "VALID_NOTIFY_METHOD", + &enotify_extension, + EXT_ENOTIFY_OPERATION_VALID_NOTIFY_METHOD, + tst_vnotifym_operation_dump, + tst_vnotifym_operation_execute +}; + +/* + * Test validation + */ + +static bool tst_vnotifym_validate + (struct sieve_validator *validator, struct sieve_command_context *tst) +{ + struct sieve_ast_argument *arg = tst->first_positional; + + if ( !sieve_validate_positional_argument + (validator, tst, arg, "notification-uris", 1, SAAT_STRING_LIST) ) { + return FALSE; + } + + return sieve_validator_argument_activate(validator, tst, arg, FALSE); +} + +/* + * Test generation + */ + +static bool tst_vnotifym_generate + (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) +{ + sieve_operation_emit_code(cgenv->sbin, &valid_notify_method_operation); + + /* Generate arguments */ + return sieve_generate_arguments(cgenv, ctx, NULL); +} + +/* + * Code dump + */ + +static bool tst_vnotifym_operation_dump +(const struct sieve_operation *op ATTR_UNUSED, + const struct sieve_dumptime_env *denv, sieve_size_t *address) +{ + sieve_code_dumpf(denv, "VALID_NOTIFY_METHOD"); + sieve_code_descend(denv); + + return + sieve_opr_stringlist_dump(denv, address, "notify-uris"); +} + +/* + * Code execution + */ + +static int tst_vnotifym_operation_execute +(const struct sieve_operation *op ATTR_UNUSED, + const struct sieve_runtime_env *renv, sieve_size_t *address) +{ + struct sieve_coded_stringlist *notify_uris; + + /* + * Read operands + */ + + /* Read notify uris */ + if ( (notify_uris=sieve_opr_stringlist_read(renv, address)) == NULL ) { + sieve_runtime_trace_error(renv, "invalid notify-uris operand"); + return SIEVE_EXEC_BIN_CORRUPT; + } + + /* + * Perform operation + */ + + sieve_runtime_trace(renv, "VALID_NOTIFY_METHOD test"); + + sieve_interpreter_set_test_result(renv->interp, FALSE); + return SIEVE_EXEC_OK; +} diff --git a/tests/extensions/enotify/basic.svtest b/tests/extensions/enotify/basic.svtest index 65397e24492257369c9cfafe9720832b829180dc..2b67398b38913df029757a1b7a3a213906441ebd 100644 --- a/tests/extensions/enotify/basic.svtest +++ b/tests/extensions/enotify/basic.svtest @@ -1,7 +1,13 @@ require "vnd.dovecot.testsuite"; require "enotify"; -test "Valid notification" { +test "Execute" { + /* Test to catch runtime segfaults */ + if valid_notify_method + "mailto:alm@example.com" { + stop; + } + /* Test to catch runtime segfaults */ notify :message "This is probably very important"