dovecot-2.2-pigeonhole: lib-sieve: interpreter; Added support fo...

pigeonhole at rename-it.nl pigeonhole at rename-it.nl
Sun Nov 29 15:17:55 UTC 2015


details:   http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/d9bc8186e02e
changeset: 2149:d9bc8186e02e
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Sun Nov 29 16:17:15 2015 +0100
description:
lib-sieve: interpreter; Added support for program jumps that explicitly cross loop boundaries.
Needed for test suite.

diffstat:

 src/lib-sieve/sieve-code.c        |   6 ++--
 src/lib-sieve/sieve-interpreter.c |  45 ++++++++++++++++++++++++++++++--------
 src/lib-sieve/sieve-interpreter.h |   2 +-
 3 files changed, 39 insertions(+), 14 deletions(-)

diffs (126 lines):

diff -r d9d6a8e4d0b9 -r d9bc8186e02e src/lib-sieve/sieve-code.c
--- a/src/lib-sieve/sieve-code.c	Sun Nov 29 15:33:25 2015 +0100
+++ b/src/lib-sieve/sieve-code.c	Sun Nov 29 16:17:15 2015 +0100
@@ -1145,7 +1145,7 @@
 static int opc_jmp_execute
 (const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED)
 {
-	return sieve_interpreter_program_jump(renv->interp, TRUE);
+	return sieve_interpreter_program_jump(renv->interp, TRUE, FALSE);
 }
 
 static int opc_jmptrue_execute
@@ -1156,7 +1156,7 @@
 	sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "jump if result is true");
 	sieve_runtime_trace_descend(renv);
 
-	return sieve_interpreter_program_jump(renv->interp, result);
+	return sieve_interpreter_program_jump(renv->interp, result, FALSE);
 }
 
 static int opc_jmpfalse_execute
@@ -1167,5 +1167,5 @@
 	sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "jump if result is false");
 	sieve_runtime_trace_descend(renv);
 
-	return sieve_interpreter_program_jump(renv->interp, !result);
+	return sieve_interpreter_program_jump(renv->interp, !result, FALSE);
 }
diff -r d9d6a8e4d0b9 -r d9bc8186e02e src/lib-sieve/sieve-interpreter.c
--- a/src/lib-sieve/sieve-interpreter.c	Sun Nov 29 15:33:25 2015 +0100
+++ b/src/lib-sieve/sieve-interpreter.c	Sun Nov 29 16:17:15 2015 +0100
@@ -665,6 +665,28 @@
 	return SIEVE_EXEC_OK;
 }
 
+static int
+sieve_interpreter_loop_break_out(struct sieve_interpreter *interp,
+	sieve_size_t target)
+{
+	struct sieve_interpreter_loop *loops;
+	unsigned int count, i;
+
+	if ( !array_is_created(&interp->loop_stack) )
+		return SIEVE_EXEC_OK;
+
+	loops = array_get_modifiable(&interp->loop_stack, &count);
+	for ( i = count; i > 0; i-- ) {
+		/* We're really making sure our loop matches */
+		if ( loops[i-1].end > target )
+			break;
+	}
+	if ( i == count )
+		return SIEVE_EXEC_OK;
+
+	return sieve_interpreter_loop_break(interp, &loops[i]);
+}
+
 struct sieve_interpreter_loop *sieve_interpreter_loop_get_surrounding
 (struct sieve_interpreter *interp,
 	struct sieve_interpreter_loop *loop,
@@ -727,14 +749,14 @@
 }
 
 int sieve_interpreter_program_jump
-(struct sieve_interpreter *interp, bool jump)
+(struct sieve_interpreter *interp, bool jump, bool break_loops)
 {
 	const struct sieve_runtime_env *renv = &interp->runenv;
 	sieve_size_t *address = &(interp->runenv.pc);
-	sieve_size_t jmp_start = *address;
-	sieve_size_t jmp_limit = ( interp->loop_limit == 0 ?
-		sieve_binary_block_get_size(renv->sblock) : interp->loop_limit );
+	sieve_size_t jmp_start = *address, jmp_target;
+	sieve_size_t loop_limit = ( break_loops ? 0 : interp->loop_limit );
 	sieve_offset_t jmp_offset;
+	int ret;
 
 	if ( !sieve_binary_read_offset(renv->sblock, address, &jmp_offset) )
 	{
@@ -742,25 +764,28 @@
 		return SIEVE_EXEC_BIN_CORRUPT;
 	}
 
-	if ( (jmp_start + jmp_offset) <= jmp_limit &&
+	jmp_target = jmp_start + jmp_offset;
+	if ( jmp_target <= sieve_binary_block_get_size(renv->sblock) &&
+		(loop_limit == 0 || jmp_target < loop_limit) &&
 		jmp_start + jmp_offset > 0 )
 	{
 		if ( jump ) {
-			sieve_size_t jmp_addr = jmp_start + jmp_offset;
-
 			if ( sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS) ) {
 				unsigned int jmp_line =
-					sieve_runtime_get_source_location(renv, jmp_addr);
+					sieve_runtime_get_source_location(renv, jmp_target);
 
 				if ( sieve_runtime_trace_hasflag(renv, SIEVE_TRFLG_ADDRESSES) ) {
 					sieve_runtime_trace(renv, 0, "jumping to line %d [%08llx]",
-						jmp_line, (long long unsigned int) jmp_addr);
+						jmp_line, (long long unsigned int) jmp_target);
 				} else {
 					sieve_runtime_trace(renv, 0, "jumping to line %d", jmp_line);
 				}
 			}
 
-			*address = jmp_addr;
+			if ( break_loops && 
+				(ret=sieve_interpreter_loop_break_out(interp, jmp_target)) <= 0 )
+				return ret;
+			*address = jmp_target;
 		} else {
 			sieve_runtime_trace(renv, 0, "not jumping");
 		}
diff -r d9d6a8e4d0b9 -r d9bc8186e02e src/lib-sieve/sieve-interpreter.h
--- a/src/lib-sieve/sieve-interpreter.h	Sun Nov 29 15:33:25 2015 +0100
+++ b/src/lib-sieve/sieve-interpreter.h	Sun Nov 29 16:17:15 2015 +0100
@@ -98,7 +98,7 @@
 	(struct sieve_interpreter *interp);
 
 int sieve_interpreter_program_jump
-	(struct sieve_interpreter *interp, bool jump);
+	(struct sieve_interpreter *interp, bool jump, bool break_loops);
 
 /*
  * Test results


More information about the dovecot-cvs mailing list