diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2023-04-16 11:48:23 +0300 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2023-04-16 11:48:23 +0300 |
commit | a6b5394086260c262e393dd113057916fd14134b (patch) | |
tree | 1687520d5d57f7fe269483c78b85c7be429b52d3 /src | |
parent | 030e0f5859698638a33d3a34c0659871d1dc7333 (diff) | |
download | sciteco-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.
Diffstat (limited to 'src')
-rw-r--r-- | src/parser.c | 16 |
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, |