Skip to content

Commit

Permalink
fixed interruptions of commands with string arguments in interactive …
Browse files Browse the repository at this point in the history
…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.
  • Loading branch information
rhaberkorn committed Apr 16, 2023
1 parent 030e0f5 commit a6b5394
Showing 1 changed file with 12 additions and 4 deletions.
16 changes: 12 additions & 4 deletions src/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;

Expand All @@ -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,
Expand Down

0 comments on commit a6b5394

Please sign in to comment.