From 428137d8765f6aeb56503d8d37e3b1c9b33994ce Mon Sep 17 00:00:00 2001 From: nicm Date: Sat, 16 May 2020 14:49:50 +0000 Subject: Instead of forbidding invalid session names, sanitize them like window names. --- cmd-new-session.c | 35 ++++++++++++++--------------------- cmd-rename-session.c | 12 ++++-------- session.c | 19 ++++++++++++++----- 3 files changed, 32 insertions(+), 34 deletions(-) diff --git a/cmd-new-session.c b/cmd-new-session.c index 353f7bed..f08155c0 100644 --- a/cmd-new-session.c +++ b/cmd-new-session.c @@ -70,13 +70,14 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item) struct cmd_find_state *current = cmdq_get_current(item); struct cmd_find_state *target = cmdq_get_target(item); struct client *c = cmdq_get_client(item); - struct session *s, *as, *groupwith; + struct session *s, *as, *groupwith = NULL; struct environ *env; struct options *oo; struct termios tio, *tiop; - struct session_group *sg; - const char *errstr, *template, *group, *prefix, *tmp; + struct session_group *sg = NULL; + const char *errstr, *template, *group, *tmp; char *cause, *cwd = NULL, *cp, *newname = NULL; + char *name, *prefix = NULL; int detached, already_attached, is_control = 0; u_int sx, sy, dsx, dsy; struct spawn_context sc; @@ -98,11 +99,9 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item) tmp = args_get(args, 's'); if (tmp != NULL) { - newname = format_single(item, tmp, c, NULL, NULL, NULL); - if (!session_check_name(newname)) { - cmdq_error(item, "bad session name: %s", newname); - goto fail; - } + name = format_single(item, tmp, c, NULL, NULL, NULL); + newname = session_check_name(name); + free(name); } if (args_has(args, 'A')) { if (newname != NULL) @@ -126,24 +125,16 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item) group = args_get(args, 't'); if (group != NULL) { groupwith = target->s; - if (groupwith == NULL) { - if (!session_check_name(group)) { - cmdq_error(item, "bad group name: %s", group); - goto fail; - } + if (groupwith == NULL) sg = session_group_find(group); - } else + else sg = session_group_contains(groupwith); if (sg != NULL) - prefix = sg->name; + prefix = xstrdup(sg->name); else if (groupwith != NULL) - prefix = groupwith->name; + prefix = xstrdup(groupwith->name); else - prefix = group; - } else { - groupwith = NULL; - sg = NULL; - prefix = NULL; + prefix = session_check_name(group); } /* Set -d if no client. */ @@ -353,10 +344,12 @@ cmd_new_session_exec(struct cmd *self, struct cmdq_item *item) free(cwd); free(newname); + free(prefix); return (CMD_RETURN_NORMAL); fail: free(cwd); free(newname); + free(prefix); return (CMD_RETURN_ERROR); } diff --git a/cmd-rename-session.c b/cmd-rename-session.c index 4b2c3d88..51b8ffc8 100644 --- a/cmd-rename-session.c +++ b/cmd-rename-session.c @@ -49,19 +49,15 @@ cmd_rename_session_exec(struct cmd *self, struct cmdq_item *item) struct args *args = cmd_get_args(self); struct cmd_find_state *target = cmdq_get_target(item); struct session *s = target->s; - char *newname; + char *newname, *tmp; - newname = format_single_from_target(item, args->argv[0]); + tmp = format_single_from_target(item, args->argv[0]); + newname = session_check_name(tmp); + free(tmp); if (strcmp(newname, s->name) == 0) { free(newname); return (CMD_RETURN_NORMAL); } - - if (!session_check_name(newname)) { - cmdq_error(item, "bad session name: %s", newname); - free(newname); - return (CMD_RETURN_ERROR); - } if (session_find(newname) != NULL) { cmdq_error(item, "duplicate session: %s", newname); free(newname); diff --git a/session.c b/session.c index be9c8e07..93d50b47 100644 --- a/session.c +++ b/session.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "tmux.h" @@ -123,7 +124,6 @@ session_create(const char *prefix, const char *name, const char *cwd, s->cwd = xstrdup(cwd); - s->curw = NULL; TAILQ_INIT(&s->lastw); RB_INIT(&s->windows); @@ -142,7 +142,6 @@ session_create(const char *prefix, const char *name, const char *cwd, s->name = xstrdup(name); s->id = next_session_id++; } else { - s->name = NULL; do { s->id = next_session_id++; free(s->name); @@ -232,11 +231,20 @@ session_destroy(struct session *s, int notify, const char *from) session_remove_ref(s, __func__); } -/* Check a session name is valid: not empty and no colons or periods. */ -int +/* Sanitize session name. */ +char * session_check_name(const char *name) { - return (*name != '\0' && name[strcspn(name, ":.")] == '\0'); + char *copy, *cp, *new_name; + + copy = xstrdup(name); + for (cp = copy; *cp != '\0'; cp++) { + if (*cp == ':' || *cp == '.') + *cp = '_'; + } + utf8_stravis(&new_name, copy, VIS_OCTAL|VIS_CSTYLE|VIS_TAB|VIS_NL); + free(copy); + return (new_name); } /* Lock session if it has timed out. */ @@ -556,6 +564,7 @@ session_group_remove(struct session *s) TAILQ_REMOVE(&sg->sessions, s, gentry); if (TAILQ_EMPTY(&sg->sessions)) { RB_REMOVE(session_groups, &session_groups, sg); + free((void *)sg->name); free(sg); } } -- cgit v1.2.3