Handle NULL client (in config file) when showing a status message; also
authornicm <nicm@openbsd.org>
Tue, 14 Nov 2023 15:59:49 +0000 (15:59 +0000)
committernicm <nicm@openbsd.org>
Tue, 14 Nov 2023 15:59:49 +0000 (15:59 +0000)
copy the file when processing if-shell since it may be freed. GitHub
issue 3746.

usr.bin/tmux/arguments.c
usr.bin/tmux/status.c

index b62d1f7..a13965b 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: arguments.c,v 1.60 2023/06/30 21:55:08 nicm Exp $ */
+/* $OpenBSD: arguments.c,v 1.61 2023/11/14 15:59:49 nicm Exp $ */
 
 /*
  * Copyright (c) 2010 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -761,6 +761,7 @@ args_make_commands_prepare(struct cmd *self, struct cmdq_item *item, u_int idx,
        struct args_value               *value;
        struct args_command_state       *state;
        const char                      *cmd;
+       const char                      *file;
 
        state = xcalloc(1, sizeof *state);
 
@@ -787,7 +788,8 @@ args_make_commands_prepare(struct cmd *self, struct cmdq_item *item, u_int idx,
 
        if (wait)
                state->pi.item = item;
-       cmd_get_source(self, &state->pi.file, &state->pi.line);
+       cmd_get_source(self, &file, &state->pi.line);
+       state->pi.file = xstrdup(file);
        state->pi.c = tc;
        if (state->pi.c != NULL)
                state->pi.c->references++;
@@ -842,6 +844,7 @@ args_make_commands_free(struct args_command_state *state)
                cmd_list_free(state->cmdlist);
        if (state->pi.c != NULL)
                server_client_unref(state->pi.c);
+       free((void *)state->pi.file);
        free(state->cmd);
        free(state);
 }
index 9e7aa29..1f2138b 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: status.c,v 1.240 2023/08/15 07:01:47 nicm Exp $ */
+/* $OpenBSD: status.c,v 1.241 2023/11/14 15:59:49 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -472,17 +472,26 @@ void
 status_message_set(struct client *c, int delay, int ignore_styles,
     int ignore_keys, const char *fmt, ...)
 {
-       struct timeval  tv;
-       va_list         ap;
-
-       status_message_clear(c);
-       status_push_screen(c);
+       struct timeval   tv;
+       va_list          ap;
+       char            *s;
 
        va_start(ap, fmt);
-       xvasprintf(&c->message_string, fmt, ap);
+       xvasprintf(&s, fmt, ap);
        va_end(ap);
 
-       server_add_message("%s message: %s", c->name, c->message_string);
+       log_debug("%s: %s", __func__, s);
+
+       if (c == NULL) {
+               server_add_message("message: %s", s);
+               free(s);
+               return;
+       }
+
+       status_message_clear(c);
+       status_push_screen(c);
+       c->message_string = s;
+       server_add_message("%s message: %s", c->name, s);
 
        /*
         * With delay -1, the display-time option is used; zero means wait for