fix: unescape quoted logfmt values (#4844)

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
TowyTowy
2026-07-17 02:20:56 +02:00
committed by GitHub
parent b86831d2ba
commit e3f4566f6f
2 changed files with 41 additions and 1 deletions
+19 -1
View File
@@ -2,6 +2,8 @@ package container
import (
"errors"
"strconv"
"strings"
orderedmap "github.com/wk8/go-ordered-map/v2"
)
@@ -36,7 +38,7 @@ func ParseLogFmt(log string) (*orderedmap.OrderedMap[string, string], error) {
} else if char == '\\' {
escaping = true
} else if char == '"' {
value = log[start:i]
value = unescapeQuoted(log[start-1 : i+1])
result.Set(key, value)
inQuotes = false
isKey = true
@@ -77,3 +79,19 @@ func ParseLogFmt(log string) (*orderedmap.OrderedMap[string, string], error) {
return result, nil
}
// unescapeQuoted decodes a quoted logfmt value (including the surrounding
// quotes) so escape sequences like \" and \\ produced by logfmt encoders
// (logrus, go-kit, go-logfmt) yield the original text instead of leaking
// backslashes into the parsed value. If the sequence is not decodable, the
// raw content between the quotes is returned unchanged.
func unescapeQuoted(quoted string) string {
raw := quoted[1 : len(quoted)-1]
if !strings.ContainsRune(raw, '\\') {
return raw
}
if unquoted, err := strconv.Unquote(quoted); err == nil {
return unquoted
}
return raw
}
+22
View File
@@ -67,6 +67,28 @@ func TestParseLog(t *testing.T) {
),
wantErr: false,
},
{
name: "Escaped quotes and backslashes in quoted values",
log: `level=info msg="failed to open \"config.yml\"" path="C:\\temp"`,
want: orderedmap.New[string, string](
orderedmap.WithInitialData(
orderedmap.Pair[string, string]{Key: "level", Value: "info"},
orderedmap.Pair[string, string]{Key: "msg", Value: `failed to open "config.yml"`},
orderedmap.Pair[string, string]{Key: "path", Value: `C:\temp`},
),
),
wantErr: false,
},
{
name: "Quoted value with undecodable escape is kept as-is",
log: `msg="foo \q bar"`,
want: orderedmap.New[string, string](
orderedmap.WithInitialData(
orderedmap.Pair[string, string]{Key: "msg", Value: `foo \q bar`},
),
),
wantErr: false,
},
{
name: "Broken format with unexpected quotes",
log: `key1=value"1"= key2="value2"`,