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