Be more strict about what names and titles we allow and reject them

immediately when possible, but allow # again for those directly set by
commands (but not escape sequences). From Barrett Ruth in GitHub issue
5175.
This commit is contained in:
nicm
2026-06-15 21:41:39 +00:00
committed by Nicholas Marriott
parent 762e503978
commit 64e83caf04
17 changed files with 146 additions and 82 deletions

View File

@@ -77,8 +77,8 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
struct termios tio, *tiop;
struct session_group *sg = NULL;
const char *errstr, *template, *group, *tmp;
char *cause, *cwd = NULL, *cp, *newname = NULL;
char *name, *prefix = NULL;
char *cause, *cwd = NULL, *cp, *ename;
char *wname = NULL, *sname = NULL, *prefix = NULL;
int detached, already_attached, is_control = 0;
u_int sx, sy, dsx, dsy, count = args_count(args);
struct spawn_context sc = { 0 };
@@ -99,20 +99,29 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
return (CMD_RETURN_ERROR);
}
tmp = args_get(args, 's');
if (tmp != NULL) {
name = format_single(item, tmp, c, NULL, NULL, NULL);
newname = clean_name(name, "#:.");
if (newname == NULL) {
cmdq_error(item, "invalid session: %s", name);
free(name);
if ((tmp = args_get(args, 'n')) != NULL) {
ename = format_single(item, tmp, c, NULL, NULL, NULL);
if (!check_name(ename, WINDOW_NAME_FORBID)) {
cmdq_error(item, "invalid window name: %s", ename);
free(ename);
return (CMD_RETURN_ERROR);
}
free(name);
wname = clean_name(ename, WINDOW_NAME_FORBID);
free(ename);
}
if ((tmp = args_get(args, 's')) != NULL) {
ename = format_single(item, tmp, c, NULL, NULL, NULL);
if (!check_name(ename, SESSION_NAME_FORBID)) {
cmdq_error(item, "invalid session name: %s", ename);
free(ename);
goto fail;
}
sname = clean_name(ename, SESSION_NAME_FORBID);
free(ename);
}
if (args_has(args, 'A')) {
if (newname != NULL)
as = session_find(newname);
if (sname != NULL)
as = session_find(sname);
else
as = target->s;
if (as != NULL) {
@@ -120,12 +129,13 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
args_has(args, 'D'), args_has(args, 'X'), 0,
args_get(args, 'c'), args_has(args, 'E'),
args_get(args, 'f'));
free(newname);
free(wname);
free(sname);
return (retval);
}
}
if (newname != NULL && session_find(newname) != NULL) {
cmdq_error(item, "duplicate session: %s", newname);
if (sname != NULL && session_find(sname) != NULL) {
cmdq_error(item, "duplicate session: %s", sname);
goto fail;
}
@@ -142,12 +152,12 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
else if (groupwith != NULL)
prefix = xstrdup(groupwith->name);
else {
prefix = clean_name(group, "#:.");
if (prefix == NULL) {
cmdq_error(item, "invalid session group: %s",
group);
if (!check_name(group, SESSION_NAME_FORBID)) {
cmdq_error(item,
"invalid session group name: %s", group);
goto fail;
}
prefix = clean_name(group, SESSION_NAME_FORBID);
}
}
@@ -276,7 +286,7 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
environ_put(env, av->string, 0);
av = args_next_value(av);
}
s = session_create(prefix, newname, cwd, env, oo, tiop);
s = session_create(prefix, sname, cwd, env, oo, tiop);
/* Spawn the initial window. */
sc.item = item;
@@ -284,7 +294,7 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
if (!detached)
sc.tc = c;
sc.name = args_get(args, 'n');
sc.name = wname;
args_to_vector(args, &sc.argc, &sc.argv);
sc.idx = -1;
@@ -357,7 +367,8 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item)
if (sc.argv != NULL)
cmd_free_argv(sc.argc, sc.argv);
free(cwd);
free(newname);
free(wname);
free(sname);
free(prefix);
return (CMD_RETURN_NORMAL);
@@ -365,7 +376,8 @@ fail:
if (sc.argv != NULL)
cmd_free_argv(sc.argc, sc.argv);
free(cwd);
free(newname);
free(wname);
free(sname);
free(prefix);
return (CMD_RETURN_ERROR);
}