dovecot-2.2-pigeonhole: lib-sieve: Created message override infr...

pigeonhole at rename-it.nl pigeonhole at rename-it.nl
Wed Nov 12 21:11:21 UTC 2014


details:   http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/578aca9c0ba1
changeset: 1961:578aca9c0ba1
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Wed Nov 12 22:10:24 2014 +0100
description:
lib-sieve: Created message override infrastructure.
This allows extension of test commands that evaluate the message somehow.
Currently this is implemented only for the message header.
Extensions can thereby influence what headers are evaluated and how.

diffstat:

 src/lib-sieve/ext-envelope.c          |    5 +-
 src/lib-sieve/plugins/date/tst-date.c |   19 ++-
 src/lib-sieve/sieve-address-parts.c   |   26 +++-
 src/lib-sieve/sieve-address-parts.h   |    7 +-
 src/lib-sieve/sieve-common.h          |    2 +
 src/lib-sieve/sieve-match.c           |   12 ++
 src/lib-sieve/sieve-message.c         |  195 ++++++++++++++++++++++++++++++++++
 src/lib-sieve/sieve-message.h         |   94 ++++++++++++++++
 src/lib-sieve/tst-address.c           |   26 +++-
 src/lib-sieve/tst-exists.c            |   33 ++++-
 src/lib-sieve/tst-header.c            |   18 ++-
 tests/compile/errors.svtest           |    2 +-
 12 files changed, 398 insertions(+), 41 deletions(-)

diffs (truncated from 698 to 300 lines):

diff -r 519972b17360 -r 578aca9c0ba1 src/lib-sieve/ext-envelope.c
--- a/src/lib-sieve/ext-envelope.c	Wed Nov 12 22:10:23 2014 +0100
+++ b/src/lib-sieve/ext-envelope.c	Wed Nov 12 22:10:24 2014 +0100
@@ -436,10 +436,9 @@
 	struct sieve_command_registration *cmd_reg)
 {
 	/* The order of these is not significant */
-	sieve_comparators_link_tag(valdtr, cmd_reg, SIEVE_AM_OPT_COMPARATOR);
+	sieve_comparators_link_tag(valdtr, cmd_reg, SIEVE_MATCH_OPT_COMPARATOR);
+	sieve_match_types_link_tags(valdtr, cmd_reg, SIEVE_MATCH_OPT_MATCH_TYPE);
 	sieve_address_parts_link_tags(valdtr, cmd_reg, SIEVE_AM_OPT_ADDRESS_PART);
-	sieve_match_types_link_tags(valdtr, cmd_reg, SIEVE_AM_OPT_MATCH_TYPE);
-
 	return TRUE;
 }
 
diff -r 519972b17360 -r 578aca9c0ba1 src/lib-sieve/plugins/date/tst-date.c
--- a/src/lib-sieve/plugins/date/tst-date.c	Wed Nov 12 22:10:23 2014 +0100
+++ b/src/lib-sieve/plugins/date/tst-date.c	Wed Nov 12 22:10:24 2014 +0100
@@ -139,7 +139,7 @@
  */
 
 enum tst_date_optional {
-	OPT_DATE_ZONE = SIEVE_MATCH_OPT_LAST,
+	OPT_DATE_ZONE = SIEVE_AM_OPT_LAST,
 	OPT_DATE_LAST
 };
 
