mirror of
https://github.com/tmux/tmux.git
synced 2026-02-13 00:59:16 +00:00
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:
@@ -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);
|
||||
}
|
||||
|
||||
4
paste.c
4
paste.c
@@ -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
2
tmux.h
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user