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:
parent
3e68694760
commit
d082ec7ab9
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
2
irctest
2
irctest
@ -1 +1 @@
|
|||||||
Subproject commit bb8a6b6c3d3e55c1146c3c9f8224983d88a42b17
|
Subproject commit 22c6743b24f2a85bf79a92fb0c7fab325c047a6c
|
Loading…
Reference in New Issue
Block a user