Pass paste buffer through vis(3) when pasting to prevent buffers

containing for example the bracket end sequence causing issues. -S flag
disables. Reported by Mason Davis.
This commit is contained in:
nicm
2026-02-25 07:53:41 +00:00
parent bd6e201926
commit 5b3c642195
4 changed files with 40 additions and 16 deletions

View File

@@ -34,8 +34,8 @@ const struct cmd_entry cmd_paste_buffer_entry = {
.name = "paste-buffer",
.alias = "pasteb",
.args = { "db:prs:t:", 0, 0, NULL },
.usage = "[-dpr] [-s separator] " CMD_BUFFER_USAGE " "
.args = { "db:prSs:t:", 0, 0, NULL },
.usage = "[-dprS] [-s separator] " CMD_BUFFER_USAGE " "
CMD_TARGET_PANE_USAGE,
.target = { 't', CMD_FIND_PANE, 0 },
@@ -44,6 +44,17 @@ const struct cmd_entry cmd_paste_buffer_entry = {
.exec = cmd_paste_buffer_exec
};
static void
cmd_paste_buffer_paste(struct window_pane *wp, const char *buf, size_t len)
{
char *cp;
size_t n;
n = utf8_stravisx(&cp, buf, len, VIS_SAFE);
bufferevent_write(wp->event, cp, n);
free(cp);
}
static enum cmd_retval
cmd_paste_buffer_exec(struct cmd *self, struct cmdq_item *item)
{
@@ -52,7 +63,7 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmdq_item *item)
struct window_pane *wp = target->wp;
struct paste_buffer *pb;
const char *sepstr, *bufname, *bufdata, *bufend, *line;
size_t seplen, bufsize;
size_t seplen, bufsize, len;
int bracket = args_has(args, 'p');
if (window_pane_exited(wp)) {
@@ -94,14 +105,22 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmdq_item *item)
line = memchr(bufdata, '\n', bufend - bufdata);
if (line == NULL)
break;
bufferevent_write(wp->event, bufdata, line - bufdata);
len = line - bufdata;
if (args_has(args, 'S'))
bufferevent_write(wp->event, bufdata, len);
else
cmd_paste_buffer_paste(wp, bufdata, len);
bufferevent_write(wp->event, sepstr, seplen);
bufdata = line + 1;
}
if (bufdata != bufend)
bufferevent_write(wp->event, bufdata, bufend - bufdata);
if (bufdata != bufend) {
len = bufend - bufdata;
if (args_has(args, 'S'))
bufferevent_write(wp->event, bufdata, len);
else
cmd_paste_buffer_paste(wp, bufdata, len);
}
if (bracket && (wp->screen->mode & MODE_BRACKETPASTE))
bufferevent_write(wp->event, "\033[201~", 6);

7
tmux.1
View File

@@ -7449,7 +7449,7 @@ is
the contents are read from stdin.
.Tg pasteb
.It Xo Ic paste-buffer
.Op Fl dpr
.Op Fl dprS
.Op Fl b Ar buffer-name
.Op Fl s Ar separator
.Op Fl t Ar target-pane
@@ -7457,9 +7457,14 @@ the contents are read from stdin.
.D1 Pq alias: Ic pasteb
Insert the contents of a paste buffer into the specified pane.
If not specified, paste into the current one.
By default, control characters are sanitized with
.Xr vis 3 ;
.Fl S
disables this.
With
.Fl d ,
also delete the paste buffer.
.Pp
When output, any linefeed (LF) characters in the paste buffer are replaced with
a separator, by default carriage return (CR).
A custom separator may be specified using the

6
tmux.h
View File

@@ -3573,9 +3573,9 @@ void utf8_copy(struct utf8_data *, const struct utf8_data *);
enum utf8_state utf8_open(struct utf8_data *, u_char);
enum utf8_state utf8_append(struct utf8_data *, u_char);
int utf8_isvalid(const char *);
int utf8_strvis(char *, const char *, size_t, int);
int utf8_stravis(char **, const char *, int);
int utf8_stravisx(char **, const char *, size_t, int);
size_t utf8_strvis(char *, const char *, size_t, int);
size_t utf8_stravis(char **, const char *, int);
size_t utf8_stravisx(char **, const char *, size_t, int);
char *utf8_sanitize(const char *);
size_t utf8_strlen(const struct utf8_data *);
u_int utf8_strwidth(const struct utf8_data *, ssize_t);

10
utf8.c
View File

@@ -639,7 +639,7 @@ utf8_append(struct utf8_data *ud, u_char ch)
* bytes available for each character from src (for \abc or UTF-8) plus space
* for \0.
*/
int
size_t
utf8_strvis(char *dst, const char *src, size_t len, int flag)
{
struct utf8_data ud;
@@ -677,11 +677,11 @@ utf8_strvis(char *dst, const char *src, size_t len, int flag)
}
/* Same as utf8_strvis but allocate the buffer. */
int
size_t
utf8_stravis(char **dst, const char *src, int flag)
{
char *buf;
int len;
size_t len;
buf = xreallocarray(NULL, 4, strlen(src) + 1);
len = utf8_strvis(buf, src, strlen(src), flag);
@@ -691,11 +691,11 @@ utf8_stravis(char **dst, const char *src, int flag)
}
/* Same as utf8_strvis but allocate the buffer. */
int
size_t
utf8_stravisx(char **dst, const char *src, size_t srclen, int flag)
{
char *buf;
int len;
size_t len;
buf = xreallocarray(NULL, 4, srclen + 1);
len = utf8_strvis(buf, src, srclen, flag);