3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-11-29 15:40:02 +01:00

Merge pull request #1009 from slingamn/issue1005_multiline_blanks

fix #1005
This commit is contained in:
Shivaram Lingamneni 2020-05-15 05:07:29 -07:00 committed by GitHub
commit ade87463c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 28 deletions

View File

@ -146,6 +146,7 @@ type MultilineBatch struct {
target string target string
responseLabel string // this is the value of the labeled-response tag sent with BATCH responseLabel string // this is the value of the labeled-response tag sent with BATCH
message utils.SplitMessage message utils.SplitMessage
lenBytes int
tags map[string]string tags map[string]string
} }
@ -168,14 +169,14 @@ func (s *Session) EndMultilineBatch(label string) (batch MultilineBatch, err err
s.fakelag.Unsuspend() s.fakelag.Unsuspend()
// heuristics to estimate how much data they used while fakelag was suspended // heuristics to estimate how much data they used while fakelag was suspended
fakelagBill := (batch.message.LenBytes() / 512) + 1 fakelagBill := (batch.lenBytes / 512) + 1
fakelagBillLines := (batch.message.LenLines() * 60) / 512 fakelagBillLines := (batch.message.LenLines() * 60) / 512
if fakelagBill < fakelagBillLines { if fakelagBill < fakelagBillLines {
fakelagBill = fakelagBillLines fakelagBill = fakelagBillLines
} }
s.deferredFakelagCount = fakelagBill s.deferredFakelagCount = fakelagBill
if batch.label == "" || batch.label != label || batch.message.LenLines() == 0 { if batch.label == "" || batch.label != label || !batch.message.ValidMultiline() {
err = errInvalidMultilineBatch err = errInvalidMultilineBatch
return return
} }
@ -1357,9 +1358,14 @@ func (session *Session) sendSplitMsgFromClientInternal(blocking bool, nickmask,
session.SendRawMessage(msg, blocking) session.SendRawMessage(msg, blocking)
} }
} else { } else {
for i, messagePair := range message.Split { msgidSent := false // send msgid on the first nonblank line
for _, messagePair := range message.Split {
if len(messagePair.Message) == 0 {
continue
}
var msgid string var msgid string
if i == 0 { if !msgidSent {
msgidSent = true
msgid = message.Msgid msgid = message.Msgid
} }
session.sendFromClientInternal(blocking, message.Time, msgid, nickmask, accountName, tags, command, target, messagePair.Message) session.sendFromClientInternal(blocking, message.Time, msgid, nickmask, accountName, tags, command, target, messagePair.Message)

View File

@ -1793,33 +1793,39 @@ func nickHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Resp
// helper to store a batched PRIVMSG in the session object // helper to store a batched PRIVMSG in the session object
func absorbBatchedMessage(server *Server, client *Client, msg ircmsg.IrcMessage, batchTag string, histType history.ItemType, rb *ResponseBuffer) { func absorbBatchedMessage(server *Server, client *Client, msg ircmsg.IrcMessage, batchTag string, histType history.ItemType, rb *ResponseBuffer) {
var errorCode, errorMessage string
defer func() {
if errorCode != "" {
if histType != history.Notice {
rb.Add(nil, server.name, "FAIL", "BATCH", errorCode, errorMessage)
}
rb.session.EndMultilineBatch("")
}
}()
if batchTag != rb.session.batch.label { if batchTag != rb.session.batch.label {
if histType != history.Notice { errorCode, errorMessage = "MULTILINE_INVALID", client.t("Incorrect batch tag sent")
rb.Add(nil, server.name, "FAIL", "BATCH", "MULTILINE_INVALID", client.t("Incorrect batch tag sent"))
}
rb.session.EndMultilineBatch("")
return return
} else if len(msg.Params) < 2 || msg.Params[1] == "" { } else if len(msg.Params) < 2 {
if histType != history.Notice { errorCode, errorMessage = "MULTILINE_INVALID", client.t("Invalid multiline batch")
rb.Add(nil, server.name, "FAIL", "BATCH", "MULTILINE_INVALID", client.t("Invalid multiline batch"))
}
rb.session.EndMultilineBatch("")
return return
} }
rb.session.batch.command = msg.Command rb.session.batch.command = msg.Command
isConcat, _ := msg.GetTag(caps.MultilineConcatTag) isConcat, _ := msg.GetTag(caps.MultilineConcatTag)
if isConcat && len(msg.Params[1]) == 0 {
errorCode, errorMessage = "MULTILINE_INVALID", client.t("Cannot send a blank line with the multiline concat tag")
return
}
if !isConcat && len(rb.session.batch.message.Split) != 0 {
rb.session.batch.lenBytes++ // bill for the newline
}
rb.session.batch.message.Append(msg.Params[1], isConcat) rb.session.batch.message.Append(msg.Params[1], isConcat)
rb.session.batch.lenBytes += len(msg.Params[1])
config := server.Config() config := server.Config()
if config.Limits.Multiline.MaxBytes < rb.session.batch.message.LenBytes() { if config.Limits.Multiline.MaxBytes < rb.session.batch.lenBytes {
if histType != history.Notice { errorCode, errorMessage = "MULTILINE_MAX_BYTES", strconv.Itoa(config.Limits.Multiline.MaxBytes)
rb.Add(nil, server.name, "FAIL", "BATCH", "MULTILINE_MAX_BYTES", strconv.Itoa(config.Limits.Multiline.MaxBytes))
}
rb.session.EndMultilineBatch("")
} else if config.Limits.Multiline.MaxLines != 0 && config.Limits.Multiline.MaxLines < rb.session.batch.message.LenLines() { } else if config.Limits.Multiline.MaxLines != 0 && config.Limits.Multiline.MaxLines < rb.session.batch.message.LenLines() {
if histType != history.Notice { errorCode, errorMessage = "MULTILINE_MAX_LINES", strconv.Itoa(config.Limits.Multiline.MaxLines)
rb.Add(nil, server.name, "FAIL", "BATCH", "MULTILINE_MAX_LINES", strconv.Itoa(config.Limits.Multiline.MaxLines))
}
rb.session.EndMultilineBatch("")
} }
} }

View File

@ -67,14 +67,14 @@ func (sm *SplitMessage) LenLines() int {
return len(sm.Split) return len(sm.Split)
} }
func (sm *SplitMessage) LenBytes() (result int) { func (sm *SplitMessage) ValidMultiline() bool {
if sm.Split == nil { // must contain at least one nonblank line
return len(sm.Message)
}
for i := 0; i < len(sm.Split); i++ { for i := 0; i < len(sm.Split); i++ {
result += len(sm.Split[i].Message) if len(sm.Split[i].Message) != 0 {
return true
}
} }
return return false
} }
func (sm *SplitMessage) IsRestrictedCTCPMessage() bool { func (sm *SplitMessage) IsRestrictedCTCPMessage() bool {