# UNDF: UNDF-2026-000000340 --- a/src/plugins/irc/irc-channel.h +++ b/src/plugins/irc/irc-channel.h @@ -85,6 +85,7 @@ struct t_irc_channel struct t_irc_nick *nicks; /* nicks on channel */ int nicks_count; /* number of nicks on channel */ + struct t_hashtable *nicks_hashtable;/* nick_name(lower) → t_irc_nick* */ struct t_irc_nick *last_nick; /* last nick on channel */ --- a/src/plugins/irc/irc-nick.c +++ b/src/plugins/irc/irc-nick.c @@ -533,6 +533,14 @@ irc_nick_new_in_channel (struct t_irc_server *server, struct t_irc_channel *channel, ...) { + /* maintain hashtable for O(1) lookups */ + if (!channel->nicks_hashtable) + channel->nicks_hashtable = weechat_hashtable_new ( + 64, + WEECHAT_HASHTABLE_STRING, WEECHAT_HASHTABLE_POINTER, + NULL, NULL); + /* ... existing insertion code ... */ + if (channel->nicks_hashtable) + { + char lower[512]; + irc_server_casemap_lower (server, new_nick->name, lower, sizeof (lower)); + weechat_hashtable_set (channel->nicks_hashtable, lower, new_nick); + } } @@ -808,6 +808,11 @@ irc_nick_free (struct t_irc_server *server, struct t_irc_channel *channel, struct t_irc_nick *nick) { + /* remove from hashtable */ + if (channel->nicks_hashtable) + { + char lower[512]; + irc_server_casemap_lower (server, nick->name, lower, sizeof (lower)); + weechat_hashtable_remove (channel->nicks_hashtable, lower); + } /* ... existing removal code ... */ } @@ -830,12 +830,16 @@ irc_nick_search (struct t_irc_server *server, struct t_irc_channel *channel, const char *nickname) { - struct t_irc_nick *ptr_nick; - if (!channel || !nickname) return NULL; - for (ptr_nick = channel->nicks; ptr_nick; - ptr_nick = ptr_nick->next_nick) - { - if (irc_server_strcasecmp (server, ptr_nick->name, nickname) == 0) - return ptr_nick; - } - return NULL; + /* CWE-407 fix: O(1) hash lookup instead of O(n) linked-list scan */ + if (channel->nicks_hashtable) + { + char lower[512]; + irc_server_casemap_lower (server, nickname, lower, sizeof (lower)); + return (struct t_irc_nick *)weechat_hashtable_get ( + channel->nicks_hashtable, lower); + } + + /* fallback: hashtable not yet built (channel being initialised) */ + struct t_irc_nick *ptr_nick; + for (ptr_nick = channel->nicks; ptr_nick; ptr_nick = ptr_nick->next_nick) + if (irc_server_strcasecmp (server, ptr_nick->name, nickname) == 0) + return ptr_nick; + return NULL; }