From c7fdb4656e025568013c9052759d74e89b5d8061 Mon Sep 17 00:00:00 2001 From: Daniel Oaks Date: Thu, 27 Oct 2016 00:44:36 +1000 Subject: [PATCH] strings: Use inbuilt precis.Nickname encoding now --- CHANGELOG.md | 1 + irc/client.go | 14 ++++++- irc/strings.go | 8 ++-- irc/strings_nickname.go | 89 ----------------------------------------- 4 files changed, 19 insertions(+), 93 deletions(-) delete mode 100644 irc/strings_nickname.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d8849b9..c447cef4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ New release of Oragono! ### Fixed * Fixed bug where `HELP` wouldn't correctly display for operators, and added more help topics. * Fixed display of large `MONITOR` lists. +* Fixed bug where you would always have certain capabilities enabled. ## [0.3.0] - 2016-10-23 diff --git a/irc/client.go b/irc/client.go index 4b099188..22963788 100644 --- a/irc/client.go +++ b/irc/client.go @@ -287,7 +287,19 @@ func (c *Client) ModeString() (str string) { // Friends refers to clients that share a channel with this client. func (client *Client) Friends(Capabilities ...Capability) ClientSet { friends := make(ClientSet) - friends.Add(client) + + // make sure that I have the right caps + hasCaps := true + for _, Cap := range Capabilities { + if !client.capabilities[Cap] { + hasCaps = false + break + } + } + if hasCaps { + friends.Add(client) + } + for channel := range client.channels { for member := range channel.members { // make sure they have all the required caps diff --git a/irc/strings.go b/irc/strings.go index 4e777a05..072bac18 100644 --- a/irc/strings.go +++ b/irc/strings.go @@ -8,6 +8,8 @@ package irc import ( "errors" "strings" + + "golang.org/x/text/secure/precis" ) var ( @@ -16,12 +18,12 @@ var ( // Casefold returns a casefolded string, without doing any name or channel character checks. func Casefold(str string) (string, error) { - return NicknameProfile.String(str) + return precis.Nickname.CompareKey(str) } // CasefoldChannel returns a casefolded version of a channel name. func CasefoldChannel(name string) (string, error) { - lowered, err := NicknameProfile.String(name) + lowered, err := precis.Nickname.CompareKey(name) if err != nil { return "", err @@ -45,7 +47,7 @@ func CasefoldChannel(name string) (string, error) { // CasefoldName returns a casefolded version of a nick/user name. func CasefoldName(name string) (string, error) { - lowered, err := NicknameProfile.String(name) + lowered, err := precis.Nickname.CompareKey(name) if err != nil { return "", err diff --git a/irc/strings_nickname.go b/irc/strings_nickname.go deleted file mode 100644 index a426fbe9..00000000 --- a/irc/strings_nickname.go +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//NOTE(dan): I need this because the default PRECIS API does not allow a way to retrieve the casefolded version of strings. -// See also: https://github.com/golang/go/issues/17386 - -// the content of this file is taken wholesale from the proper PRECIS API: -// https://github.com/golang/text/tree/master/secure/precis - -package irc - -import ( - "unicode" - "unicode/utf8" - - "golang.org/x/text/secure/precis" - "golang.org/x/text/transform" - "golang.org/x/text/unicode/norm" -) - -type nickAdditionalMapping struct { - // TODO: This transformer needs to be stateless somehow… - notStart bool - prevSpace bool -} - -func (t *nickAdditionalMapping) Reset() { - t.prevSpace = false - t.notStart = false -} - -func (t *nickAdditionalMapping) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { - // RFC 7700 §2.1. Rules - // - // 2. Additional Mapping Rule: The additional mapping rule consists of - // the following sub-rules. - // - // 1. Any instances of non-ASCII space MUST be mapped to ASCII - // space (U+0020); a non-ASCII space is any Unicode code point - // having a general category of "Zs", naturally with the - // exception of U+0020. - // - // 2. Any instances of the ASCII space character at the beginning - // or end of a nickname MUST be removed (e.g., "stpeter " is - // mapped to "stpeter"). - // - // 3. Interior sequences of more than one ASCII space character - // MUST be mapped to a single ASCII space character (e.g., - // "St Peter" is mapped to "St Peter"). - - for nSrc < len(src) { - r, size := utf8.DecodeRune(src[nSrc:]) - if size == 0 { // Incomplete UTF-8 encoding - if !atEOF { - return nDst, nSrc, transform.ErrShortSrc - } - size = 1 - } - if unicode.Is(unicode.Zs, r) { - t.prevSpace = true - } else { - if t.prevSpace && t.notStart { - dst[nDst] = ' ' - nDst += 1 - } - if size != copy(dst[nDst:], src[nSrc:nSrc+size]) { - nDst += size - return nDst, nSrc, transform.ErrShortDst - } - nDst += size - t.prevSpace = false - t.notStart = true - } - nSrc += size - } - return nDst, nSrc, nil -} - -var ( - NicknameProfile = precis.NewFreeform( - precis.AdditionalMapping(func() transform.Transformer { - return &nickAdditionalMapping{} - }), - precis.LowerCase(), - precis.Norm(norm.NFKC), - precis.DisallowEmpty, - ) -)