3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-12-22 18:52:41 +01:00
This commit is contained in:
Shivaram Lingamneni 2020-03-20 08:11:12 -04:00
parent 4eaef9f772
commit 2d908eac8b
3 changed files with 108 additions and 2 deletions

View File

@ -1113,7 +1113,7 @@ func (config *Config) generateISupport() (err error) {
isupport.Add("AWAYLEN", strconv.Itoa(config.Limits.AwayLen)) isupport.Add("AWAYLEN", strconv.Itoa(config.Limits.AwayLen))
isupport.Add("CASEMAPPING", "ascii") isupport.Add("CASEMAPPING", "ascii")
isupport.Add("CHANLIMIT", fmt.Sprintf("%s:%d", chanTypes, config.Channels.MaxChannelsPerClient)) isupport.Add("CHANLIMIT", fmt.Sprintf("%s:%d", chanTypes, config.Channels.MaxChannelsPerClient))
isupport.Add("CHANMODES", strings.Join([]string{modes.Modes{modes.BanMask, modes.ExceptMask, modes.InviteMask}.String(), "", modes.Modes{modes.UserLimit, modes.Key}.String(), modes.Modes{modes.InviteOnly, modes.Moderated, modes.NoOutside, modes.OpOnlyTopic, modes.ChanRoleplaying, modes.Secret, modes.NoCTCP, modes.RegisteredOnly}.String()}, ",")) isupport.Add("CHANMODES", strings.Join([]string{modes.Modes{modes.BanMask, modes.ExceptMask, modes.InviteMask}.String(), modes.Modes{modes.Key}.String(), modes.Modes{modes.UserLimit}.String(), modes.Modes{modes.InviteOnly, modes.Moderated, modes.NoOutside, modes.OpOnlyTopic, modes.ChanRoleplaying, modes.Secret, modes.NoCTCP, modes.RegisteredOnly}.String()}, ","))
if config.History.Enabled && config.History.ChathistoryMax > 0 { if config.History.Enabled && config.History.ChathistoryMax > 0 {
isupport.Add("draft/CHATHISTORY", strconv.Itoa(config.History.ChathistoryMax)) isupport.Add("draft/CHATHISTORY", strconv.Itoa(config.History.ChathistoryMax))
} }

View File

@ -281,7 +281,7 @@ func ParseChannelModeChanges(params ...string) (ModeChanges, map[rune]bool) {
} else { } else {
continue continue
} }
case Key, UserLimit: case UserLimit:
// don't require value when removing // don't require value when removing
if change.Op == Add { if change.Op == Add {
if len(params) > skipArgs { if len(params) > skipArgs {
@ -291,6 +291,23 @@ func ParseChannelModeChanges(params ...string) (ModeChanges, map[rune]bool) {
continue continue
} }
} }
case Key:
// #874: +k is technically a type B mode, requiring a parameter
// both for add and remove. so attempt to consume a parameter,
// but allow remove (but not add) even if no parameter is available.
// however, the remove parameter should always display as "*", matching
// the freenode behavior.
if len(params) > skipArgs {
if change.Op == Add {
change.Arg = params[skipArgs]
}
skipArgs++
} else if change.Op == Add {
continue
}
if change.Op == Remove {
change.Arg = "*"
}
} }
var isKnown bool var isKnown bool

View File

