Skip to content

Commit 5e9afab

Browse files
committed
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 <[email protected]> Run-TryBot: Jonathan Amsterdam <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent a5f1d02 commit 5e9afab

File tree

2 files changed

+16
-3
lines changed

2 files changed

+16
-3
lines changed

src/log/slog/handler.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -438,16 +438,17 @@ func (s *handleState) closeGroup(name string) {
438438
// It handles replacement and checking for an empty key.
439439
// after replacement).
440440
func (s *handleState) appendAttr(a Attr) {
441+
a.Value = a.Value.Resolve()
441442
if rep := s.h.opts.ReplaceAttr; rep != nil && a.Value.Kind() != KindGroup {
442443
var gs []string
443444
if s.groups != nil {
444445
gs = *s.groups
445446
}
446-
// Resolve before calling ReplaceAttr, so the user doesn't have to.
447-
a.Value = a.Value.Resolve()
447+
// a.Value is resolved before calling ReplaceAttr, so the user doesn't have to.
448448
a = rep(gs, a)
449+
// The ReplaceAttr function may return an unresolved Attr.
450+
a.Value = a.Value.Resolve()
449451
}
450-
a.Value = a.Value.Resolve()
451452
// Elide empty Attrs.
452453
if a.isEmpty() {
453454
return

src/log/slog/handler_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,18 @@ func TestJSONAndTextHandlers(t *testing.T) {
491491
wantText: "g.x=0 g.n=4 g.h.b=2",
492492
wantJSON: `{"g":{"x":0,"n":4,"h":{"b":2,"i":{}}}}`,
493493
},
494+
{
495+
name: "replace resolved group",
496+
replace: func(groups []string, a Attr) Attr {
497+
if a.Value.Kind() == KindGroup {
498+
return Attr{"bad", IntValue(1)}
499+
}
500+
return removeKeys(TimeKey, LevelKey, MessageKey)(groups, a)
501+
},
502+
attrs: []Attr{Any("name", logValueName{"Perry", "Platypus"})},
503+
wantText: "name.first=Perry name.last=Platypus",
504+
wantJSON: `{"name":{"first":"Perry","last":"Platypus"}}`,
505+
},
494506
} {
495507
r := NewRecord(testTime, LevelInfo, "message", callerPC(2))
496508
line := strconv.Itoa(r.source().Line)

0 commit comments

Comments
 (0)