]> PatchyGit - patchyircd.git/commitdiff
irc: tighten up nick validation
authorEgor <egor@patchysicp.xyz>
Sun, 25 Jan 2026 01:00:18 +0000 (03:00 +0200)
committerEgor <egor@patchysicp.xyz>
Sun, 25 Jan 2026 01:00:18 +0000 (03:00 +0200)
src/irc.cpp

index a0b1ea8..69a3414 100644 (file)
@@ -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