Skip to content

Commit 62c840e

Browse files
json: pass remaining cycle/unsupported-value tests
1 parent 1c6ff8f commit 62c840e

File tree

2 files changed

+22
-6
lines changed

2 files changed

+22
-6
lines changed

json/codec.go

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -309,12 +309,13 @@ func constructSliceCodec(t reflect.Type, seen seenMap) codec {
309309
e := t.Elem()
310310
s := alignedSize(e)
311311

312+
var c codec
313+
312314
if e.Kind() == reflect.Uint8 {
313315
// Go 1.7+ behavior: slices of byte types (and aliases) may override the
314316
// default encoding and decoding behaviors by implementing marshaler and
315317
// unmarshaler interfaces.
316318
p := reflect.PointerTo(e)
317-
c := codec{}
318319

319320
switch {
320321
case e.Implements(jsonMarshalerType):
@@ -353,11 +354,26 @@ func constructSliceCodec(t reflect.Type, seen seenMap) codec {
353354
return c
354355
}
355356

356-
c := constructCodec(e, seen, true)
357-
return codec{
358-
encode: constructSliceEncodeFunc(s, t, c.encode),
359-
decode: constructSliceDecodeFunc(s, t, c.decode),
357+
inner := constructCodec(e, seen, true)
358+
359+
// If encode/decode functions are nil, that means this is a recursive type,
360+
// and so we can use delayed binding to define self-referential calls.
361+
if inner.encode == nil {
362+
inner.encode = func(e encoder, b []byte, p unsafe.Pointer) ([]byte, error) {
363+
return c.encode(e, b, p)
364+
}
360365
}
366+
367+
if inner.decode == nil {
368+
inner.decode = func(d decoder, b []byte, p unsafe.Pointer) ([]byte, error) {
369+
return c.decode(d, b, p)
370+
}
371+
}
372+
373+
c.encode = constructSliceEncodeFunc(s, t, inner.encode)
374+
c.decode = constructSliceDecodeFunc(s, t, inner.decode)
375+
376+
return c
361377
}
362378

363379
func constructSliceEncodeFunc(size uintptr, t reflect.Type, encode encodeFunc) encodeFunc {

json/encode.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ func (e encoder) encodeTime(b []byte, p unsafe.Pointer) ([]byte, error) {
297297

298298
func (e encoder) encodeArray(b []byte, p unsafe.Pointer, n int, size uintptr, t reflect.Type, encode encodeFunc) ([]byte, error) {
299299
if shouldCheckForRefCycle(&e) {
300-
key := cycleKey{ptr: p}
300+
key := cycleKey{ptr: p, len: n}
301301
if hasRefCycle(&e, key) {
302302
return b, refCycleError(t, p)
303303
}

0 commit comments

Comments
 (0)