From 41ab6becb26c96f95d87eeae139db9a04e1c906b Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Tue, 28 Nov 2023 14:39:28 -0600 Subject: [PATCH] core/logger: sanitize escape chars in console logs (#11402) --- .../internal/colortest/prettyconsole_test.go | 6 ++++ core/logger/prettyconsole.go | 29 +++++++++++++++++-- docs/CHANGELOG.md | 1 + 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/core/logger/internal/colortest/prettyconsole_test.go b/core/logger/internal/colortest/prettyconsole_test.go index fd2ea3f0b17..125f5a2ea50 100644 --- a/core/logger/internal/colortest/prettyconsole_test.go +++ b/core/logger/internal/colortest/prettyconsole_test.go @@ -61,6 +61,12 @@ func TestPrettyConsole_Write(t *testing.T) { "2018-04-12T12:55:28Z \x1b[91m[FATAL] \x1b[0mtop level \x1b[34m\x1b[0m \n", false, }, + { + "control", + `{"ts":1523537728, "level":"fatal", "msg":"\u0008\t\n\r\u000b\u000c\ufffd\ufffd", "hash":"nuances"}`, + "2018-04-12T12:55:28Z \x1b[91m[FATAL] \x1b[0m\\b\t\n\r\\v\\f�� \x1b[34m\x1b[0m \n", + false, + }, {"broken", `{"broken":}`, `{}`, true}, } diff --git a/core/logger/prettyconsole.go b/core/logger/prettyconsole.go index 69427f74715..5150f1f3d69 100644 --- a/core/logger/prettyconsole.go +++ b/core/logger/prettyconsole.go @@ -6,8 +6,10 @@ import ( "net/url" "os" "sort" + "strconv" "strings" "time" + "unicode" "github.com/fatih/color" "github.com/tidwall/gjson" @@ -72,7 +74,7 @@ func generateHeadline(js gjson.Result) string { tsStr, " ", coloredLevel(js.Get("level")), - fmt.Sprintf("%-50s", js.Get("msg")), + fmt.Sprintf("%-50s", sanitized(js.Get("msg").String())), " ", fmt.Sprintf("%-32s", blue(js.Get("caller"))), } @@ -105,7 +107,7 @@ func generateDetails(js gjson.Result) string { var details strings.Builder for _, v := range keys { - details.WriteString(fmt.Sprintf("%s=%v ", green(v), data[v])) + details.WriteString(fmt.Sprintf("%s=%v ", green(sanitized(v)), sanitized(data[v].String()))) } return details.String() @@ -129,3 +131,26 @@ func prettyConsoleSink(s zap.Sink) func(*url.URL) (zap.Sink, error) { return PrettyConsole{s}, nil } } + +type sanitized string + +// String replaces control characters with Go escape sequences, except for newlines and tabs. +// See strconv.QuoteRune. +func (s sanitized) String() string { + var out string + for _, r := range s { + switch r { + case '\n', '\r', '\t': + // allowed + default: + // escape others + if unicode.IsControl(r) { + q := strconv.QuoteRune(r) + out += q[1 : len(q)-1] // trim quotes + continue + } + } + out += string(r) + } + return out +} diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index d9a785ff518..64f9472319f 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -54,6 +54,7 @@ LatestReportDeadline = "5s" # Default ### Changed - `L2Suggested` mode is now called `SuggestedPrice` +- Console logs will now escape (non-whitespace) control characters ### Removed