From e7f0aea682542d1feeb4566533b0b0ebe16bb96a Mon Sep 17 00:00:00 2001 From: Ed Kellett Date: Tue, 19 Oct 2021 13:30:03 +0100 Subject: [PATCH] m_list: Treat valid names with wildcards as masks * and ? are valid characters for channel names on IRC, and ELIST M gives no way to distinguish between `LIST #foo-*` that's meant to search for channels beginning `#foo-` and `LIST #foo-*` that's meant to list one channel named literally `#foo-*`. In order to deal with this, we will always assume a name with wildcards is a mask. If it's also a channel name, that will be listed first. --- modules/m_list.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/modules/m_list.c b/modules/m_list.c index 03d05f35..7216464e 100644 --- a/modules/m_list.c +++ b/modules/m_list.c @@ -191,7 +191,7 @@ mo_list(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_ } /* Single channel. */ - if (args && IsChannelName(args) && !strchr(args, ',')) + if (args && IsChannelName(args) && !strpbrk(args, "*?, ")) { safelist_channel_named(source_p, args, operspy); return; @@ -357,6 +357,8 @@ static bool safelist_sendq_exceeded(struct Client *client_p) */ static void safelist_client_instantiate(struct Client *client_p, struct ListClient *params) { + struct Channel *chptr; + s_assert(MyClient(client_p)); s_assert(params != NULL); @@ -368,6 +370,12 @@ static void safelist_client_instantiate(struct Client *client_p, struct ListClie rb_dlinkAddAlloc(client_p, &safelisting_clients); /* give the user some initial data to work with */ + if (params->mask && (chptr = find_channel(params->mask))) + { + bool visible = !SecretChannel(chptr) || IsMember(client_p, chptr); + if (visible || params->operspy) + list_one_channel(client_p, chptr, visible); + } safelist_iterate_client(client_p); } @@ -474,7 +482,7 @@ static void safelist_one_channel(struct Client *source_p, struct Channel *chptr, if (params->created_max && chptr->channelts > params->created_max) return; - if (params->mask && !match(params->mask, chptr->chname)) + if (params->mask && (!irccmp(params->mask, chptr->chname) || !match(params->mask, chptr->chname))) return; if (params->nomask && match(params->nomask, chptr->chname))