From 7c4d016fcb250a7f2cfa5d9e4933c6e9d5f852c4 Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Sun, 27 Dec 2020 20:17:24 -0500 Subject: [PATCH 1/2] fix incorrect sprintf-before-unescape --- irc/server.go | 2 +- irc/services.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/irc/server.go b/irc/server.go index 695c81a3..eed41a3e 100644 --- a/irc/server.go +++ b/irc/server.go @@ -488,7 +488,7 @@ func (client *Client) getWhoisOf(target *Client, hasPrivs bool, rb *ResponseBuff rb.Add(nil, client.server.name, RPL_WHOISACCOUNT, cnick, tnick, targetInfo.accountName, client.t("is logged in as")) } if target.HasMode(modes.Bot) { - rb.Add(nil, client.server.name, RPL_WHOISBOT, cnick, tnick, ircfmt.Unescape(fmt.Sprintf(client.t("is a $bBot$b on %s"), client.server.Config().Network.Name))) + rb.Add(nil, client.server.name, RPL_WHOISBOT, cnick, tnick, fmt.Sprintf(ircfmt.Unescape(client.t("is a $bBot$b on %s")), client.server.Config().Network.Name)) } if client == target || hasPrivs { diff --git a/irc/services.go b/irc/services.go index c4451c34..5dc20077 100644 --- a/irc/services.go +++ b/irc/services.go @@ -235,14 +235,14 @@ func serviceHelpHandler(service *ircService, server *Server, client *Client, par rb.Add(nil, service.prefix, "NOTICE", nick, notice) } - sendNotice(ircfmt.Unescape(fmt.Sprintf("*** $b%s HELP$b ***", service.Name))) + sendNotice(fmt.Sprintf(ircfmt.Unescape("*** $b%s HELP$b ***"), service.Name)) if len(params) == 0 { helpBannerLines := strings.Split(client.t(service.HelpBanner), "\n") helpBannerLines = append(helpBannerLines, []string{ "", client.t("To see in-depth help for a specific command, try:"), - ircfmt.Unescape(fmt.Sprintf(client.t(" $b/msg %s HELP $b"), service.Name)), + fmt.Sprintf(ircfmt.Unescape(client.t(" $b/msg %s HELP $b")), service.Name), "", client.t("Here are the commands you can use:"), }...) @@ -262,7 +262,7 @@ func serviceHelpHandler(service *ircService, server *Server, client *Client, par continue } - shownHelpLines = append(shownHelpLines, ircfmt.Unescape(" "+client.t(commandInfo.helpShort))) + shownHelpLines = append(shownHelpLines, " "+ircfmt.Unescape(client.t(commandInfo.helpShort))) } if disabledCommands { @@ -301,7 +301,7 @@ func serviceHelpHandler(service *ircService, server *Server, client *Client, par } } - sendNotice(ircfmt.Unescape(fmt.Sprintf(client.t("*** $bEnd of %s HELP$b ***"), service.Name))) + sendNotice(fmt.Sprintf(ircfmt.Unescape(client.t("*** $bEnd of %s HELP$b ***")), service.Name)) } func makeServiceHelpTextGenerator(cmd string, banner string) func(*Client) string { From 4f3b005d18ce8a5e927f292b240825aa91303c76 Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Sun, 27 Dec 2020 20:18:29 -0500 Subject: [PATCH 2/2] bump ircfmt --- go.mod | 2 +- go.sum | 2 + .../goshuirc/irc-go/ircfmt/ircfmt.go | 157 ++++++++---------- vendor/modules.txt | 2 +- 4 files changed, 76 insertions(+), 87 deletions(-) diff --git a/go.mod b/go.mod index d7138a24..c103c7f2 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/go-sql-driver/mysql v1.5.0 github.com/go-test/deep v1.0.6 // indirect github.com/gorilla/websocket v1.4.2 - github.com/goshuirc/irc-go v0.0.0-20201118022549-7209d10d54a8 + github.com/goshuirc/irc-go v0.0.0-20201228002532-4e36cb3f41f1 github.com/onsi/ginkgo v1.12.0 // indirect github.com/onsi/gomega v1.9.0 // indirect github.com/oragono/confusables v0.0.0-20201108231250-4ab98ab61fb1 diff --git a/go.sum b/go.sum index 0aa4623c..5735425a 100644 --- a/go.sum +++ b/go.sum @@ -24,6 +24,8 @@ github.com/goshuirc/irc-go v0.0.0-20201116034710-7e7b0985c4b5 h1:oqOT5hi8MRDGvfu github.com/goshuirc/irc-go v0.0.0-20201116034710-7e7b0985c4b5/go.mod h1:q/JhvvKLmif3y9q8MDQM+gRCnjEKnu5ClF298TTXJug= github.com/goshuirc/irc-go v0.0.0-20201118022549-7209d10d54a8 h1:7vZqkY9bwimFNuLhWAzdxM9IM7ym853YLNhWsKAnsrQ= github.com/goshuirc/irc-go v0.0.0-20201118022549-7209d10d54a8/go.mod h1:q/JhvvKLmif3y9q8MDQM+gRCnjEKnu5ClF298TTXJug= +github.com/goshuirc/irc-go v0.0.0-20201228002532-4e36cb3f41f1 h1:Kyyey3K8nhx60lt4xish6NzLqButwqAwDb62UOU3GbE= +github.com/goshuirc/irc-go v0.0.0-20201228002532-4e36cb3f41f1/go.mod h1:q/JhvvKLmif3y9q8MDQM+gRCnjEKnu5ClF298TTXJug= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= diff --git a/vendor/github.com/goshuirc/irc-go/ircfmt/ircfmt.go b/vendor/github.com/goshuirc/irc-go/ircfmt/ircfmt.go index 4cc78ce4..e18c57bc 100644 --- a/vendor/github.com/goshuirc/irc-go/ircfmt/ircfmt.go +++ b/vendor/github.com/goshuirc/irc-go/ircfmt/ircfmt.go @@ -4,6 +4,7 @@ package ircfmt import ( + "regexp" "strings" ) @@ -81,26 +82,6 @@ var ( "0": "white", } - // full and truncated colour codes - colourcodesFull = map[string]string{ - "white": "00", - "black": "01", - "blue": "02", - "green": "03", - "red": "04", - "brown": "05", - "magenta": "06", - "orange": "07", - "yellow": "08", - "light green": "09", - "cyan": "10", - "light cyan": "11", - "light blue": "12", - "pink": "13", - "grey": "14", - "light grey": "15", - "default": "99", - } colourcodesTruncated = map[string]string{ "white": "0", "black": "1", @@ -120,6 +101,9 @@ var ( "light grey": "15", "default": "99", } + + bracketedExpr = regexp.MustCompile(`^\[.*\]`) + colourDigits = regexp.MustCompile(`^[0-9]{1,2}$`) ) // Escape takes a raw IRC string and returns it with our escapes. @@ -242,87 +226,90 @@ func removeColour(runes []rune) []rune { return runes } +// resolve "light blue" to "12", "12" to "12", "asdf" to "", etc. +func resolveToColourCode(str string) (result string) { + str = strings.ToLower(strings.TrimSpace(str)) + if colourDigits.MatchString(str) { + return str + } + return colourcodesTruncated[str] +} + +// resolve "[light blue, black]" to ("13, "1") +func resolveToColourCodes(namedColors string) (foreground, background string) { + // cut off the brackets + namedColors = strings.TrimPrefix(namedColors, "[") + namedColors = strings.TrimSuffix(namedColors, "]") + + var foregroundStr, backgroundStr string + commaIdx := strings.IndexByte(namedColors, ',') + if commaIdx != -1 { + foregroundStr = namedColors[:commaIdx] + backgroundStr = namedColors[commaIdx+1:] + } else { + foregroundStr = namedColors + } + + return resolveToColourCode(foregroundStr), resolveToColourCode(backgroundStr) +} + // Unescape takes our escaped string and returns a raw IRC string. // // IE, it turns this: "This is a $bcool$b, $c[red]red$r message!" // into this: "This is a \x02cool\x02, \x034red\x0f message!" func Unescape(in string) string { - out := strings.Builder{} + var out strings.Builder - remaining := []rune(in) - for 0 < len(remaining) { + remaining := in + for len(remaining) != 0 { char := remaining[0] remaining = remaining[1:] - if char == '$' && 0 < len(remaining) { - char = remaining[0] - remaining = remaining[1:] + if char != '$' || len(remaining) == 0 { + // not an escape + out.WriteByte(char) + continue + } - val, exists := escapetoval[char] - if exists { - out.WriteString(val) - } else if char == 'c' { - out.WriteString(colour) + // ingest the next character of the escape + char = remaining[0] + remaining = remaining[1:] - if len(remaining) < 2 || remaining[0] != '[' { - continue + if char == 'c' { + out.WriteString(colour) + + namedColors := bracketedExpr.FindString(remaining) + if namedColors == "" { + // for a non-bracketed color code, output the following characters directly, + // e.g., `$c1,8` will become `\x031,8` + continue + } + // process bracketed color codes: + remaining = remaining[len(namedColors):] + followedByDigit := len(remaining) != 0 && ('0' <= remaining[0] && remaining[0] <= '9') + + foreground, background := resolveToColourCodes(namedColors) + if foreground != "" { + if len(foreground) == 1 && background == "" && followedByDigit { + out.WriteByte('0') } - - // get colour names - var coloursBuffer string - remaining = remaining[1:] - for remaining[0] != ']' { - coloursBuffer += string(remaining[0]) - remaining = remaining[1:] - } - remaining = remaining[1:] // strip final ']' - - colours := strings.Split(coloursBuffer, ",") - var foreColour, backColour string - foreColour = colours[0] - if 1 < len(colours) { - backColour = colours[1] - } - - // decide whether we can use truncated colour codes - canUseTruncated := len(remaining) < 1 || !strings.Contains(colours1, string(remaining[0])) - - // turn colour names into real codes - var foreColourCode, backColourCode string - var exists bool - - if backColour != "" || canUseTruncated { - foreColourCode, exists = colourcodesTruncated[foreColour] - } else { - foreColourCode, exists = colourcodesFull[foreColour] - } - if exists { - foreColour = foreColourCode - } - - if backColour != "" { - if canUseTruncated { - backColourCode, exists = colourcodesTruncated[backColour] - } else { - backColourCode, exists = colourcodesFull[backColour] - } - if exists { - backColour = backColourCode + out.WriteString(foreground) + if background != "" { + out.WriteByte(',') + if len(background) == 1 && followedByDigit { + out.WriteByte('0') } + out.WriteString(background) } - - // output colour codes - out.WriteString(foreColour) - if backColour != "" { - out.WriteRune(',') - out.WriteString(backColour) - } - } else { - // unknown char - out.WriteRune(char) } } else { - out.WriteRune(char) + val, exists := escapetoval[rune(char)] + if exists { + out.WriteString(val) + } else { + // invalid escape, use the raw char + out.WriteByte(char) + } } } diff --git a/vendor/modules.txt b/vendor/modules.txt index 81b14111..558b0f92 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -21,7 +21,7 @@ github.com/go-sql-driver/mysql # github.com/gorilla/websocket v1.4.2 ## explicit github.com/gorilla/websocket -# github.com/goshuirc/irc-go v0.0.0-20201118022549-7209d10d54a8 +# github.com/goshuirc/irc-go v0.0.0-20201228002532-4e36cb3f41f1 ## explicit github.com/goshuirc/irc-go/ircfmt github.com/goshuirc/irc-go/ircmsg