Merge branch 'obsd-master'

This commit is contained in:
Thomas Adam
2026-06-29 19:30:07 +01:00
12 changed files with 35 additions and 63 deletions

View File

@@ -108,7 +108,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item)
if (args_has(args, 'W')) if (args_has(args, 'W'))
return (cmd_break_pane_float(item, args, w, wp)); return (cmd_break_pane_float(item, args, w, wp));
if (name != NULL && !check_name(name, WINDOW_NAME_FORBID)) { if (name != NULL && !check_name(name)) {
cmdq_error(item, "invalid window name: %s", name); cmdq_error(item, "invalid window name: %s", name);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
@@ -132,7 +132,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item)
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
if (name != NULL) { if (name != NULL) {
window_set_name(w, name, WINDOW_NAME_FORBID); window_set_name(w, name, 0);
options_set_number(w->options, "automatic-rename", 0); options_set_number(w->options, "automatic-rename", 0);
} }
server_unlink_window(src_s, wl); server_unlink_window(src_s, wl);
@@ -162,7 +162,7 @@ cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item)
if (name == NULL) { if (name == NULL) {
newname = default_window_name(w); newname = default_window_name(w);
window_set_name(w, newname, WINDOW_NAME_FORBID); window_set_name(w, newname, 0);
free(newname); free(newname);
} else { } else {
window_set_name(w, name, 0); window_set_name(w, name, 0);

View File

@@ -101,22 +101,22 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
if ((tmp = args_get(args, 'n')) != NULL) { if ((tmp = args_get(args, 'n')) != NULL) {
ename = format_single(item, tmp, c, NULL, NULL, NULL); ename = format_single(item, tmp, c, NULL, NULL, NULL);
if (!check_name(ename, WINDOW_NAME_FORBID)) { if (!check_name(ename)) {
cmdq_error(item, "invalid window name: %s", ename); cmdq_error(item, "invalid window name: %s", ename);
free(ename); free(ename);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
wname = clean_name(ename, WINDOW_NAME_FORBID); wname = clean_name(ename, 0);
free(ename); free(ename);
} }
if ((tmp = args_get(args, 's')) != NULL) { if ((tmp = args_get(args, 's')) != NULL) {
ename = format_single(item, tmp, c, NULL, NULL, NULL); ename = format_single(item, tmp, c, NULL, NULL, NULL);
if (!check_name(ename, SESSION_NAME_FORBID)) { if (!check_name(ename)) {
cmdq_error(item, "invalid session name: %s", ename); cmdq_error(item, "invalid session name: %s", ename);
free(ename); free(ename);
goto fail; goto fail;
} }
sname = clean_name(ename, SESSION_NAME_FORBID); sname = clean_name(ename, 0);
free(ename); free(ename);
} }
if (args_has(args, 'A')) { if (args_has(args, 'A')) {
@@ -152,12 +152,12 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
else if (groupwith != NULL) else if (groupwith != NULL)
prefix = xstrdup(groupwith->name); prefix = xstrdup(groupwith->name);
else { else {
if (!check_name(group, SESSION_NAME_FORBID)) { if (!check_name(group)) {
cmdq_error(item, cmdq_error(item,
"invalid session group name: %s", group); "invalid session group name: %s", group);
goto fail; goto fail;
} }
prefix = clean_name(group, SESSION_NAME_FORBID); prefix = clean_name(group, 0);
} }
} }

View File

@@ -73,12 +73,12 @@ cmd_new_window_exec(struct cmd *self, struct cmdq_item *item)
name = args_get(args, 'n'); name = args_get(args, 'n');
if (name != NULL) { if (name != NULL) {
expanded = format_single(item, name, c, s, NULL, NULL); expanded = format_single(item, name, c, s, NULL, NULL);
if (!check_name(expanded, WINDOW_NAME_FORBID)) { if (!check_name(expanded)) {
cmdq_error(item, "invalid window name: %s", expanded); cmdq_error(item, "invalid window name: %s", expanded);
free(expanded); free(expanded);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
wname = clean_name(expanded, WINDOW_NAME_FORBID); wname = clean_name(expanded, 0);
free(expanded); free(expanded);
} }
if (args_has(args, 'S') && wname != NULL && target->idx == -1) { if (args_has(args, 'S') && wname != NULL && target->idx == -1) {

View File

@@ -52,12 +52,12 @@ cmd_rename_session_exec(struct cmd *self, struct cmdq_item *item)
char *newname, *tmp; char *newname, *tmp;
tmp = format_single_from_target(item, args_string(args, 0)); tmp = format_single_from_target(item, args_string(args, 0));
if (!check_name(tmp, SESSION_NAME_FORBID)) { if (!check_name(tmp)) {
cmdq_error(item, "invalid session name: %s", tmp); cmdq_error(item, "invalid session name: %s", tmp);
free(tmp); free(tmp);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
newname = clean_name(tmp, SESSION_NAME_FORBID); newname = clean_name(tmp, 0);
free(tmp); free(tmp);
if (strcmp(newname, s->name) == 0) { if (strcmp(newname, s->name) == 0) {
free(newname); free(newname);

View File

@@ -51,13 +51,13 @@ cmd_rename_window_exec(struct cmd *self, struct cmdq_item *item)
char *name; char *name;
name = format_single_from_target(item, args_string(args, 0)); name = format_single_from_target(item, args_string(args, 0));
if (!check_name(name, WINDOW_NAME_FORBID)) { if (!check_name(name)) {
cmdq_error(item, "invalid window name: %s", name); cmdq_error(item, "invalid window name: %s", name);
free(name); free(name);
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }
window_set_name(wl->window, name, WINDOW_NAME_FORBID); window_set_name(wl->window, name, 0);
options_set_number(wl->window->options, "automatic-rename", 0); options_set_number(wl->window->options, "automatic-rename", 0);
free(name); free(name);

14
input.c
View File

@@ -1953,16 +1953,14 @@ input_csi_dispatch_rm_private(struct input_ctx *ictx)
case 2004: case 2004:
screen_write_mode_clear(sctx, MODE_BRACKETPASTE); screen_write_mode_clear(sctx, MODE_BRACKETPASTE);
break; break;
case 2026:
screen_write_stop_sync(ictx->wp);
break;
case 2031: case 2031:
screen_write_mode_clear(sctx, MODE_THEME_UPDATES); screen_write_mode_clear(sctx, MODE_THEME_UPDATES);
if (ictx->wp != NULL) if (ictx->wp != NULL)
ictx->wp->flags &= ~PANE_THEMECHANGED; ictx->wp->flags &= ~PANE_THEMECHANGED;
break; break;
case 2026: /* synchronized output */
screen_write_stop_sync(ictx->wp);
if (ictx->wp != NULL)
ictx->wp->flags |= PANE_REDRAW;
break;
default: default:
log_debug("%s: unknown '%c'", __func__, ictx->ch); log_debug("%s: unknown '%c'", __func__, ictx->ch);
break; break;
@@ -2065,7 +2063,7 @@ input_csi_dispatch_sm_private(struct input_ctx *ictx)
ictx->wp->flags &= ~PANE_THEMECHANGED; ictx->wp->flags &= ~PANE_THEMECHANGED;
} }
break; break;
case 2026: /* synchronized output */ case 2026:
screen_write_start_sync(ictx->wp); screen_write_start_sync(ictx->wp);
break; break;
default: default:
@@ -2822,10 +2820,10 @@ input_exit_rename(struct input_ctx *ictx)
if (o != NULL) if (o != NULL)
options_remove_or_default(o, -1, NULL); options_remove_or_default(o, -1, NULL);
if (!options_get_number(w->options, "automatic-rename")) if (!options_get_number(w->options, "automatic-rename"))
window_set_name(w, "", WINDOW_NAME_FORBID_EXT); window_set_name(w, "", 1);
} else { } else {
options_set_number(w->options, "automatic-rename", 0); options_set_number(w->options, "automatic-rename", 0);
window_set_name(w, ictx->input_buf, WINDOW_NAME_FORBID_EXT); window_set_name(w, ictx->input_buf, 1);
} }
server_redraw_window_borders(w); server_redraw_window_borders(w);
server_status_window(w); server_status_window(w);

View File

@@ -95,7 +95,7 @@ check_window_name(struct window *w)
name = format_window_name(w); name = format_window_name(w);
if (strcmp(name, w->name) != 0) { if (strcmp(name, w->name) != 0) {
log_debug("@%u new name %s (was %s)", w->id, name, w->name); log_debug("@%u new name %s (was %s)", w->id, name, w->name);
window_set_name(w, name, WINDOW_NAME_FORBID_EXT); window_set_name(w, name, 1);
server_redraw_window_borders(w); server_redraw_window_borders(w);
server_status_window(w); server_status_window(w);
} else } else
@@ -166,7 +166,7 @@ parse_window_name(const char *in)
if (*name == '/') if (*name == '/')
name = basename(name); name = basename(name);
name = clean_name(name, WINDOW_NAME_FORBID); name = clean_name(name, 0);
free(copy); free(copy);
if (name == NULL) if (name == NULL)
return (xstrdup("")); return (xstrdup(""));

View File

@@ -219,7 +219,7 @@ paste_rename(const char *oldname, const char *newname, char **cause)
return (-1); return (-1);
} }
name = clean_name(newname, ""); name = clean_name(newname, 0);
if (name == NULL) { if (name == NULL) {
if (cause != NULL) if (cause != NULL)
xasprintf(cause, "invalid buffer name: %s", newname); xasprintf(cause, "invalid buffer name: %s", newname);
@@ -287,7 +287,7 @@ paste_set(char *data, size_t size, const char *name, char **cause)
return (-1); return (-1);
} }
newname = clean_name(name, ""); newname = clean_name(name, 0);
if (newname == NULL) { if (newname == NULL) {
if (cause != NULL) if (cause != NULL)
xasprintf(cause, "invalid buffer name: %s", name); xasprintf(cause, "invalid buffer name: %s", name);

View File

@@ -250,10 +250,7 @@ screen_set_title(struct screen *s, const char *title, int untrusted)
{ {
char *new_title; char *new_title;
if (untrusted) new_title = clean_name(title, untrusted);
new_title = clean_name(title, "#");
else
new_title = clean_name(title, "");
if (new_title == NULL) if (new_title == NULL)
return (0); return (0);
free(s->title); free(s->title);
@@ -267,10 +264,7 @@ screen_set_path(struct screen *s, const char *path, int untrusted)
{ {
char *new_path; char *new_path;
if (untrusted) new_path = clean_name(path, untrusted);
new_path = clean_name(path, "#");
else
new_path = clean_name(path, "");
if (new_path == NULL) if (new_path == NULL)
return (0); return (0);
free(s->path); free(s->path);

20
tmux.c
View File

@@ -282,7 +282,7 @@ get_timer(void)
} }
char * char *
clean_name(const char *name, const char* forbid) clean_name(const char *name, int untrusted)
{ {
char *copy, *cp, *new_name; char *copy, *cp, *new_name;
@@ -290,10 +290,7 @@ clean_name(const char *name, const char* forbid)
return (NULL); return (NULL);
copy = xstrdup(name); copy = xstrdup(name);
for (cp = copy; *cp != '\0'; cp++) { for (cp = copy; *cp != '\0'; cp++) {
if (*cp == '#' && strchr(forbid, '#') != NULL) { if (untrusted && cp[0] == '#' && cp[1] == '(')
if (cp[1] == '(')
*cp = '_';
} else if (strchr(forbid, *cp) != NULL)
*cp = '_'; *cp = '_';
} }
utf8_stravis(&new_name, copy, VIS_OCTAL|VIS_CSTYLE|VIS_TAB|VIS_NL); utf8_stravis(&new_name, copy, VIS_OCTAL|VIS_CSTYLE|VIS_TAB|VIS_NL);
@@ -301,22 +298,11 @@ clean_name(const char *name, const char* forbid)
return (new_name); return (new_name);
} }
/*
* Check a name given by a command: reject it if it is empty, not valid UTF-8,
* or contains a forbidden character. Other characters that clean_name would
* change (for example with utf8_stravis) are allowed and fixed silently.
*/
int int
check_name(const char *name, const char *forbid) check_name(const char *name)
{ {
const char *cp;
if (!utf8_isvalid(name)) if (!utf8_isvalid(name))
return (0); return (0);
for (cp = name; *cp != '\0'; cp++) {
if (strchr(forbid, *cp) != NULL)
return (0);
}
return (1); return (1);
} }

12
tmux.h
View File

@@ -100,12 +100,6 @@ struct winlink;
#define TMUX_LOCK_CMD "lock -np" #define TMUX_LOCK_CMD "lock -np"
#endif #endif
/* Forbidden characters in names. */
#define WINDOW_NAME_FORBID ":."
#define WINDOW_NAME_FORBID_EXT ":.#"
#define SESSION_NAME_FORBID ":."
#define SESSION_NAME_FORBID_EXT ":.#"
/* Minimum and maximum layout cell size, NOT including border lines. */ /* Minimum and maximum layout cell size, NOT including border lines. */
#define PANE_MINIMUM 1 #define PANE_MINIMUM 1
#define PANE_MAXIMUM 10000 #define PANE_MAXIMUM 10000
@@ -2499,8 +2493,8 @@ int checkshell(const char *);
void setblocking(int, int); void setblocking(int, int);
char *shell_argv0(const char *, int); char *shell_argv0(const char *, int);
uint64_t get_timer(void); uint64_t get_timer(void);
char *clean_name(const char *, const char *); char *clean_name(const char *, int);
int check_name(const char *, const char *); int check_name(const char *);
const char *sig2name(int); const char *sig2name(int);
const char *find_cwd(void); const char *find_cwd(void);
const char *find_home(void); const char *find_home(void);
@@ -3621,7 +3615,7 @@ void window_pane_stack_push(struct window_panes *,
struct window_pane *); struct window_pane *);
void window_pane_stack_remove(struct window_panes *, void window_pane_stack_remove(struct window_panes *,
struct window_pane *); struct window_pane *);
void window_set_name(struct window *, const char *, const char *); void window_set_name(struct window *, const char *, int);
void window_add_ref(struct window *, const char *); void window_add_ref(struct window *, const char *);
void window_remove_ref(struct window *, const char *); void window_remove_ref(struct window *, const char *);
void winlink_clear_flags(struct winlink *); void winlink_clear_flags(struct winlink *);

View File

@@ -420,11 +420,11 @@ window_remove_ref(struct window *w, const char *from)
} }
void void
window_set_name(struct window *w, const char *new_name, const char *forbid) window_set_name(struct window *w, const char *new_name, int untrusted)
{ {
char *name; char *name;
name = clean_name(new_name, forbid); name = clean_name(new_name, untrusted);
if (name != NULL) { if (name != NULL) {
free(w->name); free(w->name);
w->name = name; w->name = name;