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.
This commit is contained in:
Ed Kellett 2021-10-19 13:30:03 +01:00
parent cbb9d48fa2
commit e7f0aea682

View file

@ -191,7 +191,7 @@ mo_list(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_
} }
/* Single channel. */ /* Single channel. */
if (args && IsChannelName(args) && !strchr(args, ',')) if (args && IsChannelName(args) && !strpbrk(args, "*?, "))
{ {
safelist_channel_named(source_p, args, operspy); safelist_channel_named(source_p, args, operspy);
return; 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) static void safelist_client_instantiate(struct Client *client_p, struct ListClient *params)
{ {
struct Channel *chptr;
s_assert(MyClient(client_p)); s_assert(MyClient(client_p));
s_assert(params != NULL); 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); rb_dlinkAddAlloc(client_p, &safelisting_clients);
/* give the user some initial data to work with */ /* 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); 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) if (params->created_max && chptr->channelts > params->created_max)
return; return;
if (params->mask && !match(params->mask, chptr->chname)) if (params->mask && (!irccmp(params->mask, chptr->chname) || !match(params->mask, chptr->chname)))
return; return;
if (params->nomask && match(params->nomask, chptr->chname)) if (params->nomask && match(params->nomask, chptr->chname))