aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2023-04-16 11:48:23 +0300
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2023-04-16 11:48:23 +0300
commita6b5394086260c262e393dd113057916fd14134b (patch)
tree1687520d5d57f7fe269483c78b85c7be429b52d3
parent030e0f5859698638a33d3a34c0659871d1dc7333 (diff)
downloadsciteco-a6b5394086260c262e393dd113057916fd14134b.tar.gz
fixed interruptions of commands with string arguments in interactive mode
* In order to provoke this bug, there must be a loop with a string command. For instance <Ifoobar^J$>. When interrupting this loop, ctx->expectstring.insert_len might end up > 0. This breaks an optimization that avoids undo tokens for insert_len since it is usually reset to 0 after every keypress. Once you rubout everything and retype `I`, you can crash SciTECO. * I am not sure if this solution is ideal. An alternative might be adding teco_state_expectstring_initial(), but we would have to chain to it from some child states that have their own initial() callback. Of course, we could also simply teco_undo_gsize(insert_len) at the cost of undo tokens.
-rw-r--r--src/parser.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/src/parser.c b/src/parser.c
index 8e24a9d..cf887d4 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -803,6 +803,10 @@ teco_state_expectstring_input(teco_machine_main_t *ctx, gchar chr, GError **erro
}
}
+ /* insert_len might end up > 0 after interruptions */
+ if (!ctx->expectstring.string.len)
+ ctx->expectstring.insert_len = 0;
+
if (!ctx->expectstring.nesting) {
/*
* Call process_cb() even if interactive feedback
@@ -857,11 +861,11 @@ teco_state_expectstring_input(teco_machine_main_t *ctx, gchar chr, GError **erro
} else if (ctx->mode == TECO_MODE_NORMAL) {
teco_string_append_c(&ctx->expectstring.string, chr);
}
+
/*
- * NOTE: As an optimization insert_len is not
- * restored on undo since that is only
- * necessary in interactive mode and we get
- * called once per character when this is necessary.
+ * NOTE: As an optimization insert_len is not restored on undo since
+ * it is 0 after every key press anyway.
+ * The only exception is when interrupting a command in a loop.
*/
ctx->expectstring.insert_len += ctx->expectstring.string.len - old_len;
@@ -873,6 +877,10 @@ teco_state_expectstring_refresh(teco_machine_main_t *ctx, GError **error)
{
teco_state_t *current = ctx->parent.current;
+ /* insert_len might end up > 0 after interruptions */
+ if (!ctx->expectstring.string.len)
+ ctx->expectstring.insert_len = 0;
+
/* never calls process_cb() in parse-only mode */
if (ctx->expectstring.insert_len && current->expectstring.process_cb &&
!current->expectstring.process_cb(ctx, &ctx->expectstring.string,