diff --git a/Makefile.am b/Makefile.am
index 3d1ff922ff6fdec80a9af8e109a45492d7550b0e..616eb3dc8b892809dd6852d8ccd20841227b9226 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -191,6 +191,13 @@ test_cases = \
 $(test_cases):
 	@$(TEST_BIN) $(top_srcdir)/$@
 
+failure_test_cases = \
+	tests/failures/fuzz1.svtest \
+	tests/failures/fuzz2.svtest
+
+$(failure_test_cases):
+	@$(TEST_BIN) -F $(top_srcdir)/$@
+
 TEST_EXTPROGRAMS_BIN = $(TEST_BIN) \
 	-P src/plugins/sieve-extprograms/.libs/sieve_extprograms
 
@@ -209,8 +216,8 @@ extprograms_test_cases = \
 $(extprograms_test_cases):
 	@$(TEST_EXTPROGRAMS_BIN) 	$(top_srcdir)/$@
 
-.PHONY: test test-plugins $(test_cases) $(extprograms_test_cases)
-test: all-am $(test_cases)
+.PHONY: test test-plugins $(test_cases) $(failure_test_cases) $(extprograms_test_cases)
+test: all-am $(test_cases) $(failure_test_cases)
 test-plugins: all-am $(extprograms_test_cases)
 
 check: check-am test
diff --git a/src/testsuite/cmd-test-config.c b/src/testsuite/cmd-test-config.c
index 75b7247b2acb68afdd3e4bb7637e6d215f1baa89..c1399b0635313d71392857115ffb1cb61a0d374f 100644
--- a/src/testsuite/cmd-test-config.c
+++ b/src/testsuite/cmd-test-config.c
@@ -494,10 +494,9 @@ cmd_test_config_reload_operation_execute(const struct sieve_runtime_env *renv,
 		ext = sieve_extension_get_by_name(eenv->svinst,
 						  str_c(extension));
 		if (ext == NULL) {
-			testsuite_test_failf("test_config_reload: "
-					     "unknown extension '%s'",
-					     str_c(extension));
-			return SIEVE_EXEC_OK;
+			return testsuite_test_failf(
+				renv, "test_config_reload: "
+				"unknown extension '%s'", str_c(extension));
 		}
 		sieve_extension_reload(ext);
 	}
diff --git a/src/testsuite/cmd-test-fail.c b/src/testsuite/cmd-test-fail.c
index 4427afcbd5101beae2f2aa1a7dab9ad4743f5441..9226a3ba097a471f2cdc8141f9a69a43328c3ad0 100644
--- a/src/testsuite/cmd-test-fail.c
+++ b/src/testsuite/cmd-test-fail.c
@@ -88,17 +88,12 @@ static bool
 cmd_test_fail_generate(const struct sieve_codegen_env *cgenv,
 		       struct sieve_command *cmd)
 {
-	struct testsuite_generator_context *genctx =
-		_get_generator_context(cgenv->gentr);
-
 	sieve_operation_emit(cgenv->sblock, cmd->ext, &test_fail_operation);
 
 	/* Generate arguments */
 	if (!sieve_generate_arguments(cgenv, cmd, NULL))
 		return FALSE;
 
-	sieve_jumplist_add(genctx->exit_jumps,
-			   sieve_binary_emit_offset(cgenv->sblock, 0));
 	return TRUE;
 }
 
@@ -110,22 +105,12 @@ static bool
 cmd_test_fail_operation_dump(const struct sieve_dumptime_env *denv,
 			     sieve_size_t *address)
 {
-	unsigned int pc;
-	sieve_offset_t offset;
-
 	sieve_code_dumpf(denv, "TEST_FAIL:");
 	sieve_code_descend(denv);
 
 	if (!sieve_opr_string_dump(denv, address, "reason"))
 		return FALSE;
 
-	sieve_code_mark(denv);
-	pc = *address;
-	if (!sieve_binary_read_offset(denv->sblock, address, &offset))
-		return FALSE;
-	sieve_code_dumpf(denv, "offset: %d [%08x]",
-			 offset, pc + offset);
-
 	return TRUE;
 }
 
@@ -147,7 +132,5 @@ cmd_test_fail_operation_execute(const struct sieve_runtime_env *renv,
 	sieve_runtime_trace(renv, SIEVE_TRLVL_COMMANDS, "testsuite: "
 			    "test_fail command; FAIL current test");
 
-	testsuite_test_fail(reason);
-
-	return sieve_interpreter_program_jump(renv->interp, TRUE, TRUE);
+	return testsuite_test_fail(renv, reason);
 }
