From e968cf85c0e9326deeb466826ce3dbeaddc97637 Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan@rename-it.nl>
Date: Sat, 28 Jun 2008 14:42:22 +0200
Subject: [PATCH] Imapflags: finished for implicit flag attachment to fileinto
 and keep commands.

---
 src/lib-sieve/ext-fileinto.c                | 17 +++++++++++----
 src/lib-sieve/plugins/imapflags/tag-flags.c | 10 ++++-----
 src/lib-sieve/sieve-actions.c               |  8 +++++--
 src/lib-sieve/sieve-binary.c                |  8 +++++++
 src/lib-sieve/sieve-binary.h                |  2 ++
 src/lib-sieve/sieve-code-dumper.c           | 11 ++++++----
 src/lib-sieve/sieve-commands.c              |  4 +++-
 src/lib-sieve/sieve-commands.h              |  3 ++-
 src/lib-sieve/sieve-extensions-private.h    | 23 ++++++++++++++++++---
 9 files changed, 65 insertions(+), 21 deletions(-)

diff --git a/src/lib-sieve/ext-fileinto.c b/src/lib-sieve/ext-fileinto.c
index 24ecd50ad..ae0903b2f 100644
--- a/src/lib-sieve/ext-fileinto.c
+++ b/src/lib-sieve/ext-fileinto.c
@@ -11,13 +11,14 @@
 #include <stdio.h>
 
 #include "sieve-extensions.h"
+#include "sieve-binary.h"
 #include "sieve-commands.h"
 #include "sieve-code.h"
 #include "sieve-actions.h"
 #include "sieve-validator.h"
 #include "sieve-generator.h"
 #include "sieve-interpreter.h"
-#include "sieve-code-dumper.h"
+#include "sieve-dump.h"
 #include "sieve-result.h"
 
 /* Forward declarations */
@@ -133,11 +134,18 @@ static bool ext_fileinto_operation_dump
 	sieve_code_dumpf(denv, "FILEINTO");
 	sieve_code_descend(denv);
 
-	if ( !sieve_code_dumper_print_optional_operands(denv, address) )
+	if ( !sieve_code_dumper_print_optional_operands(denv, address) ) {
+		sieve_binary_corrupt(denv->sbin, 
+			"FILEINTO: failed to dump optional operands");
 		return FALSE;
+	}
 
-	return 
-		sieve_opr_string_dump(denv, address);
+	if ( !sieve_opr_string_dump(denv, address) ) {
+		sieve_binary_corrupt(denv->sbin, "FILEINTO: failed to dump string operand");
+		return FALSE;
+	}
+	
+	return TRUE;
 }
 
 /*
@@ -159,6 +167,7 @@ static bool ext_fileinto_operation_execute
 	
 	if ( !sieve_opr_string_read(renv, address, &folder) ) {
 		t_pop();
+		sieve_binary_corrupt(renv->sbin, "FILEINTO: failed to read string operand");
 		return FALSE;
 	}
 
diff --git a/src/lib-sieve/plugins/imapflags/tag-flags.c b/src/lib-sieve/plugins/imapflags/tag-flags.c
index 7efe0e38e..03adffc8a 100644
--- a/src/lib-sieve/plugins/imapflags/tag-flags.c
+++ b/src/lib-sieve/plugins/imapflags/tag-flags.c
@@ -42,7 +42,7 @@ const struct sieve_argument tag_flags_implicit = {
 
 /* Side effect */
 
