Skip to content

Commit

Permalink
fix #2113
Browse files Browse the repository at this point in the history
Persisting always-on clients was panicking if client X believed it was
a member of channel Y, but channel Y didn't have a record of client X.
  • Loading branch information
slingamn committed Jan 3, 2024
1 parent a4d160b commit 4aa1aa3
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 3 deletions.
7 changes: 5 additions & 2 deletions irc/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -545,11 +545,14 @@ func (channel *Channel) ClientStatus(client *Client) (present bool, joinTimeSecs

// helper for persisting channel-user modes for always-on clients;
// return the channel name and all channel-user modes for a client
func (channel *Channel) alwaysOnStatus(client *Client) (chname string, status alwaysOnChannelStatus) {
func (channel *Channel) alwaysOnStatus(client *Client) (ok bool, chname string, status alwaysOnChannelStatus) {
channel.stateMutex.RLock()
defer channel.stateMutex.RUnlock()
chname = channel.name
data := channel.members[client]
data, ok := channel.members[client]
if !ok {
return
}
status.Modes = data.modes.String()
status.JoinTime = data.joinTime
return
Expand Down
6 changes: 5 additions & 1 deletion irc/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -1803,7 +1803,11 @@ func (client *Client) performWrite(additionalDirtyBits uint) {
channels := client.Channels()
channelToModes := make(map[string]alwaysOnChannelStatus, len(channels))
for _, channel := range channels {
chname, status := channel.alwaysOnStatus(client)
ok, chname, status := channel.alwaysOnStatus(client)
if !ok {
client.server.logger.Error("internal", "client and channel membership out of sync", chname, client.Nick())
continue
}
channelToModes[chname] = status
}
client.server.accounts.saveChannels(account, channelToModes)
Expand Down

0 comments on commit 4aa1aa3

Please sign in to comment.