diff --git a/src/testsuite/cmd-test-mailbox.c b/src/testsuite/cmd-test-mailbox.c
index 9dcf8c3ae79c04dda335cdd203a9e0a64da26979..3ace33ea983d289428599406d9d52585aea309e6 100644
--- a/src/testsuite/cmd-test-mailbox.c
+++ b/src/testsuite/cmd-test-mailbox.c
@@ -195,7 +195,8 @@ cmd_test_mailbox_operation_execute(const struct sieve_runtime_env *renv,
 		}
 
 		/* FIXME: implement */
-		testsuite_test_failf("test_mailbox_delete: NOT IMPLEMENTED");
+		return testsuite_test_failf(
+			renv, "test_mailbox_delete: NOT IMPLEMENTED");
 	}
 
 	return SIEVE_EXEC_OK;
diff --git a/src/testsuite/cmd-test-message.c b/src/testsuite/cmd-test-message.c
index f27ee074feb525834b0d2961a5cb744af82729df..dd3c4caff5486d42adf4d1c3096ce0add772f28f 100644
--- a/src/testsuite/cmd-test-message.c
+++ b/src/testsuite/cmd-test-message.c
@@ -434,8 +434,8 @@ cmd_test_message_smtp_operation_execute(const struct sieve_runtime_env *renv,
 	}
 
 	if (!result) {
-		testsuite_test_failf(
-			"no outgoing SMTP message with index %llu",
+		return testsuite_test_failf(
+			renv, "no outgoing SMTP message with index %llu",
 			(unsigned long long)msg_index);
 	}
 
@@ -506,8 +506,8 @@ cmd_test_message_mailbox_operation_execute(const struct sieve_runtime_env *renv,
 	}
 
 	if (!result) {
-		testsuite_test_failf(
-			"no message in folder '%s' with index %llu",
+		return testsuite_test_failf(
+			renv, "no message in folder '%s' with index %llu",
 			str_c(folder), (unsigned long long)msg_index);
 	}
 
diff --git a/src/testsuite/cmd-test.c b/src/testsuite/cmd-test.c
index 590ad2c27b8d2b3d65df0284dd198ffe1b4813b2..c817aedb0f83f588f2bd4d7006b7f73abab96601 100644
--- a/src/testsuite/cmd-test.c
+++ b/src/testsuite/cmd-test.c
@@ -121,6 +121,8 @@ cmd_test_generate(const struct sieve_codegen_env *cgenv,
 
 	/* Prepare jumplist */
 	sieve_jumplist_reset(genctx->exit_jumps);
+	sieve_jumplist_add(genctx->exit_jumps,
+		sieve_binary_emit_offset(cgenv->sblock, 0));
 
 	/* Test body */
 	if (!sieve_generate_block(cgenv, cmd->ast_node))
@@ -142,10 +144,24 @@ static bool
 cmd_test_operation_dump(const struct sieve_dumptime_env *denv,
 			sieve_size_t *address)
 {
+	sieve_size_t tst_begin;
+	sieve_offset_t tst_end_offset;
+
 	sieve_code_dumpf(denv, "TEST:");
 	sieve_code_descend(denv);
 
-	return sieve_opr_string_dump(denv, address, "test name");
+	if (!sieve_opr_string_dump(denv, address, "test name"))
+		return FALSE;
+
+	sieve_code_mark(denv);
+	tst_begin = *address;
+	if (!sieve_binary_read_offset(denv->sblock, address, &tst_end_offset))
+		return FALSE;
+	sieve_code_dumpf(denv, "end: %d [%08llx]",
+			 tst_end_offset,
+			 (unsigned long long)tst_begin + tst_end_offset);
+
+	return TRUE;
 }
 
 /*
@@ -156,6 +172,8 @@ static int
 cmd_test_operation_execute(const struct sieve_runtime_env *renv,
 			   sieve_size_t *address)
 {
+	sieve_size_t tst_begin, tst_end;
+	sieve_offset_t tst_end_offset;
 	string_t *test_name;
 	int ret;
 
@@ -163,23 +181,28 @@ cmd_test_operation_execute(const struct sieve_runtime_env *renv,
 	if (ret <= 0)
 		return ret;
 
+	tst_begin = *address;
+	if (!sieve_binary_read_offset(renv->sblock, address, &tst_end_offset)) {
+		sieve_runtime_trace_error(renv, "invalid end offset");
+		return SIEVE_EXEC_BIN_CORRUPT;
+	}
+	tst_end = tst_begin + tst_end_offset;
+
 	sieve_runtime_trace_sep(renv);
 	sieve_runtime_trace(renv, SIEVE_TRLVL_NONE,
-			    "** Testsuite test start: \"%s\"",
-			    str_c(test_name));
+			    "** Testsuite test start: \"%s\" (end: %08llx)",
+			    str_c(test_name),
+			    (unsigned long long)tst_end);
 
-	testsuite_test_start(test_name);
-	return SIEVE_EXEC_OK;
+	return testsuite_test_start(renv, test_name, tst_end);
 }
 
 static int
-cmd_test_finish_operation_execute(
-	const struct sieve_runtime_env *renv ATTR_UNUSED,
-	sieve_size_t *address ATTR_UNUSED)
+cmd_test_finish_operation_execute(const struct sieve_runtime_env *renv,
+				  sieve_size_t *address)
 {
 	sieve_runtime_trace(renv, SIEVE_TRLVL_NONE, "** Testsuite test end");
 	sieve_runtime_trace_sep(renv);
 
-	testsuite_test_succeed(NULL);
-	return SIEVE_EXEC_OK;
+	return testsuite_test_succeed(renv, address, NULL);
 }
diff --git a/src/testsuite/testsuite-common.c b/src/testsuite/testsuite-common.c
index 33434afca2b28a9e0fea6cf23811061f05b8b87c..050828c620a0747d9587118d6b5b006a7a3590f1 100644
--- a/src/testsuite/testsuite-common.c
+++ b/src/testsuite/testsuite-common.c
@@ -50,6 +50,7 @@ char *testsuite_test_path = NULL;
 /* Test context */
 
 static string_t *test_name;
+static sieve_size_t test_block_end;
 static unsigned int test_index;
 static unsigned int test_failures;
 
@@ -154,35 +155,51 @@ testsuite_interpreter_context_get(struct sieve_interpreter *interp,
 static void testsuite_test_context_init(void)
 {
 	test_name = str_new(default_pool, 128);
+	test_block_end = 0;
 	test_index = 0;
 	test_failures = 0;
 }
 
-void testsuite_test_start(string_t *name)
+int testsuite_test_start(const struct sieve_runtime_env *renv,
+			 string_t *name, sieve_size_t block_end)
 {
+	if (test_block_end != 0) {
+		sieve_runtime_trace_error(renv, "already inside test block");
+		return SIEVE_EXEC_BIN_CORRUPT;
+	}
 	str_truncate(test_name, 0);
 	str_append_str(test_name, name);
 
+	test_block_end = block_end;
 	test_index++;
+
+	return SIEVE_EXEC_OK;
 }
 
-void testsuite_test_fail(string_t *reason)
+int testsuite_test_fail(const struct sieve_runtime_env *renv,
+			string_t *reason)
 {
-	testsuite_test_fail_cstr(str_c(reason));
+	return testsuite_test_fail_cstr(renv, str_c(reason));
 }
 
-void testsuite_test_failf(const char *fmt, ...)
+int testsuite_test_failf(const struct sieve_runtime_env *renv,
+			 const char *fmt, ...)
 {
 	va_list args;
-	va_start(args, fmt);
-
-	testsuite_test_fail_cstr(t_strdup_vprintf(fmt, args));
+	int ret;
 
+	va_start(args, fmt);
+	ret = testsuite_test_fail_cstr(renv, t_strdup_vprintf(fmt, args));
 	va_end(args);
+
+	return ret;
 }
 
-void testsuite_test_fail_cstr(const char *reason)
+int testsuite_test_fail_cstr(const struct sieve_runtime_env *renv,
+			     const char *reason)
 {
+	sieve_size_t end = test_block_end;
+
 	if (str_len(test_name) == 0) {
 		if (reason == NULL || *reason == '\0')
 			printf("%2d: Test FAILED\n", test_index);
@@ -199,8 +216,11 @@ void testsuite_test_fail_cstr(const char *reason)
 	}
 
 	str_truncate(test_name, 0);
+	test_block_end = 0;
 
 	test_failures++;
+
+	return sieve_interpreter_program_jump_to(renv->interp, end, FALSE);
 }
 
 void testsuite_testcase_fail(const char *reason)
@@ -213,8 +233,12 @@ void testsuite_testcase_fail(const char *reason)
 	test_failures++;
 }
 
-void testsuite_test_succeed(string_t *reason)
+int testsuite_test_succeed(const struct sieve_runtime_env *renv,
+			   sieve_size_t *address, string_t *reason)
 {
+	sieve_size_t end = test_block_end;
+	int ret;
+
 	if (str_len(test_name) == 0) {
 		if (reason == NULL || str_len(reason) == 0)
 			printf("%2d: Test SUCCEEDED\n", test_index);
@@ -231,7 +255,22 @@ void testsuite_test_succeed(string_t *reason)
 				str_c(test_name), str_c(reason));
 		}
 	}
+
 	str_truncate(test_name, 0);
+	test_block_end = 0;
+
+	if (*address > end) {
+		sieve_runtime_trace_error(
+			renv, "invalid test block end offset");
+		return SIEVE_EXEC_BIN_CORRUPT;
+	} else if (*address < end) {
+		ret = sieve_interpreter_program_jump_to(
+			renv->interp, end, FALSE);
+		if (ret <= 0)
+			return ret;
+	}
+
+	return SIEVE_EXEC_OK;
 }
 
 static void testsuite_test_context_deinit(void)
diff --git a/src/testsuite/testsuite-common.h b/src/testsuite/testsuite-common.h
index 644ce5bbcee07c3c62f69ecd365b23ddda600a65..9a40cddd594f291b1d5d7efbf1f51ff703220600 100644
--- a/src/testsuite/testsuite-common.h
+++ b/src/testsuite/testsuite-common.h
@@ -161,12 +161,17 @@ enum testsuite_operand_code {
  * Test context
  */
 
-void testsuite_test_start(string_t *name);
-void testsuite_test_fail(string_t *reason);
-void testsuite_test_failf(const char *fmt, ...) ATTR_FORMAT(1, 2);
-void testsuite_test_fail_cstr(const char *reason);
-
-void testsuite_test_succeed(string_t *reason);
+int testsuite_test_start(const struct sieve_runtime_env *renv,
+			 string_t *name, sieve_size_t block_end);
+int testsuite_test_fail(const struct sieve_runtime_env *renv,
+			string_t *reason);
+int testsuite_test_failf(const struct sieve_runtime_env *renv,
+			 const char *fmt, ...) ATTR_FORMAT(2, 3);
+int testsuite_test_fail_cstr(const struct sieve_runtime_env *renv,
+			     const char *reason);
+
+int testsuite_test_succeed(const struct sieve_runtime_env *renv,
+			   sieve_size_t *address, string_t *reason);
 
 void testsuite_testcase_fail(const char *reason);
 bool testsuite_testcase_result(bool expect_failure);
diff --git a/tests/failures/fuzz1.svtest b/tests/failures/fuzz1.svtest
new file mode 100644
index 0000000000000000000000000000000000000000..a6fe086c6a6b2f5b0ae0bbd95e01315d912c5a8a
--- /dev/null
+++ b/tests/failures/fuzz1.svtest
@@ -0,0 +1,33 @@
+# Used to cause the test suite to segfault
+
+require "vnd.dovecot.testsuite";
+require "fileinto";
+require "imap4flags";
+require "mailbox";
+
+
+test_set "message" text:
+Subject: Test message.
+
+Test message.
+.
+;
+
+test "Flag changes between stores" {
+        fileinto :create "FolderA";
+
+        if not test_result_execute {
+                test_fail "failed to execute first result";
+        }
+
+        test_message :folder "FolderA" 0;
+
+        test_result_reset;
+
+        test_message :folder "Uninteiesting" 0;
+
+        if not hasflag "$label1" {
+                test_fail "flags not stored for fired for third message";
+        }
+
+}
diff --git a/tests/failures/fuzz2.svtest b/tests/failures/fuzz2.svtest
new file mode 100644
index 0000000000000000000000000000000000000000..9fa63eac5df77483d8ac9f53db4d9af33fd65737
--- /dev/null
+++ b/tests/failures/fuzz2.svtest
@@ -0,0 +1,37 @@
+require "vnd.dovecot.testsuite";
+require "fileinto";
+require "variables";
+require "mailbox";
+
+set "message" text:
+From:.org
+To:rg
+Subject: First message
+
+Frop
+.
+;
+
+
+test "sometest" {
+    test_set "message" "${message}";
+
+    fileinto :create "Folder";
+
+    if not test_result_execute {
+        test_fail "";
+    }
+
+    test_message :folder "Folder" 0;
+
+    if not header "subject" "First message" {
+        test_fail "";
+    }
+
+    test_message :folder " .Folder" 1;
+
+    if not header "subject" "Second message" {
+        test_fail "";
+    }
+
+}