mirror of https://github.com/goccy/go-json.git
Fix cycle pointer value
This commit is contained in:
parent
51a1e71c6b
commit
7ac966b81e
|
@ -22,6 +22,7 @@ type Encoder struct {
|
||||||
indent int
|
indent int
|
||||||
structTypeToCompiledCode map[uintptr]*compiledCode
|
structTypeToCompiledCode map[uintptr]*compiledCode
|
||||||
structTypeToCompiledIndentCode map[uintptr]*compiledCode
|
structTypeToCompiledIndentCode map[uintptr]*compiledCode
|
||||||
|
seenPtr map[uintptr]struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type compiledCode struct {
|
type compiledCode struct {
|
||||||
|
@ -67,6 +68,7 @@ func init() {
|
||||||
buf: make([]byte, 0, bufSize),
|
buf: make([]byte, 0, bufSize),
|
||||||
structTypeToCompiledCode: map[uintptr]*compiledCode{},
|
structTypeToCompiledCode: map[uintptr]*compiledCode{},
|
||||||
structTypeToCompiledIndentCode: map[uintptr]*compiledCode{},
|
structTypeToCompiledIndentCode: map[uintptr]*compiledCode{},
|
||||||
|
seenPtr: map[uintptr]struct{}{},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
18
encode_vm.go
18
encode_vm.go
|
@ -80,6 +80,13 @@ func (e *Encoder) run(code *opcode) error {
|
||||||
typ: ifaceCode.typ,
|
typ: ifaceCode.typ,
|
||||||
ptr: unsafe.Pointer(ptr),
|
ptr: unsafe.Pointer(ptr),
|
||||||
}))
|
}))
|
||||||
|
if _, exists := e.seenPtr[ptr]; exists {
|
||||||
|
return &UnsupportedValueError{
|
||||||
|
Value: reflect.ValueOf(v),
|
||||||
|
Str: fmt.Sprintf("encountered a cycle via %s", code.typ),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
e.seenPtr[ptr] = struct{}{}
|
||||||
rv := reflect.ValueOf(v)
|
rv := reflect.ValueOf(v)
|
||||||
if rv.IsNil() {
|
if rv.IsNil() {
|
||||||
e.encodeNull()
|
e.encodeNull()
|
||||||
|
@ -498,6 +505,17 @@ func (e *Encoder) run(code *opcode) error {
|
||||||
code = c.next
|
code = c.next
|
||||||
case opStructFieldRecursive:
|
case opStructFieldRecursive:
|
||||||
recursive := code.toRecursiveCode()
|
recursive := code.toRecursiveCode()
|
||||||
|
if _, exists := e.seenPtr[recursive.ptr]; exists {
|
||||||
|
v := *(*interface{})(unsafe.Pointer(&interfaceHeader{
|
||||||
|
typ: code.typ,
|
||||||
|
ptr: unsafe.Pointer(recursive.ptr),
|
||||||
|
}))
|
||||||
|
return &UnsupportedValueError{
|
||||||
|
Value: reflect.ValueOf(v),
|
||||||
|
Str: fmt.Sprintf("encountered a cycle via %s", code.typ),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
e.seenPtr[recursive.ptr] = struct{}{}
|
||||||
if err := e.run(newRecursiveCode(recursive)); err != nil {
|
if err := e.run(newRecursiveCode(recursive)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue