Skip to content

Commit

Permalink
fix handleTOPIC only supporting modern RPL_TOPIC (#72)
Browse files Browse the repository at this point in the history
handleTOPIC was using the wrong event parameters when a TOPIC message
or (old) RPL_TOPIC was received, it only handles (new) RPL_TOPIC messages
correctly.

TOPIC messages are defined as `TOPIC <channel> [:<topic>]` in both specs
while RPL_TOPIC differs between RFC1459/RFC2812 and "Modern IRC" such that
they are respectively defined as `RPC_TOPIC <channel> :<topic>` and
`RPL_TOPIC <client> <channel> :<topic>`.

The old code only correctly parsed the "Modern IRC" RPL_TOPIC variant and
not the (old) RPL_TOPIC or TOPIC events, these were instead silently never
used in state tracking of the channel topic.
  • Loading branch information
Wessie authored Feb 10, 2025
1 parent 0c03e8d commit 6320efd
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 5 deletions.
13 changes: 9 additions & 4 deletions builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,14 +223,19 @@ func handlePART(c *Client, e Event) {
// handleTOPIC handles incoming TOPIC events and keeps channel tracking info
// updated with the latest channel topic.
func handleTOPIC(c *Client, e Event) {
var name string
var name, topic string
switch len(e.Params) {
case 0:
return
case 1:
case 1: // TOPIC, message format is `TOPIC <channel>`
name = e.Params[0]
default:
topic = ""
case 2: // TOPIC, message format is `TOPIC <channel> :<topic>`
name = e.Params[0]
topic = e.Last()
default: // RPL_TOPIC, message format is `332 <client> <channel> :<topic>`
name = e.Params[1]
topic = e.Last()
}

c.state.Lock()
Expand All @@ -240,7 +245,7 @@ func handleTOPIC(c *Client, e Event) {
return
}

channel.Topic = e.Last()
channel.Topic = topic
c.state.Unlock()
c.state.notify(c, UPDATE_STATE)
}
Expand Down
7 changes: 6 additions & 1 deletion state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,13 @@ const mockConnStartState = `:dummy.int NOTICE * :*** Looking up your hostname...
:dummy.int 354 nick 1 #channel nick2 other.int nick2 nick2 :realname2
:dummy.int 315 nick #channel :End of /WHO list.
:[email protected] JOIN #channel2 * :realname
:dummy.int 332 nick #channel2 :example topic
:dummy.int 332 nick #channel2 :example init topic
:dummy.int 353 nick = #channel2 :[email protected] @[email protected]
:dummy.int 366 nick #channel2 :End of /NAMES list.
:dummy.int 354 nick 1 #channel2 ~user local.int nick 0 :realname
:dummy.int 354 nick 1 #channel2 nick2 other.int nick2 nick2 :realname2
:dummy.int 315 nick #channel2 :End of /WHO list.
:dummy.int TOPIC #channel2 :example topic
`

const mockConnEndState = `:[email protected] QUIT :example reason
Expand Down Expand Up @@ -190,6 +191,10 @@ func TestState(t *testing.T) {
t.Fatal("User.InChannel() returned false for existing channel")
}

if ch2 := c.LookupChannel("#channel2"); ch2.Topic != "example topic" {
t.Fatalf("Channel.Topic == %q, want \"example topic\"", ch2.Topic)
}

finishStart <- true
})

Expand Down

0 comments on commit 6320efd

Please sign in to comment.