From 853bb12c29e2c48692e58bf793e36c6c3336639d Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Mon, 14 Dec 2020 08:24:38 -0500 Subject: [PATCH 1/2] fix #1449 INVITE playback (#1409) was buggy, due to the double use of (Item).Params[0] for the channel name and the recipient nick. Stuff the channel name in (Item).Message.Message instead. --- irc/channel.go | 3 +-- irc/client.go | 23 +++++++++++++++-------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/irc/channel.go b/irc/channel.go index e9773f46..23726fcc 100644 --- a/irc/channel.go +++ b/irc/channel.go @@ -1537,11 +1537,10 @@ func (channel *Channel) Invite(invitee *Client, inviter *Client, rb *ResponseBuf details := inviter.Details() tDetails := invitee.Details() tnick := invitee.Nick() - message := utils.MakeMessage("") + message := utils.MakeMessage(chname) item := history.Item{ Type: history.Invite, Message: message, - Params: [1]string{chname}, } for _, member := range channel.Members() { diff --git a/irc/client.go b/irc/client.go index 75c7b828..7896cece 100644 --- a/irc/client.go +++ b/irc/client.go @@ -1058,16 +1058,28 @@ func (client *Client) replayPrivmsgHistory(rb *ResponseBuffer, items []history.I } batchID = rb.StartNestedHistoryBatch(target) + isSelfMessage := func(item *history.Item) bool { + // XXX: Params[0] is the message target. if the source of this message is an in-memory + // buffer, then it's "" for an incoming message and the recipient's nick for an outgoing + // message. if the source of the message is mysql, then mysql only sees one copy of the + // message, and it's the version with the recipient's nick filled in. so this is an + // incoming message if Params[0] (the recipient's nick) equals the client's nick: + return item.Params[0] != "" && item.Params[0] != nick + } + hasEventPlayback := rb.session.capabilities.Has(caps.EventPlayback) hasTags := rb.session.capabilities.Has(caps.MessageTags) for _, item := range items { var command string switch item.Type { case history.Invite: + if isSelfMessage(&item) { + continue + } if hasEventPlayback { - rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, nil, "INVITE", item.Params[0]) + rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, nil, "INVITE", nick, item.Message.Message) } else { - rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histservService.prefix, "*", nil, "PRIVMSG", fmt.Sprintf(client.t("%[1]s invited you to channel %[2]s"), stripMaskFromNick(item.Nick), item.Params[0])) + rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histservService.prefix, "*", nil, "PRIVMSG", fmt.Sprintf(client.t("%[1]s invited you to channel %[2]s"), stripMaskFromNick(item.Nick), item.Message.Message)) } continue case history.Privmsg: @@ -1087,12 +1099,7 @@ func (client *Client) replayPrivmsgHistory(rb *ResponseBuffer, items []history.I if hasTags { tags = item.Tags } - // XXX: Params[0] is the message target. if the source of this message is an in-memory - // buffer, then it's "" for an incoming message and the recipient's nick for an outgoing - // message. if the source of the message is mysql, then mysql only sees one copy of the - // message, and it's the version with the recipient's nick filled in. so this is an - // incoming message if Params[0] (the recipient's nick) equals the client's nick: - if item.Params[0] == "" || item.Params[0] == nick { + if !isSelfMessage(&item) { rb.AddSplitMessageFromClient(item.Nick, item.AccountName, tags, command, nick, item.Message) } else { // this message was sent *from* the client to another nick; the target is item.Params[0] From 15a0cda78b169e1e27eb51596d919d994707a4b3 Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Mon, 14 Dec 2020 15:23:01 -0500 Subject: [PATCH 2/2] pointless refactor of stripMaskFromNick --- irc/channel.go | 10 +--------- irc/client.go | 4 ++-- irc/histserv.go | 2 +- irc/strings.go | 8 ++++++++ 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/irc/channel.go b/irc/channel.go index 23726fcc..8a68f136 100644 --- a/irc/channel.go +++ b/irc/channel.go @@ -1073,14 +1073,6 @@ func (channel *Channel) replayHistoryForResume(session *Session, after time.Time rb.Send(true) } -func stripMaskFromNick(nickMask string) (nick string) { - index := strings.Index(nickMask, "!") - if index == -1 { - return nickMask - } - return nickMask[0:index] -} - func (channel *Channel) replayHistoryItems(rb *ResponseBuffer, items []history.Item, autoreplay bool) { // send an empty batch if necessary, as per the CHATHISTORY spec chname := channel.Name() @@ -1103,7 +1095,7 @@ func (channel *Channel) replayHistoryItems(rb *ResponseBuffer, items []history.I defer rb.EndNestedBatch(batchID) for _, item := range items { - nick := stripMaskFromNick(item.Nick) + nick := NUHToNick(item.Nick) switch item.Type { case history.Privmsg: rb.AddSplitMessageFromClient(item.Nick, item.AccountName, item.Tags, "PRIVMSG", chname, item.Message) diff --git a/irc/client.go b/irc/client.go index 7896cece..8640ecdc 100644 --- a/irc/client.go +++ b/irc/client.go @@ -975,7 +975,7 @@ func (session *Session) playResume() { if privmsgSeq != nil { privmsgs, _, _ := privmsgSeq.Between(history.Selector{}, history.Selector{}, config.History.ClientLength) for _, item := range privmsgs { - sender := server.clients.Get(stripMaskFromNick(item.Nick)) + sender := server.clients.Get(NUHToNick(item.Nick)) if sender != nil { friends.Add(sender) } @@ -1079,7 +1079,7 @@ func (client *Client) replayPrivmsgHistory(rb *ResponseBuffer, items []history.I if hasEventPlayback { rb.AddFromClient(item.Message.Time, item.Message.Msgid, item.Nick, item.AccountName, nil, "INVITE", nick, item.Message.Message) } else { - rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histservService.prefix, "*", nil, "PRIVMSG", fmt.Sprintf(client.t("%[1]s invited you to channel %[2]s"), stripMaskFromNick(item.Nick), item.Message.Message)) + rb.AddFromClient(item.Message.Time, utils.MungeSecretToken(item.Message.Msgid), histservService.prefix, "*", nil, "PRIVMSG", fmt.Sprintf(client.t("%[1]s invited you to channel %[2]s"), NUHToNick(item.Nick), item.Message.Message)) } continue case history.Privmsg: diff --git a/irc/histserv.go b/irc/histserv.go index b5aadc5a..4c686737 100644 --- a/irc/histserv.go +++ b/irc/histserv.go @@ -173,7 +173,7 @@ func histservPlayHandler(service *ircService, server *Server, client *Client, co } playMessage := func(timestamp time.Time, nick, message string) { - service.Notice(rb, fmt.Sprintf("%s <%s> %s", timestamp.Format("15:04:05"), stripMaskFromNick(nick), message)) + service.Notice(rb, fmt.Sprintf("%s <%s> %s", timestamp.Format("15:04:05"), NUHToNick(nick), message)) } for _, item := range items { diff --git a/irc/strings.go b/irc/strings.go index c59f1bed..48bca280 100644 --- a/irc/strings.go +++ b/irc/strings.go @@ -308,3 +308,11 @@ func foldPermissive(str string) (result string, err error) { str = norm.NFD.String(str) return str, nil } + +// Reduce, e.g., `alice!~u@host` to `alice` +func NUHToNick(nuh string) (nick string) { + if idx := strings.IndexByte(nuh, '!'); idx != -1 { + return nuh[0:idx] + } + return nuh +}