From: Egor Date: Sun, 25 Jan 2026 01:00:18 +0000 (+0200) Subject: irc: tighten up nick validation X-Git-Url: https://git.patchysicp.xyz/?a=commitdiff_plain;h=299c7dc6ad5cfc1b277b85b06bc0e174cdddda1f;p=patchyircd.git irc: tighten up nick validation --- diff --git a/src/irc.cpp b/src/irc.cpp index a0b1ea8..69a3414 100644 --- a/src/irc.cpp +++ b/src/irc.cpp @@ -1321,33 +1321,36 @@ static void updateNuh(Client *client) { sprintf(client->nuh, "%s!%s@%s", n, u, h); stringlower(client->nuh); } +static bool is_nick_valid(std::string_view nickname) { + if (nickname.size() < 0 || nickname.size() >= MAX_NICKLEN) + return false; + if (nickname.find_first_of(" ,*?!@$:#&~%+."sv) != std::string_view::npos) + return false; + return true; +} void setNick(Client *client, char* nickname) { - // TODO: perform basic sanitization - size_t nicklen = strlen(nickname); - if (nicklen >= MAX_NICKLEN || nickname[0] == '\0') { + if (!is_nick_valid(std::string_view(nickname, nicklen))) { err_erroneusnickname(client, nickname), sendbuf(client); return; } - const char *forbidden = " ,*?!@$:#&."; - while (*forbidden) - if (strchr(nickname, *forbidden++)) { - err_erroneusnickname(client, nickname), sendbuf(client); - return; - } + + if (Client *other = client_map.iget(nickname); other) { + if (client != other) + err_nicknameinuse(client, nickname), sendbuf(client); + return; + } char key[MAX_NICKLEN]; memcpy(key, nickname, nicklen+1); stringlower(key); // TODO: make the cia nickname a define - if (Client *other = client_map.get(key); other || !strcmp(key, "cia")) { - if (client != other) - err_nicknameinuse(client, nickname), sendbuf(client); + if (strcmp(key, "cia") == 0) { + err_nicknameinuse(client, nickname), sendbuf(client); return; } - // Update nickname if (client->nick) { admin_hook("nickchange", client, 0, 0, key); msg_nick(client, nickname); @@ -1371,7 +1374,6 @@ void setNick(Client *client, char* nickname) { client->key = mystrdup(key); client_map.add(client); rpl_mononline(0, client), sendbuf_monitor(client->key, 0, 0, 0); - return; } /* changes username, hostname or both * NULL means no change. additionally username can be client->username+1