Skip to content

Commit

Permalink
log/slog: ensure ReplaceAttr does not see a group
Browse files Browse the repository at this point in the history
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 <[email protected]>
Run-TryBot: Jonathan Amsterdam <[email protected]>
TryBot-Result: Gopher Robot <[email protected]>
  • Loading branch information
jba committed Sep 25, 2023
1 parent a5f1d02 commit 5e9afab
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 3 deletions.
7 changes: 4 additions & 3 deletions src/log/slog/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 12 additions & 0 deletions src/log/slog/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 5e9afab

Please sign in to comment.