Nicks are unique by exact case but compared ignoring case #128

Closed
opened 2026-10-08 10:31:19 +02:00 by clawbot · 0 comments
Collaborator

README.md (Nick Semantics) rules that nicks are case-sensitive: "Alice and alice are different nicks", because case-insensitive comparison is "a perpetual source of IRC bugs". The database already follows it: sessions.nick is unique by exact case and every lookup is nick = ?. But some comparisons ignore case (strings.EqualFold):

  • the IRC listener's relay, internal/ircserver/relay.go (own-message checks in the PRIVMSG/NOTICE, JOIN, PART, NICK and QUIT delivery), so an IRC listener user alice never sees these from Alice;
  • user MODE on both transports, internal/ircserver/commands.go (handleUserMode) and internal/handlers/utility.go (handleUserMode), so MODE Alice from alice is treated as her own nick.

Found by the README review at #120 (comment).

Reading: the README decides this, so nicks compare by exact case everywhere. (An earlier version of this issue took the opposite reading; it contradicted the README and is withdrawn.)

Definition of done

  1. Every nick comparison in the code is exact: the five relay checks and both handleUserMode checks use ==; no nick comparison ignores case anywhere.
  2. Tests: an IRC listener user alice receives a PRIVMSG, JOIN, PART, NICK and QUIT from Alice in a shared channel; MODE Alice from alice gets 502 on both transports; Alice can register while alice exists.
  3. README.md: drop "Nick comparison is case-insensitive." (User modes bullet) and the "One gap remains" paragraph under Bridge to HTTP API; Nick Semantics stays as it is.
  4. One reviewed PR against next.

Judgement call: the 005 reply keeps CASEMAPPING=ascii. IRC defines no value for case-sensitive nicks, and a server that sends none is read as rfc1459, which also ignores case.

Model: opus-5-5

`README.md` (Nick Semantics) rules that nicks are case-sensitive: "`Alice` and `alice` are different nicks", because case-insensitive comparison is "a perpetual source of IRC bugs". The database already follows it: `sessions.nick` is unique by exact case and every lookup is `nick = ?`. But some comparisons ignore case (`strings.EqualFold`): - the IRC listener's relay, `internal/ircserver/relay.go` (own-message checks in the PRIVMSG/NOTICE, JOIN, PART, NICK and QUIT delivery), so an IRC listener user `alice` never sees these from `Alice`; - user `MODE` on both transports, `internal/ircserver/commands.go` (`handleUserMode`) and `internal/handlers/utility.go` (`handleUserMode`), so `MODE Alice` from `alice` is treated as her own nick. Found by the README review at https://git.eeqj.de/sneak/neoirc/pulls/120#issuecomment-133596. Reading: the README decides this, so nicks compare by exact case everywhere. (An earlier version of this issue took the opposite reading; it contradicted the README and is withdrawn.) ## Definition of done 1. Every nick comparison in the code is exact: the five relay checks and both `handleUserMode` checks use `==`; no nick comparison ignores case anywhere. 2. Tests: an IRC listener user `alice` receives a PRIVMSG, JOIN, PART, NICK and QUIT from `Alice` in a shared channel; `MODE Alice` from `alice` gets 502 on both transports; `Alice` can register while `alice` exists. 3. `README.md`: drop "Nick comparison is case-insensitive." (User modes bullet) and the "One gap remains" paragraph under Bridge to HTTP API; Nick Semantics stays as it is. 4. One reviewed PR against `next`. Judgement call: the `005` reply keeps `CASEMAPPING=ascii`. IRC defines no value for case-sensitive nicks, and a server that sends none is read as `rfc1459`, which also ignores case. Model: opus-5-5
clawbot self-assigned this 2026-10-08 10:31:19 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/neoirc#128