-const struct sieve_side_effect_extension ext_flags_side_effect;
+extern const struct sieve_side_effect_extension imapflags_seffect_extension;
 
 static bool seff_flags_dump_context
 	(const struct sieve_side_effect *seffect,
@@ -72,7 +72,7 @@ const struct sieve_side_effect flags_side_effect = {
 	"flags",
 	&act_store,
 	
-	&ext_flags_side_effect,
+	&imapflags_seffect_extension,
 	EXT_IMAPFLAGS_SEFFECT_FLAGS,
 	seff_flags_dump_context,
 	seff_flags_read_context,
@@ -86,7 +86,7 @@ const struct sieve_side_effect flags_implicit_side_effect = {
 	"flags-implicit",
 	&act_store,
 	
-	&ext_flags_side_effect,
+	&imapflags_seffect_extension,
 	EXT_IMAPFLAGS_SEFFECT_FLAGS_IMPLICIT,
 	NULL,
 	seff_flags_read_implicit_context,
@@ -112,8 +112,7 @@ static bool tag_flags_validate_persistent
 (struct sieve_validator *validator ATTR_UNUSED, struct sieve_command_context *cmd)
 {	
 	if ( sieve_command_find_argument(cmd, &tag_flags) == NULL ) {
-		printf("ADD DYNAMIC\n");
-		sieve_command_add_dynamic_tag(cmd, &tag_flags_implicit);
+		sieve_command_add_dynamic_tag(cmd, &tag_flags_implicit, -1);
 	}
 	
 	return TRUE;
@@ -167,7 +166,6 @@ static bool tag_flags_generate
 			!param->argument->generate(generator, param, cmd) ) 
 			return FALSE;
 	} else if ( arg->argument == &tag_flags_implicit ) {
-		printf("GENERATE IMPLICIT\n");
 		sieve_opr_side_effect_emit
 			(sbin, &flags_implicit_side_effect, ext_imapflags_my_id);
 	} else
diff --git a/src/lib-sieve/sieve-actions.c b/src/lib-sieve/sieve-actions.c
index 3b0c9d098..e36f7ea84 100644
--- a/src/lib-sieve/sieve-actions.c
+++ b/src/lib-sieve/sieve-actions.c
@@ -154,15 +154,19 @@ bool sieve_opr_side_effect_dump
 	sieve_code_mark(denv);
 	seffect = sieve_side_effect_read(denv->sbin, address);
 
-	if ( seffect == NULL ) 
+	if ( seffect == NULL ) {
+		sieve_binary_corrupt(denv->sbin, "failed to read side effect");
 		return FALSE;
+	}
 
 	sieve_code_dumpf(denv, "SIDE-EFFECT: %s", seffect->name);
 
 	if ( seffect->dump_context != NULL ) {
 		sieve_code_descend(denv);
-		if ( !seffect->dump_context(seffect, denv, address) )
+		if ( !seffect->dump_context(seffect, denv, address) ) {
+			sieve_binary_corrupt(denv->sbin, "failed to read side effect context");
 			return FALSE;	
+		}
 		sieve_code_ascend(denv);
 	}
 
diff --git a/src/lib-sieve/sieve-binary.c b/src/lib-sieve/sieve-binary.c
index 2ee3b8846..a580629ba 100644
--- a/src/lib-sieve/sieve-binary.c
+++ b/src/lib-sieve/sieve-binary.c
@@ -265,6 +265,14 @@ bool sieve_binary_script_older
 	return ( sieve_script_older(script, sbin->file->st.st_mtime) );
 }
 
+void sieve_binary_corrupt(struct sieve_binary *sbin, const char *fmt, ...)
+{
+	va_list args;
+	
+	va_start(args, fmt);
+	printf("BINARY CORRUPT: %s.\n", t_strdup_vprintf(fmt, args));
+	va_end(args);
+}
 
 /* 
  * Block management 
diff --git a/src/lib-sieve/sieve-binary.h b/src/lib-sieve/sieve-binary.h
index 368dc70db..6b8067ca7 100644
--- a/src/lib-sieve/sieve-binary.h
+++ b/src/lib-sieve/sieve-binary.h
@@ -18,6 +18,8 @@ const char *sieve_binary_path(struct sieve_binary *sbin);
 bool sieve_binary_script_older
 	(struct sieve_binary *sbin, struct sieve_script *script);
 
+void sieve_binary_corrupt(struct sieve_binary *sbin, const char *fmt, ...);
+
 void sieve_binary_activate(struct sieve_binary *sbin);
 
 bool sieve_binary_save
diff --git a/src/lib-sieve/sieve-code-dumper.c b/src/lib-sieve/sieve-code-dumper.c
index 173faa415..207a0aca1 100644
--- a/src/lib-sieve/sieve-code-dumper.c
+++ b/src/lib-sieve/sieve-code-dumper.c
@@ -111,19 +111,22 @@ void sieve_code_ascend(const struct sieve_dumptime_env *denv)
 bool sieve_code_dumper_print_optional_operands
 	(const struct sieve_dumptime_env *denv, sieve_size_t *address)
 {
-	int opt_code;
+	int opt_code = -1;
 	
 	if ( sieve_operand_optional_present(denv->sbin, address) ) {
-		while ( opt_code != 0 ) {
-			if ( !sieve_operand_optional_read(denv->sbin, address, &opt_code) )
+		
+		while ( opt_code != 0 ) {			
+			if ( !sieve_operand_optional_read(denv->sbin, address, &opt_code) ) {
+				sieve_binary_corrupt(denv->sbin, "failed to read optional operand");
 				return FALSE;
+			}
 
 			if ( opt_code == SIEVE_OPT_SIDE_EFFECT ) {
 				if ( !sieve_opr_side_effect_dump(denv, address) )
 					return FALSE;
 			}
 		}
-	}
+	} 
 	return TRUE;
 }
  
diff --git a/src/lib-sieve/sieve-commands.c b/src/lib-sieve/sieve-commands.c
index d2425729b..b52252c2d 100644
--- a/src/lib-sieve/sieve-commands.c
+++ b/src/lib-sieve/sieve-commands.c
@@ -251,7 +251,8 @@ const char *sieve_command_type_name(const struct sieve_command *command) {
 }
 
 struct sieve_ast_argument *sieve_command_add_dynamic_tag
-(struct sieve_command_context *cmd, const struct sieve_argument *tag)
+(struct sieve_command_context *cmd, const struct sieve_argument *tag, 
+	int id_code)
 {
 	struct sieve_ast_argument *arg;
 	
@@ -263,6 +264,7 @@ struct sieve_ast_argument *sieve_command_add_dynamic_tag
 			(cmd->ast_node, tag->identifier, cmd->ast_node->source_line);
 	
 	arg->argument = tag;
+	arg->arg_id_code = id_code;
 	
 	return arg;
 }
diff --git a/src/lib-sieve/sieve-commands.h b/src/lib-sieve/sieve-commands.h
index f87540b04..307d0af15 100644
--- a/src/lib-sieve/sieve-commands.h
+++ b/src/lib-sieve/sieve-commands.h
@@ -116,7 +116,8 @@ struct sieve_command_context *sieve_command_parent_context
 	(struct sieve_command_context *context);
 	
 struct sieve_ast_argument *sieve_command_add_dynamic_tag
-	(struct sieve_command_context *cmd, const struct sieve_argument *tag);
+	(struct sieve_command_context *cmd, const struct sieve_argument *tag,
+		int id_code);
 struct sieve_ast_argument *sieve_command_find_argument
 	(struct sieve_command_context *cmd, const struct sieve_argument *argument);	
 	
diff --git a/src/lib-sieve/sieve-extensions-private.h b/src/lib-sieve/sieve-extensions-private.h
index 249492c1e..3a6914658 100644
--- a/src/lib-sieve/sieve-extensions-private.h
+++ b/src/lib-sieve/sieve-extensions-private.h
@@ -19,6 +19,7 @@ static inline const void *_sieve_extension_get_object
 		const void * const *objects = (const void * const *) reg->objects;
 		return objects[code]; 
 	}
+	
 	return NULL;
 }
 #define sieve_extension_get_object(type, reg, code) \
@@ -59,19 +60,35 @@ static inline const void *_sieve_extension_read_obj
 
 	if ( sieve_binary_read_byte(sbin, address, &obj_code) ) { 
 		if ( obj_code < defreg->count ) { 
-			return _sieve_extension_get_object(defreg, obj_code); 
+			const void *object = _sieve_extension_get_object(defreg, obj_code); 
+			
+			if ( object == 0 ) 
+				sieve_binary_corrupt(sbin, "failed to read object with code %d "
+					"from default object registry", obj_code);
+			
+			return object;
 		} else {
+			const void *object;
 			unsigned int code = 0; 	 
 			const struct sieve_extension_obj_registry *reg;
 		
 			if ( (reg=get_reg_func(sbin, obj_code - defreg->count)) == NULL || 
-				reg->count == 0 ) 
+				reg->count == 0 ) {
+				sieve_binary_corrupt(sbin, 
+					"failed to read object registry with code %d", obj_code);
 				return NULL; 
+			}
 		
 			if ( reg->count > 1) 
 				sieve_binary_read_byte(sbin, address, &code); 
 	
-			return _sieve_extension_get_object(reg, code);
+			object = _sieve_extension_get_object(reg, code);
+			
+			if ( object == 0 ) 
+				sieve_binary_corrupt(sbin, "failed to read object with code %d "
+					"from object registry %d", code, obj_code);
+			
+			return object;
 		}
 	}
 	
-- 
GitLab