Skip to content

coretasks: bot.channels can learn about random channels from RPL_WHOREPLY #2679

@dgw

Description

@dgw

Accidentally submitted the initial issue with only a title… Gotta be careful with that gh CLI.

I was testing some tweaks to #2676 and noticed another little bug in WHO processing, different from #2675: Sopel can theoretically add a channel to bot.channels that it hasn't joined, if the server chooses an arbitrary non-secret channel to put in RPL_WHOREPLY instead of the * placeholder.

Since coretasks can't tell that a RPL_WHOREPLY was initiated by other code, it'll just add that channel to bot.channels—and then Sopel will start periodically sending WHOs for that channel via _periodic_send_who(). (The server might just send back an empty list for channels Sopel hasn't joined, but it still takes up an interval slot that could be used for a channel Sopel cares about.)

Additionally, I have raw logs of at least one IRC network sending back a non-common channel after Sopel sent WHO dgw (through the admin plugin's .raw command), despite being in a common channel. It isn't consistent, but it does happen:

# SopelTest is not joined to ##linux, but:
2025-06-10 18:57:41,232 >>      'WHO dgw\r\n'
2025-06-10 18:57:41,266 <<      ':irc.rizon.life 352 SopelTest ##linux dgw Portal.desu.yo * dgw Hr*&@ :0 dgw\r\n'
2025-06-10 18:57:41,268 <<      ':irc.rizon.life 315 SopelTest dgw :End of /WHO list.\r\n'

----

# debug check using sopel-ipython console
[2025-06-10 18:58:00,123] asyncio              DEBUG    - Using selector: EpollSelector
In [1]: bot.channels
Out[1]:
{Identifier('#my_test_channel'): <sopel.tools.target.Channel at 0x7f3567142da0>,
 Identifier('##linux'): <sopel.tools.target.Channel at 0x7f356706fbe0>}

Proposed solution

Sopel should not "learn" new channels from WHO or WHOX replies at all. It should ignore user privilege prefixes for channels that aren't already in bot.channels, and rely on track_join() to create the channel when Sopel itself joins a new channel.


This is slightly related to #2562, which is another case where RPL_WHOREPLY data doesn't match up with the actual state (in that case, because the IRCd may omit optional Flags from the response).

It's also related to the same IRC conversation with dyno10 last month that spawned #2675 re: the * placeholder; I just didn't dive far enough in at the time to find this edge case.

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugThings to squish; generally used for issuesCore/IRC Protocol HandlingNeeds TriageIssues that need to be reviewed and categorized

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions