3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-11-15 00:19:29 +01:00

don't send multiline responses to CAP LS 301 (#2068)

* don't send multiline responses to CAP LS 301

This is more or less explicitly prohibited by the spec:

https://ircv3.net/specs/extensions/capability-negotiation.html#multiline-replies-to-cap-ls-and-cap-list

* switch to whitelist model to be future-proof

* bump irctest to include test

* add a unit test
This commit is contained in:
Shivaram Lingamneni 2023-05-31 20:22:16 -07:00 committed by GitHub
parent 3e68694760
commit d082ec7ab9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 3 deletions

View File

@ -102,6 +102,13 @@ func (s *Set) Strings(version Version, values Values, maxLen int) (result []stri
var capab Capability var capab Capability
asSlice := s[:] asSlice := s[:]
for capab = 0; capab < numCapabs; capab++ { for capab = 0; capab < numCapabs; capab++ {
// XXX clients that only support CAP LS 301 cannot handle multiline
// responses. omit some CAPs in this case, forcing the response to fit on
// a single line. this is technically buggy for CAP LIST (as opposed to LS)
// but it shouldn't matter
if version < Cap302 && !isAllowed301(capab) {
continue
}
// skip any capabilities that are not enabled // skip any capabilities that are not enabled
if !utils.BitsetGet(asSlice, uint(capab)) { if !utils.BitsetGet(asSlice, uint(capab)) {
continue continue
@ -122,3 +129,15 @@ func (s *Set) Strings(version Version, values Values, maxLen int) (result []stri
} }
return return
} }
// this is a fixed whitelist of caps that are eligible for display in CAP LS 301
func isAllowed301(capab Capability) bool {
switch capab {
case AccountNotify, AccountTag, AwayNotify, Batch, ChgHost, Chathistory, EventPlayback,
Relaymsg, EchoMessage, Nope, ExtendedJoin, InviteNotify, LabeledResponse, MessageTags,
MultiPrefix, SASL, ServerTime, SetName, STS, UserhostInNames, ZNCSelfMessage, ZNCPlayback:
return true
default:
return false
}
}

View File

@ -3,8 +3,11 @@
package caps package caps
import "testing" import (
import "reflect" "fmt"
"reflect"
"testing"
)
func TestSets(t *testing.T) { func TestSets(t *testing.T) {
s1 := NewSet() s1 := NewSet()
@ -60,6 +63,19 @@ func TestSets(t *testing.T) {
} }
} }
func assertEqual(found, expected interface{}) {
if !reflect.DeepEqual(found, expected) {
panic(fmt.Sprintf("found %#v, expected %#v", found, expected))
}
}
func Test301WhitelistNotRespectedFor302(t *testing.T) {
s1 := NewSet()
s1.Enable(AccountTag, EchoMessage, StandardReplies)
assertEqual(s1.Strings(Cap301, nil, 0), []string{"account-tag echo-message"})
assertEqual(s1.Strings(Cap302, nil, 0), []string{"account-tag echo-message standard-replies"})
}
func TestSubtract(t *testing.T) { func TestSubtract(t *testing.T) {
s1 := NewSet(AccountTag, EchoMessage, UserhostInNames, ServerTime) s1 := NewSet(AccountTag, EchoMessage, UserhostInNames, ServerTime)

@ -1 +1 @@
Subproject commit bb8a6b6c3d3e55c1146c3c9f8224983d88a42b17 Subproject commit 22c6743b24f2a85bf79a92fb0c7fab325c047a6c