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

7
tmux.1
View File

@@ -7449,7 +7449,7 @@ is
the contents are read from stdin. the contents are read from stdin.
.Tg pasteb .Tg pasteb
.It Xo Ic paste-buffer .It Xo Ic paste-buffer
.Op Fl dpr .Op Fl dprS
.Op Fl b Ar buffer-name .Op Fl b Ar buffer-name
.Op Fl s Ar separator .Op Fl s Ar separator
.Op Fl t Ar target-pane .Op Fl t Ar target-pane
@@ -7457,9 +7457,14 @@ the contents are read from stdin.
.D1 Pq alias: Ic pasteb .D1 Pq alias: Ic pasteb
Insert the contents of a paste buffer into the specified pane. Insert the contents of a paste buffer into the specified pane.
If not specified, paste into the current one. If not specified, paste into the current one.
By default, control characters are sanitized with
.Xr vis 3 ;
.Fl S
disables this.
With With
.Fl d , .Fl d ,
also delete the paste buffer. also delete the paste buffer.
.Pp
When output, any linefeed (LF) characters in the paste buffer are replaced with When output, any linefeed (LF) characters in the paste buffer are replaced with
a separator, by default carriage return (CR). a separator, by default carriage return (CR).
A custom separator may be specified using the 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_open(struct utf8_data *, u_char);
enum utf8_state utf8_append(struct utf8_data *, u_char); enum utf8_state utf8_append(struct utf8_data *, u_char);
int utf8_isvalid(const char *); int utf8_isvalid(const char *);
int utf8_strvis(char *, const char *, size_t, int); size_t utf8_strvis(char *, const char *, size_t, int);
int utf8_stravis(char **, const char *, int); size_t utf8_stravis(char **, const char *, int);
int utf8_stravisx(char **, const char *, size_t, int); size_t utf8_stravisx(char **, const char *, size_t, int);
char *utf8_sanitize(const char *); char *utf8_sanitize(const char *);
size_t utf8_strlen(const struct utf8_data *); size_t utf8_strlen(const struct utf8_data *);
u_int utf8_strwidth(const struct utf8_data *, ssize_t); 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 * bytes available for each character from src (for \abc or UTF-8) plus space
* for \0. * for \0.
*/ */
int size_t
utf8_strvis(char *dst, const char *src, size_t len, int flag) utf8_strvis(char *dst, const char *src, size_t len, int flag)
{ {
struct utf8_data ud; 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. */ /* Same as utf8_strvis but allocate the buffer. */
int size_t
utf8_stravis(char **dst, const char *src, int flag) utf8_stravis(char **dst, const char *src, int flag)
{ {
char *buf; char *buf;
int len; size_t len;
buf = xreallocarray(NULL, 4, strlen(src) + 1); buf = xreallocarray(NULL, 4, strlen(src) + 1);
len = utf8_strvis(buf, src, strlen(src), flag); 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. */ /* Same as utf8_strvis but allocate the buffer. */
int size_t
utf8_stravisx(char **dst, const char *src, size_t srclen, int flag) utf8_stravisx(char **dst, const char *src, size_t srclen, int flag)
{ {
char *buf; char *buf;
int len; size_t len;
buf = xreallocarray(NULL, 4, srclen + 1); buf = xreallocarray(NULL, 4, srclen + 1);
len = utf8_strvis(buf, src, srclen, flag); len = utf8_strvis(buf, src, srclen, flag);