aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2025-03-16 22:30:41 +0300
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2025-03-17 17:39:30 +0300
commit06e48c350c2aed0f14d8f5b4957959055354dfd4 (patch)
treed4c0b407f8a7f14b338f57dca4c6162a78c46760 /src
parent6bc8e4a4caaa13b832c88f345e33f94ab4b83a13 (diff)
downloadsciteco-06e48c350c2aed0f14d8f5b4957959055354dfd4.tar.gz
fixed memory leak when seeing an existing label (exactly the same or redefinition)
This could actually be reproduced by `./testsuite --valgrind` and by the Address Sanitizer.
Diffstat (limited to 'src')
-rw-r--r--src/goto-commands.c32
1 files changed, 15 insertions, 17 deletions
diff --git a/src/goto-commands.c b/src/goto-commands.c
index 99288c1..d463151 100644
--- a/src/goto-commands.c
+++ b/src/goto-commands.c
@@ -65,27 +65,25 @@ teco_state_label_input(teco_machine_main_t *ctx, gunichar chr, GError **error)
if (chr == '!') {
gssize existing_pc = teco_goto_table_set(&ctx->goto_table, ctx->goto_label.data,
ctx->goto_label.len, ctx->macro_pc);
- if (existing_pc == ctx->macro_pc)
- /* encountered the same label again */
- return &teco_state_start;
- if (existing_pc >= 0) {
+ if (existing_pc < 0) {
+ /* new label */
+ if (ctx->parent.must_undo)
+ teco_goto_table_undo_remove(&ctx->goto_table, ctx->goto_label.data, ctx->goto_label.len);
+
+ if (teco_goto_skip_label.len > 0 &&
+ !teco_string_cmp(&ctx->goto_label, teco_goto_skip_label.data, teco_goto_skip_label.len)) {
+ teco_undo_string_own(teco_goto_skip_label);
+ memset(&teco_goto_skip_label, 0, sizeof(teco_goto_skip_label));
+
+ if (ctx->parent.must_undo)
+ teco_undo_guint(ctx->__flags);
+ ctx->mode = TECO_MODE_NORMAL;
+ }
+ } else if (existing_pc != ctx->macro_pc) {
g_autofree gchar *label_printable = teco_string_echo(ctx->goto_label.data,
ctx->goto_label.len);
teco_interface_msg(TECO_MSG_WARNING, "Ignoring goto label \"%s\" redefinition",
label_printable);
- return &teco_state_start;
- }
- if (ctx->parent.must_undo)
- teco_goto_table_undo_remove(&ctx->goto_table, ctx->goto_label.data, ctx->goto_label.len);
-
- if (teco_goto_skip_label.len > 0 &&
- !teco_string_cmp(&ctx->goto_label, teco_goto_skip_label.data, teco_goto_skip_label.len)) {
- teco_undo_string_own(teco_goto_skip_label);
- memset(&teco_goto_skip_label, 0, sizeof(teco_goto_skip_label));
-
- if (ctx->parent.must_undo)
- teco_undo_guint(ctx->__flags);
- ctx->mode = TECO_MODE_NORMAL;
}
if (ctx->parent.must_undo)