diff --git a/irc/strings.go b/irc/strings.go index 2ccea99c..c5385853 100644 --- a/irc/strings.go +++ b/irc/strings.go @@ -39,18 +39,25 @@ func Casefold(str string) (string, error) { // CasefoldChannel returns a casefolded version of a channel name. func CasefoldChannel(name string) (string, error) { - lowered, err := Casefold(name) - - if err != nil { - return "", err - } else if len(lowered) == 0 { + if len(name) == 0 { return "", errStringIsEmpty } - if lowered[0] != '#' { + // don't casefold the preceding #'s + var start int + for start = 0; start < len(name) && name[start] == '#'; start += 1 { + } + + if start == 0 { + // no preceding #'s return "", errInvalidCharacter } + lowered, err := Casefold(name[start:]) + if err != nil { + return "", err + } + // space can't be used // , is used as a separator // * is used in mask matching @@ -59,7 +66,7 @@ func CasefoldChannel(name string) (string, error) { return "", errInvalidCharacter } - return lowered, err + return name[:start] + lowered, err } // CasefoldName returns a casefolded version of a nick/user name. diff --git a/irc/strings_test.go b/irc/strings_test.go index 7f23af83..513a4f8f 100644 --- a/irc/strings_test.go +++ b/irc/strings_test.go @@ -40,10 +40,21 @@ func TestCasefoldChannel(t *testing.T) { channel: "#", folded: "#", }, + { + channel: "#中文频道", + folded: "#中文频道", + }, + { + // Hebrew; it's up to the client to display this right-to-left, including the # + channel: "#שלום", + folded: "#שלום", + }, } for _, errCase := range []string{ "", "#*starpower", "# NASA", "#interro?", "OOF#", "foo", + // bidi violation mixing latin and hebrew characters: + "#shalomעליכם", } { testCases = append(testCases, channelTest{channel: errCase, err: true}) }