From 97417f4c32c6cd893b74e1dcb2c9dcfdb549002d Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Sat, 11 Jul 2020 22:49:17 -0400 Subject: [PATCH 1/2] refactor WhoFields to use value receivers --- irc/client_test.go | 30 ++++++++++++++++++++++++++++++ irc/handlers.go | 30 ++++++++++++++++-------------- 2 files changed, 46 insertions(+), 14 deletions(-) diff --git a/irc/client_test.go b/irc/client_test.go index 7cfeaabf..2d1addc1 100644 --- a/irc/client_test.go +++ b/irc/client_test.go @@ -56,3 +56,33 @@ func TestUserMasks(t *testing.T) { t.Error("failure to match") } } + +func TestWhoFields(t *testing.T) { + var w whoxFields + + if w.Has('a') { + t.Error("zero value of whoxFields must be empty") + } + w = w.Add('a') + if !w.Has('a') { + t.Error("failed to set and get") + } + if w.Has('A') { + t.Error("false positive") + } + if w.Has('o') { + t.Error("false positive") + } + w = w.Add('🐬') + if w.Has('🐬') { + t.Error("should not be able to set invalid who field") + } + w = w.Add('o') + if !w.Has('o') { + t.Error("failed to set and get") + } + w = w.Add('z') + if !w.Has('z') { + t.Error("failed to set and get") + } +} diff --git a/irc/handlers.go b/irc/handlers.go index 8616ed3e..028565bf 100644 --- a/irc/handlers.go +++ b/irc/handlers.go @@ -2794,30 +2794,32 @@ func webircHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Re return true } -const WhoFieldMinimum = int('a') // lowest rune value -const WhoFieldMaximum = int('z') +type whoxFields uint32 // bitset to hold the WHOX field values, 'a' through 'z' -type WhoFields [WhoFieldMaximum - WhoFieldMinimum + 1]bool +func (fields whoxFields) Add(field rune) (result whoxFields) { + index := int(field) - int('a') + if 0 <= index && index < 26 { + return fields | (1 << index) + } else { + return fields + } +} -func (fields *WhoFields) Set(field rune) bool { - index := int(field) - if WhoFieldMinimum <= index && index <= WhoFieldMaximum { - fields[int(field)-WhoFieldMinimum] = true - return true +func (fields whoxFields) Has(field rune) bool { + index := int(field) - int('a') + if 0 <= index && index < 26 { + return (fields & (1 << index)) != 0 } else { return false } } -func (fields *WhoFields) Has(field rune) bool { - return fields[int(field)-WhoFieldMinimum] -} // rplWhoReply returns the WHO(X) reply between one user and another channel/user. // who format: // [*][~|&|@|%|+][B] : // whox format: // [*][~|&|@|%|+][B] : -func (client *Client) rplWhoReply(channel *Channel, target *Client, rb *ResponseBuffer, isWhox bool, fields WhoFields, whoType string) { +func (client *Client) rplWhoReply(channel *Channel, target *Client, rb *ResponseBuffer, isWhox bool, fields whoxFields, whoType string) { params := []string{client.Nick()} details := target.Details() @@ -2940,9 +2942,9 @@ func whoHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Respo sFields = strings.ToLower(sFields[:typeIndex]) } } - var fields WhoFields + var fields whoxFields for _, field := range sFields { - fields.Set(field) + fields = fields.Add(field) } //TODO(dan): is this used and would I put this param in the Modern doc? From a6d41109d03c77e73d23f88e6e090915f0ed38fc Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Sun, 12 Jul 2020 16:40:11 -0400 Subject: [PATCH 2/2] restore multiprefix support in RPL_WHOREPLY --- irc/handlers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/irc/handlers.go b/irc/handlers.go index 028565bf..31d469da 100644 --- a/irc/handlers.go +++ b/irc/handlers.go @@ -2867,7 +2867,7 @@ func (client *Client) rplWhoReply(channel *Channel, target *Client, rb *Response } if channel != nil { - flags.WriteString(channel.ClientPrefixes(target, false)) + flags.WriteString(channel.ClientPrefixes(target, rb.session.capabilities.Has(caps.MultiPrefix))) } if target.HasMode(modes.Bot) {