@@ -349,7 +349,7 @@
 	for (;;) {
 		int opt;
 
-		if ( (opt=sieve_match_opr_optional_dump(denv, address, &opt_code)) < 0 )
+		if ( (opt=sieve_message_opr_optional_dump(denv, address, &opt_code)) < 0 )
 			return FALSE;
 
 		if ( opt == 0 ) break;
@@ -387,6 +387,7 @@
 		SIEVE_MATCH_TYPE_DEFAULT(is_match_type);
 	struct sieve_comparator cmp =
 		SIEVE_COMPARATOR_DEFAULT(i_ascii_casemap_comparator);
+	ARRAY_TYPE(sieve_message_override) svmos;
 	string_t *date_part = NULL, *zone = NULL;
 	struct sieve_stringlist *hdr_list = NULL, *hdr_value_list;
 	struct sieve_stringlist *value_list, *key_list;
@@ -399,8 +400,10 @@
 	for (;;) {
 		int opt;
 
-		if ( (opt=sieve_match_opr_optional_read
-			(renv, address, &opt_code, &ret, &cmp, &mcht)) < 0 )
+		/* Optional operands */
+		memset(&svmos, 0, sizeof(svmos));
+		if ( (opt=sieve_message_opr_optional_read
+			(renv, address, &opt_code, &ret, NULL, &mcht, &cmp, &svmos)) < 0 )
 			return ret;
 
 		if ( opt == 0 ) break;
@@ -465,8 +468,14 @@
 
 		sieve_runtime_trace(renv, SIEVE_TRLVL_TESTS, "date test");
 
+		/* Get header */
+		sieve_runtime_trace_descend(renv);
+		if ( (ret=sieve_message_get_header_fields
+			(renv, hdr_list, &svmos, &hdr_value_list)) <= 0 )
+			return ret;
+		sieve_runtime_trace_ascend(renv);
+
 		/* 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, dpart);
 
diff -r 519972b17360 -r 578aca9c0ba1 src/lib-sieve/sieve-address-parts.c
--- a/src/lib-sieve/sieve-address-parts.c	Wed Nov 12 22:10:23 2014 +0100
+++ b/src/lib-sieve/sieve-address-parts.c	Wed Nov 12 22:10:24 2014 +0100
@@ -362,10 +362,10 @@
 			return opt;
 
 		switch ( *opt_code ) {
-		case SIEVE_AM_OPT_COMPARATOR:
+		case SIEVE_MATCH_OPT_COMPARATOR:
 			opok = sieve_opr_comparator_dump(denv, address);
 			break;
-		case SIEVE_AM_OPT_MATCH_TYPE:
+		case SIEVE_MATCH_OPT_MATCH_TYPE:
 			opok = sieve_opr_match_type_dump(denv, address);
 			break;
 		case SIEVE_AM_OPT_ADDRESS_PART:
@@ -406,13 +406,31 @@
 		}
 
 		switch ( *opt_code ) {
-		case SIEVE_AM_OPT_COMPARATOR:
+		case SIEVE_MATCH_OPT_COMPARATOR:
+			if (cmp == NULL) {
+				sieve_runtime_trace_error(renv, "unexpected comparator operand");
+				if ( exec_status != NULL )
+					*exec_status = SIEVE_EXEC_BIN_CORRUPT;
+				return -1;
+			}
 			status = sieve_opr_comparator_read(renv, address, cmp);
 			break;
-		case SIEVE_AM_OPT_MATCH_TYPE:
+		case SIEVE_MATCH_OPT_MATCH_TYPE:
+			if (mtch == NULL) {
+				sieve_runtime_trace_error(renv, "unexpected match-type operand");
+				if ( exec_status != NULL )
+					*exec_status = SIEVE_EXEC_BIN_CORRUPT;
+				return -1;
+			}
 			status = sieve_opr_match_type_read(renv, address, mtch);
 			break;
 		case SIEVE_AM_OPT_ADDRESS_PART:
+			if (addrp == NULL) {
+				sieve_runtime_trace_error(renv, "unexpected address-part operand");
+				if ( exec_status != NULL )
+					*exec_status = SIEVE_EXEC_BIN_CORRUPT;
+				return -1;
+			}
 			status = sieve_opr_address_part_read(renv, address, addrp);
 			break;
 		default:
diff -r 519972b17360 -r 578aca9c0ba1 src/lib-sieve/sieve-address-parts.h
--- a/src/lib-sieve/sieve-address-parts.h	Wed Nov 12 22:10:23 2014 +0100
+++ b/src/lib-sieve/sieve-address-parts.h	Wed Nov 12 22:10:24 2014 +0100
@@ -7,6 +7,7 @@
 #include "message-address.h"
 
 #include "sieve-common.h"
+#include "sieve-match.h"
 #include "sieve-extensions.h"
 #include "sieve-objects.h"
 
@@ -121,10 +122,8 @@
  */
 
 enum sieve_addrmatch_opt_operand {
-	SIEVE_AM_OPT_END,
-	SIEVE_AM_OPT_COMPARATOR,
-	SIEVE_AM_OPT_ADDRESS_PART,
-	SIEVE_AM_OPT_MATCH_TYPE
+	SIEVE_AM_OPT_ADDRESS_PART = SIEVE_MATCH_OPT_LAST,
+	SIEVE_AM_OPT_LAST
 };
 
 int sieve_addrmatch_opr_optional_dump
diff -r 519972b17360 -r 578aca9c0ba1 src/lib-sieve/sieve-common.h
--- a/src/lib-sieve/sieve-common.h	Wed Nov 12 22:10:23 2014 +0100
+++ b/src/lib-sieve/sieve-common.h	Wed Nov 12 22:10:24 2014 +0100
@@ -147,6 +147,8 @@
 
 /* sieve-message.h */
 struct sieve_message_context;
+struct sieve_message_override;
+struct sieve_message_override_def;
 
 /* sieve-plugins.h */
 struct sieve_plugin;
diff -r 519972b17360 -r 578aca9c0ba1 src/lib-sieve/sieve-match.c
--- a/src/lib-sieve/sieve-match.c	Wed Nov 12 22:10:23 2014 +0100
+++ b/src/lib-sieve/sieve-match.c	Wed Nov 12 22:10:24 2014 +0100
@@ -258,9 +258,21 @@
 
 		switch ( *opt_code ) {
 		case SIEVE_MATCH_OPT_COMPARATOR:
+			if (cmp == NULL) {
+				sieve_runtime_trace_error(renv, "unexpected comparator operand");
+				if ( exec_status != NULL )
+					*exec_status = SIEVE_EXEC_BIN_CORRUPT;
+				return -1;
+			}
 			status = sieve_opr_comparator_read(renv, address, cmp);
 			break;
 		case SIEVE_MATCH_OPT_MATCH_TYPE:
+			if (mcht == NULL) {
+				sieve_runtime_trace_error(renv, "unexpected match-type operand");
+				if ( exec_status != NULL )
+					*exec_status = SIEVE_EXEC_BIN_CORRUPT;
+				return -1;
+			}
 			status = sieve_opr_match_type_read(renv, address, mcht);
 			break;
 		default:
diff -r 519972b17360 -r 578aca9c0ba1 src/lib-sieve/sieve-message.c
--- a/src/lib-sieve/sieve-message.c	Wed Nov 12 22:10:23 2014 +0100
+++ b/src/lib-sieve/sieve-message.c	Wed Nov 12 22:10:24 2014 +0100
@@ -20,8 +20,11 @@
 #include "sieve-stringlist.h"
 #include "sieve-error.h"
 #include "sieve-extensions.h"
+#include "sieve-code.h"
+#include "sieve-address-parts.h"
 #include "sieve-runtime.h"
 #include "sieve-runtime-trace.h"
+#include "sieve-match.h"
 #include "sieve-interpreter.h"
 #include "sieve-address.h"
 
@@ -569,3 +572,195 @@
 	strlist->headers_index = 0;
 	sieve_stringlist_reset(strlist->field_names);
 }
+
+/*
+ * Header override operand
+ */
+
+const struct sieve_operand_class sieve_message_override_operand_class =
+	{ "header-override" };
+
+bool sieve_opr_message_override_dump
+(const struct sieve_dumptime_env *denv, sieve_size_t *address)
+{
+	struct sieve_message_override svmo;
+	const struct sieve_message_override_def *hodef;
+
+	if ( !sieve_opr_object_dump
+		(denv, &sieve_message_override_operand_class, address, &svmo.object) )
+		return FALSE;
+
+	hodef = svmo.def =
+		(const struct sieve_message_override_def *) svmo.object.def;
+
+	if ( hodef->dump_context != NULL ) {
+		sieve_code_descend(denv);
+		if ( !hodef->dump_context(&svmo, denv, address) ) {
+			return FALSE;
+		}
+		sieve_code_ascend(denv);
+	}
+
+	return TRUE;
+}
+
+bool sieve_opr_message_override_read
+(const struct sieve_runtime_env *renv, sieve_size_t *address,
+	struct sieve_message_override *svmo)
+{
+	const struct sieve_message_override_def *hodef;
+
+	svmo->context = NULL;
+
+	if ( !sieve_opr_object_read
+		(renv, &sieve_message_override_operand_class, address, &svmo->object) )
+		return FALSE;
+
+	hodef = svmo->def =
+		(const struct sieve_message_override_def *) svmo->object.def;
+
+	if ( hodef->read_context != NULL &&
+		!hodef->read_context(svmo, renv, address, &svmo->context) ) {
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+/*
+ * Optional operands
+ */
+
+int sieve_message_opr_optional_dump
+(const struct sieve_dumptime_env *denv, sieve_size_t *address,
+	signed int *opt_code)
+{
+	signed int _opt_code = 0;
+	bool final = FALSE, opok = TRUE;
+
+	if ( opt_code == NULL ) {
+		opt_code = &_opt_code;
+		final = TRUE;
+	}
+
+	while ( opok ) {
+		int opt;
+
+		if ( (opt=sieve_addrmatch_opr_optional_dump
+			(denv, address, opt_code)) <= 0 )
+			return opt;
+
+		if ( *opt_code == SIEVE_OPT_MESSAGE_OVERRIDE ) {
+			opok = sieve_opr_message_override_dump(denv, address);
+		} else {
+			return ( final ? -1 : 1 );
+		}
+	}
+
+	return -1;
+}
+
+int sieve_message_opr_optional_read
+(const struct sieve_runtime_env *renv, sieve_size_t *address,
+	signed int *opt_code, int *exec_status,
+	struct sieve_address_part *addrp, struct sieve_match_type *mcht,
+	struct sieve_comparator *cmp, 
+	ARRAY_TYPE(sieve_message_override) *svmos)
+{
+	signed int _opt_code = 0;


More information about the dovecot-cvs mailing list