From 9eda8cbd4f8bda42aa16916f28d8af56d457b9cf Mon Sep 17 00:00:00 2001 From: reverse Date: Wed, 19 Aug 2026 04:45:07 +0000 Subject: [PATCH] =?UTF-8?q?server:=20carry=20accepted=5Fnicks=20count=20ac?= =?UTF-8?q?ross=20a=20nick=20change=20=E2=80=94=20set=5Fnick=20rewrites=20?= =?UTF-8?q?ACCEPT=20entries=20old->new=20in=20place=20(bypassing=20accept?= =?UTF-8?q?=5Fadd/remove)=20so=20the=20reverse=20count=20desynced;=20the?= =?UTF-8?q?=20count-gated=20quit=20scrub=20could=20then=20skip=20a=20reuse?= =?UTF-8?q?d=20nick,=20letting=20it=20inherit=20+g=20acceptance.=20move=20?= =?UTF-8?q?the=20count=20old->new=20(also=20fixes=20a=20slow=20map=20leak)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/users.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/users.rs b/src/users.rs index 7c1e20d..cf957dd 100644 --- a/src/users.rs +++ b/src/users.rs @@ -404,6 +404,13 @@ impl Server { } } } + // carry the accepted-nick reverse count across the rename (the number of + // acceptors doesn't change when the accepted user renames), so the + // count-gated quit scrub stays correct — otherwise a reused old nick could + // inherit acceptance and bypass +g, and the old-nick count would leak. + if let Some(c) = self.accepted_nicks.remove(&oldlow) { + *self.accepted_nicks.entry(newlow.clone()).or_insert(0) += c; + } } if registered { let line = format!(":{prefix} NICK :{newnick}");