Skip to content

Commit 5dc9e08

Browse files
json: add seen-type detection into constructCodec
Also remove named/naked return values from that function.
1 parent cb77973 commit 5dc9e08

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

json/codec.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,17 @@ func constructCachedCodec(t reflect.Type, cache codecCache) codec {
126126
return c
127127
}
128128

129-
func constructCodec(t reflect.Type, seen codecCache, canAddr bool) (c codec) {
129+
func constructCodec(t reflect.Type, seen codecCache, canAddr bool) codec {
130+
// Check if the codec has already been constructed: if so, return it.
131+
// This mitigates infinite recursion due to type definition cycles.
132+
c, ok := seen[typeid(t)]
133+
if ok {
134+
return c
135+
}
136+
137+
// Arrange for the constructed codec to be recorded in seen.
138+
defer func() { seen[typeid(t)] = c }()
139+
130140
switch t {
131141
case nullType, nil:
132142
c = codec{encode: encoder.encodeNull, decode: decoder.decodeNull}
@@ -163,7 +173,7 @@ func constructCodec(t reflect.Type, seen codecCache, canAddr bool) (c codec) {
163173
}
164174

165175
if c.encode != nil {
166-
return
176+
return c
167177
}
168178

169179
switch t.Kind() {
@@ -259,7 +269,7 @@ func constructCodec(t reflect.Type, seen codecCache, canAddr bool) (c codec) {
259269
c.decode = constructTextUnmarshalerDecodeFunc(t, true)
260270
}
261271

262-
return
272+
return c
263273
}
264274

265275
func constructStringCodec(t reflect.Type, seen codecCache, canAddr bool) codec {

0 commit comments

Comments
 (0)