@ -8,6 +8,95 @@ import (
"testing" "testing"
) )
func assertEqual(supplied, expected interface{}, t *testing.T) {
if !reflect.DeepEqual(supplied, expected) {
t.Errorf("expected %v but got %v", expected, supplied)
}
}
func TestIssue874(t *testing.T) {
emptyUnknown := make(map[rune]bool)
modes, unknown := ParseChannelModeChanges("+k")
assertEqual(unknown, emptyUnknown, t)
assertEqual(modes, ModeChanges{}, t)
modes, unknown = ParseChannelModeChanges("+k", "beer")
assertEqual(unknown, emptyUnknown, t)
assertEqual(modes, ModeChanges{ModeChange{Op: Add, Mode: Key, Arg: "beer"}}, t)
modes, unknown = ParseChannelModeChanges("-k")
assertEqual(unknown, emptyUnknown, t)
assertEqual(modes, ModeChanges{ModeChange{Op: Remove, Mode: Key, Arg: "*"}}, t)
modes, unknown = ParseChannelModeChanges("-k", "beer")
assertEqual(unknown, emptyUnknown, t)
assertEqual(modes, ModeChanges{ModeChange{Op: Remove, Mode: Key, Arg: "*"}}, t)
modes, unknown = ParseChannelModeChanges("+kb", "beer")
assertEqual(unknown, emptyUnknown, t)
assertEqual(modes, ModeChanges{
ModeChange{Op: Add, Mode: Key, Arg: "beer"},
ModeChange{Op: List, Mode: BanMask, Arg: ""},
}, t)
modes, unknown = ParseChannelModeChanges("+kb", "beer")
assertEqual(unknown, emptyUnknown, t)
assertEqual(modes, ModeChanges{
ModeChange{Op: Add, Mode: Key, Arg: "beer"},
ModeChange{Op: List, Mode: BanMask, Arg: ""},
}, t)
modes, unknown = ParseChannelModeChanges("-kb", "beer")
assertEqual(unknown, emptyUnknown, t)
assertEqual(modes, ModeChanges{
ModeChange{Op: Remove, Mode: Key, Arg: "*"},
ModeChange{Op: List, Mode: BanMask, Arg: ""},
}, t)
// "beer" is the ban arg, +k with no arg should be ignored
modes, unknown = ParseChannelModeChanges("+bk", "beer")
assertEqual(unknown, emptyUnknown, t)
assertEqual(modes, ModeChanges{
ModeChange{Op: Add, Mode: BanMask, Arg: "beer"},
}, t)
// "beer" is the ban arg again
modes, unknown = ParseChannelModeChanges("-bk", "beer")
assertEqual(unknown, emptyUnknown, t)
assertEqual(modes, ModeChanges{
ModeChange{Op: Remove, Mode: BanMask, Arg: "beer"},
ModeChange{Op: Remove, Mode: Key, Arg: "*"},
}, t)
modes, unknown = ParseChannelModeChanges("+bk", "shivaram", "beer")
assertEqual(unknown, emptyUnknown, t)
assertEqual(modes, ModeChanges{
ModeChange{Op: Add, Mode: BanMask, Arg: "shivaram"},
ModeChange{Op: Add, Mode: Key, Arg: "beer"},
}, t)
modes, unknown = ParseChannelModeChanges("+kb", "beer", "shivaram")
assertEqual(unknown, emptyUnknown, t)
assertEqual(modes, ModeChanges{
ModeChange{Op: Add, Mode: Key, Arg: "beer"},
ModeChange{Op: Add, Mode: BanMask, Arg: "shivaram"},
}, t)
modes, unknown = ParseChannelModeChanges("-bk", "shivaram", "beer")
assertEqual(unknown, emptyUnknown, t)
assertEqual(modes, ModeChanges{
ModeChange{Op: Remove, Mode: BanMask, Arg: "shivaram"},
ModeChange{Op: Remove, Mode: Key, Arg: "*"},
}, t)
modes, unknown = ParseChannelModeChanges("-kb", "beer", "shivaram")
assertEqual(unknown, emptyUnknown, t)
assertEqual(modes, ModeChanges{
ModeChange{Op: Remove, Mode: Key, Arg: "*"},
ModeChange{Op: Remove, Mode: BanMask, Arg: "shivaram"},
}, t)
}
func TestParseChannelModeChanges(t *testing.T) { func TestParseChannelModeChanges(t *testing.T) {
modes, unknown := ParseChannelModeChanges("+h", "wrmsr") modes, unknown := ParseChannelModeChanges("+h", "wrmsr")
if len(unknown) > 0 { if len(unknown) > 0 {