Make paste_get_top return a copy of the buffer name which is more

sensible and avoids a double free pointed out by DongHan Kim.
This commit is contained in:
nicm
2026-02-11 08:30:37 +00:00
parent 5b455abecc
commit 7e50eb0e83
4 changed files with 27 additions and 24 deletions

View File

@@ -58,29 +58,31 @@ cmd_set_buffer_exec(struct cmd *self, struct cmdq_item *item)
struct args *args = cmd_get_args(self);
struct client *tc = cmdq_get_target_client(item);
struct paste_buffer *pb;
char *bufdata, *cause;
const char *bufname, *olddata;
size_t bufsize, newsize;
char *bufname, *bufdata = NULL, *cause = NULL;
const char *olddata;
size_t bufsize = 0, newsize;
bufname = args_get(args, 'b');
if (bufname == NULL)
if (args_get(args, 'b') == NULL)
pb = NULL;
else
else {
bufname = xstrdup(args_get(args, 'b'));
pb = paste_get_name(bufname);
}
if (cmd_get_entry(self) == &cmd_delete_buffer_entry) {
if (pb == NULL) {
if (bufname != NULL) {
cmdq_error(item, "unknown buffer: %s", bufname);
return (CMD_RETURN_ERROR);
goto fail;
}
pb = paste_get_top(&bufname);
}
if (pb == NULL) {
cmdq_error(item, "no buffer");
return (CMD_RETURN_ERROR);
goto fail;
}
paste_free(pb);
free(bufname);
return (CMD_RETURN_NORMAL);
}
@@ -88,32 +90,28 @@ cmd_set_buffer_exec(struct cmd *self, struct cmdq_item *item)
if (pb == NULL) {
if (bufname != NULL) {
cmdq_error(item, "unknown buffer: %s", bufname);
return (CMD_RETURN_ERROR);
goto fail;
}
pb = paste_get_top(&bufname);
}
if (pb == NULL) {
cmdq_error(item, "no buffer");
return (CMD_RETURN_ERROR);
goto fail;
}
if (paste_rename(bufname, args_get(args, 'n'), &cause) != 0) {
cmdq_error(item, "%s", cause);
free(cause);
return (CMD_RETURN_ERROR);
goto fail;
}
return (CMD_RETURN_NORMAL);
}
if (args_count(args) != 1) {
cmdq_error(item, "no data specified");
return (CMD_RETURN_ERROR);
goto fail;
}
if ((newsize = strlen(args_string(args, 0))) == 0)
return (CMD_RETURN_NORMAL);
bufsize = 0;
bufdata = NULL;
if (args_has(args, 'a') && pb != NULL) {
olddata = paste_buffer_data(pb, &bufsize);
bufdata = xmalloc(bufsize);
@@ -126,12 +124,16 @@ cmd_set_buffer_exec(struct cmd *self, struct cmdq_item *item)
if (paste_set(bufdata, bufsize, bufname, &cause) != 0) {
cmdq_error(item, "%s", cause);
free(bufdata);
free(cause);
return (CMD_RETURN_ERROR);
goto fail;
}
if (args_has(args, 'w') && tc != NULL)
tty_set_selection(&tc->tty, "", bufdata, bufsize);
return (CMD_RETURN_NORMAL);
fail:
free(bufdata);
free(bufname);
free(cause);
return (CMD_RETURN_ERROR);
}

View File

@@ -107,7 +107,7 @@ paste_is_empty(void)
/* Get the most recent automatic buffer. */
struct paste_buffer *
paste_get_top(const char **name)
paste_get_top(char **name)
{
struct paste_buffer *pb;
@@ -117,7 +117,7 @@ paste_get_top(const char **name)
if (pb == NULL)
return (NULL);
if (name != NULL)
*name = pb->name;
*name = xstrdup(pb->name);
return (pb);
}

2
tmux.h
View File

@@ -2320,7 +2320,7 @@ time_t paste_buffer_created(struct paste_buffer *);
const char *paste_buffer_data(struct paste_buffer *, size_t *);
struct paste_buffer *paste_walk(struct paste_buffer *);
int paste_is_empty(void);
struct paste_buffer *paste_get_top(const char **);
struct paste_buffer *paste_get_top(char **);
struct paste_buffer *paste_get_name(const char *);
void paste_free(struct paste_buffer *);
void paste_add(const char *, char *, size_t);

View File

@@ -5052,9 +5052,9 @@ static void
window_copy_append_selection(struct window_mode_entry *wme)
{
struct window_pane *wp = wme->wp;
char *buf;
char *buf, *bufname = NULL;
struct paste_buffer *pb;
const char *bufdata, *bufname = NULL;
const char *bufdata;
size_t len, bufsize;
struct screen_write_ctx ctx;
@@ -5079,6 +5079,7 @@ window_copy_append_selection(struct window_mode_entry *wme)
}
if (paste_set(buf, len, bufname, NULL) != 0)
free(buf);
free(bufname);
}
static void