mirror of
https://github.com/golang/go
synced 2024-11-18 18:14:43 -07:00
log/slog: ensure ReplaceAttr does not see a group
The ReplaceAttr function should not see groups, only leaf attributes. Previously, we checked an Value for being a group, then resolved it, then called ReplaceAttr. We neglected to see if it was a group after resolving it. Now we resolve first, then check. Fixes #62731. Change-Id: I2fc40758e77c445f82deb2c9de8cae7a3b0e22cf Reviewed-on: https://go-review.googlesource.com/c/go/+/530478 Reviewed-by: Alan Donovan <adonovan@google.com> Run-TryBot: Jonathan Amsterdam <jba@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
a5f1d0263c
commit
5e9afab7df
@ -438,16 +438,17 @@ func (s *handleState) closeGroup(name string) {
|
||||
// It handles replacement and checking for an empty key.
|
||||
// after replacement).
|
||||
func (s *handleState) appendAttr(a Attr) {
|
||||
a.Value = a.Value.Resolve()
|
||||
if rep := s.h.opts.ReplaceAttr; rep != nil && a.Value.Kind() != KindGroup {
|
||||
var gs []string
|
||||
if s.groups != nil {
|
||||
gs = *s.groups
|
||||
}
|
||||
// Resolve before calling ReplaceAttr, so the user doesn't have to.
|
||||
a.Value = a.Value.Resolve()
|
||||
// a.Value is resolved before calling ReplaceAttr, so the user doesn't have to.
|
||||
a = rep(gs, a)
|
||||
// The ReplaceAttr function may return an unresolved Attr.
|
||||
a.Value = a.Value.Resolve()
|
||||
}
|
||||
a.Value = a.Value.Resolve()
|
||||
// Elide empty Attrs.
|
||||
if a.isEmpty() {
|
||||
return
|
||||
|
@ -491,6 +491,18 @@ func TestJSONAndTextHandlers(t *testing.T) {
|
||||
wantText: "g.x=0 g.n=4 g.h.b=2",
|
||||
wantJSON: `{"g":{"x":0,"n":4,"h":{"b":2,"i":{}}}}`,
|
||||
},
|
||||
{
|
||||
name: "replace resolved group",
|
||||
replace: func(groups []string, a Attr) Attr {
|
||||
if a.Value.Kind() == KindGroup {
|
||||
return Attr{"bad", IntValue(1)}
|
||||
}
|
||||
return removeKeys(TimeKey, LevelKey, MessageKey)(groups, a)
|
||||
},
|
||||
attrs: []Attr{Any("name", logValueName{"Perry", "Platypus"})},
|
||||
wantText: "name.first=Perry name.last=Platypus",
|
||||
wantJSON: `{"name":{"first":"Perry","last":"Platypus"}}`,
|
||||
},
|
||||
} {
|
||||
r := NewRecord(testTime, LevelInfo, "message", callerPC(2))
|
||||
line := strconv.Itoa(r.source().Line)
|
||||
|
Loading…
Reference in New Issue
Block a user