mirror of
https://github.com/jeremyd/ergo.git
synced 2026-07-08 17:38:11 -07:00
Merge remote-tracking branch 'origin/master' into listener_refactor.4
This commit is contained in:
+2
-2
@@ -53,7 +53,7 @@ const (
|
||||
// https://ircv3.net/specs/extensions/invite-notify-3.2.html
|
||||
InviteNotify Capability = iota
|
||||
|
||||
// LabeledResponse is the draft IRCv3 capability named "draft/labeled-response":
|
||||
// LabeledResponse is the draft IRCv3 capability named "draft/labeled-response-0.2":
|
||||
// https://ircv3.net/specs/extensions/labeled-response.html
|
||||
LabeledResponse Capability = iota
|
||||
|
||||
@@ -135,7 +135,7 @@ var (
|
||||
"echo-message",
|
||||
"extended-join",
|
||||
"invite-notify",
|
||||
"draft/labeled-response",
|
||||
"draft/labeled-response-0.2",
|
||||
"draft/languages",
|
||||
"oragono.io/maxline-2",
|
||||
"message-tags",
|
||||
|
||||
+11
-9
@@ -1160,12 +1160,7 @@ func (session *Session) sendFromClientInternal(blocking bool, serverTime time.Ti
|
||||
msg.SetTag("msgid", msgid)
|
||||
}
|
||||
// attach server-time
|
||||
if session.capabilities.Has(caps.ServerTime) {
|
||||
if serverTime.IsZero() {
|
||||
serverTime = time.Now().UTC()
|
||||
}
|
||||
msg.SetTag("time", serverTime.Format(IRCv3TimestampFormat))
|
||||
}
|
||||
session.setTimeTag(&msg, serverTime)
|
||||
|
||||
return session.SendRawMessage(msg, blocking)
|
||||
}
|
||||
@@ -1246,12 +1241,19 @@ func (client *Client) Send(tags map[string]string, prefix string, command string
|
||||
|
||||
func (session *Session) Send(tags map[string]string, prefix string, command string, params ...string) (err error) {
|
||||
msg := ircmsg.MakeMessage(tags, prefix, command, params...)
|
||||
if session.capabilities.Has(caps.ServerTime) && !msg.HasTag("time") {
|
||||
msg.SetTag("time", time.Now().UTC().Format(IRCv3TimestampFormat))
|
||||
}
|
||||
session.setTimeTag(&msg, time.Time{})
|
||||
return session.SendRawMessage(msg, false)
|
||||
}
|
||||
|
||||
func (session *Session) setTimeTag(msg *ircmsg.IrcMessage, serverTime time.Time) {
|
||||
if session.capabilities.Has(caps.ServerTime) && !msg.HasTag("time") {
|
||||
if serverTime.IsZero() {
|
||||
serverTime = time.Now()
|
||||
}
|
||||
msg.SetTag("time", serverTime.UTC().Format(IRCv3TimestampFormat))
|
||||
}
|
||||
}
|
||||
|
||||
// Notice sends the client a notice from the server.
|
||||
func (client *Client) Notice(text string) {
|
||||
client.Send(nil, client.server.name, "NOTICE", client.Nick(), text)
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ import "fmt"
|
||||
|
||||
const (
|
||||
// SemVer is the semantic version of Oragono.
|
||||
SemVer = "1.1.0-rc1"
|
||||
SemVer = "1.2.0-unreleased"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
+14
-12
@@ -93,9 +93,7 @@ func (rb *ResponseBuffer) AddFromClient(time time.Time, msgid string, fromNickMa
|
||||
msg.SetTag("msgid", msgid)
|
||||
}
|
||||
// attach server-time
|
||||
if rb.session.capabilities.Has(caps.ServerTime) && !msg.HasTag("time") {
|
||||
msg.SetTag("time", time.UTC().Format(IRCv3TimestampFormat))
|
||||
}
|
||||
rb.session.setTimeTag(&msg, time)
|
||||
|
||||
rb.AddMessage(msg)
|
||||
}
|
||||
@@ -212,24 +210,28 @@ func (rb *ResponseBuffer) flushInternal(final bool, blocking bool) error {
|
||||
}
|
||||
|
||||
useLabel := rb.session.capabilities.Has(caps.LabeledResponse) && rb.Label != ""
|
||||
// use a batch if we have a label, and we either currently have 0 or 2+ messages,
|
||||
// use a batch if we have a label, and we either currently have 2+ messages,
|
||||
// or we are doing a Flush() and we have to assume that there will be more messages
|
||||
// in the future.
|
||||
useBatch := useLabel && (len(rb.messages) != 1 || !final)
|
||||
startBatch := useLabel && (1 < len(rb.messages) || !final)
|
||||
|
||||
// if label but no batch, add label to first message
|
||||
if useLabel && !useBatch && len(rb.messages) == 1 && rb.batchID == "" {
|
||||
rb.messages[0].SetTag(caps.LabelTagName, rb.Label)
|
||||
} else if useBatch {
|
||||
if startBatch {
|
||||
rb.sendBatchStart(blocking)
|
||||
} else if useLabel && len(rb.messages) == 0 && rb.batchID == "" && final {
|
||||
// ACK message
|
||||
message := ircmsg.MakeMessage(nil, rb.session.client.server.name, "ACK")
|
||||
message.SetTag(caps.LabelTagName, rb.Label)
|
||||
rb.session.setTimeTag(&message, time.Time{})
|
||||
rb.session.SendRawMessage(message, blocking)
|
||||
} else if useLabel && len(rb.messages) == 1 && rb.batchID == "" && final {
|
||||
// single labeled message
|
||||
rb.messages[0].SetTag(caps.LabelTagName, rb.Label)
|
||||
}
|
||||
|
||||
// send each message out
|
||||
for _, message := range rb.messages {
|
||||
// attach server-time if needed
|
||||
if rb.session.capabilities.Has(caps.ServerTime) && !message.HasTag("time") {
|
||||
message.SetTag("time", time.Now().UTC().Format(IRCv3TimestampFormat))
|
||||
}
|
||||
rb.session.setTimeTag(&message, time.Time{})
|
||||
|
||||
// attach batch ID, unless this message was part of a nested batch and is
|
||||
// already tagged
|
||||
|
||||
+1
-23
@@ -108,26 +108,6 @@ func CasefoldName(name string) (string, error) {
|
||||
return lowered, err
|
||||
}
|
||||
|
||||
// "boring" names are exempt from skeletonization.
|
||||
// this is because confusables.txt considers various pure ASCII alphanumeric
|
||||
// strings confusable: 0 and O, 1 and l, m and rn. IMO this causes more problems
|
||||
// than it solves.
|
||||
func isBoring(name string) bool {
|
||||
for i := 0; i < len(name); i += 1 {
|
||||
chr := name[i]
|
||||
if (chr >= 'a' && chr <= 'z') || (chr >= 'A' && chr <= 'Z') || (chr >= '0' && chr <= '9') {
|
||||
continue // alphanumerics
|
||||
}
|
||||
switch chr {
|
||||
case '$', '%', '^', '&', '(', ')', '{', '}', '[', ']', '<', '>', '=':
|
||||
continue // benign printable ascii characters
|
||||
default:
|
||||
return false // potentially confusable ascii like | ' `, non-ascii
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// returns true if the given name is a valid ident, using a mix of Insp and
|
||||
// Chary's ident restrictions.
|
||||
func isIdent(name string) bool {
|
||||
@@ -168,9 +148,7 @@ func Skeleton(name string) (string, error) {
|
||||
// same as PRECIS:
|
||||
name = width.Fold.String(name)
|
||||
|
||||
if !isBoring(name) {
|
||||
name = confusables.Skeleton(name)
|
||||
}
|
||||
name = confusables.SkeletonTweaked(name)
|
||||
|
||||
// internationalized lowercasing for skeletons; this is much more lenient than
|
||||
// Casefold. In particular, skeletons are expected to mix scripts (which may
|
||||
|
||||
+7
-15
@@ -128,18 +128,6 @@ func TestCasefoldName(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsBoring(t *testing.T) {
|
||||
assertBoring := func(str string, expected bool) {
|
||||
if isBoring(str) != expected {
|
||||
t.Errorf("expected [%s] to have boringness [%t], but got [%t]", str, expected, !expected)
|
||||
}
|
||||
}
|
||||
|
||||
assertBoring("warning", true)
|
||||
assertBoring("phi|ip", false)
|
||||
assertBoring("Νικηφόρος", false)
|
||||
}
|
||||
|
||||
func TestIsIdent(t *testing.T) {
|
||||
assertIdent := func(str string, expected bool) {
|
||||
if isIdent(str) != expected {
|
||||
@@ -173,15 +161,15 @@ func TestSkeleton(t *testing.T) {
|
||||
t.Errorf("but we still consider pipe confusable with l")
|
||||
}
|
||||
|
||||
if skeleton("smt") != "smt" {
|
||||
if skeleton("smt") != skeleton("smt") {
|
||||
t.Errorf("fullwidth characters should skeletonize to plain old ascii characters")
|
||||
}
|
||||
|
||||
if skeleton("SMT") != "smt" {
|
||||
if skeleton("SMT") != skeleton("smt") {
|
||||
t.Errorf("after skeletonizing, we should casefold")
|
||||
}
|
||||
|
||||
if skeleton("smt") != "smt" {
|
||||
if skeleton("smt") != skeleton("smt") {
|
||||
t.Errorf("our friend lover successfully tricked the skeleton algorithm!")
|
||||
}
|
||||
|
||||
@@ -189,6 +177,10 @@ func TestSkeleton(t *testing.T) {
|
||||
t.Errorf("we must protect against cyrillic homoglyph attacks")
|
||||
}
|
||||
|
||||
if skeleton("еmily") != skeleton("emily") {
|
||||
t.Errorf("we must protect against cyrillic homoglyph attacks")
|
||||
}
|
||||
|
||||
if skeleton("РОТАТО") != "potato" {
|
||||
t.Errorf("we must protect against cyrillic homoglyph attacks")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user