Forget emptied channels so a stale key can't leak to a recreated name
This commit is contained in:
parent
eea6e30f20
commit
0c85c5b569
1 changed files with 17 additions and 3 deletions
|
|
@ -341,11 +341,16 @@ impl Network {
|
||||||
}
|
}
|
||||||
self.users.remove(uid);
|
self.users.remove(uid);
|
||||||
self.accounts.remove(uid);
|
self.accounts.remove(uid);
|
||||||
for c in self.channels.values_mut() {
|
// Drop the membership, and forget any channel it emptied — an emptied
|
||||||
|
// channel is destroyed by the ircd, so a lingering entry would both grow
|
||||||
|
// unbounded over the process lifetime and hand stale modes (e.g. a `+k`
|
||||||
|
// key) to whoever recreates the name later.
|
||||||
|
self.channels.retain(|_, c| {
|
||||||
c.members.remove(uid);
|
c.members.remove(uid);
|
||||||
c.ops.remove(uid);
|
c.ops.remove(uid);
|
||||||
c.voices.remove(uid);
|
c.voices.remove(uid);
|
||||||
}
|
!c.members.is_empty()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nick_of(&self, uid: &str) -> Option<&str> {
|
pub fn nick_of(&self, uid: &str) -> Option<&str> {
|
||||||
|
|
@ -389,10 +394,19 @@ impl Network {
|
||||||
|
|
||||||
// A user left a channel (part/kick): drop membership and record last-seen.
|
// A user left a channel (part/kick): drop membership and record last-seen.
|
||||||
pub fn channel_part(&mut self, channel: &str, uid: &str) {
|
pub fn channel_part(&mut self, channel: &str, uid: &str) {
|
||||||
if let Some(c) = self.channels.get_mut(&lc(channel)) {
|
let key = lc(channel);
|
||||||
|
let emptied = if let Some(c) = self.channels.get_mut(&key) {
|
||||||
c.members.remove(uid);
|
c.members.remove(uid);
|
||||||
c.ops.remove(uid);
|
c.ops.remove(uid);
|
||||||
c.voices.remove(uid);
|
c.voices.remove(uid);
|
||||||
|
c.members.is_empty()
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
// An emptied channel is gone on the ircd; drop it so a later channel of
|
||||||
|
// the same name can't inherit its stale modes (see user_quit).
|
||||||
|
if emptied {
|
||||||
|
self.channels.remove(&key);
|
||||||
}
|
}
|
||||||
if let Some(nick) = self.nick_of(uid).map(str::to_string) {
|
if let Some(nick) = self.nick_of(uid).map(str::to_string) {
|
||||||
self.record_seen(lc(&nick), Seen { nick, ts: now(), what: format!("leaving {channel}") });
|
self.record_seen(lc(&nick), Seen { nick, ts: now(), what: format!("leaving {channel}") });
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue