go-json
go-json copied to clipboard
Compiler SIGSEGV on embedding of a struct with a recursive field named via struct tag
Thanks for the great library!
I ran into a little issue today. With the test case below the compiler fails with a nil pointer de-reference:
=== RUN TestBrokenRecursion
--- FAIL: TestBrokenRecursion (0.00s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x60 pc=0x5608a7]
goroutine 6 [running]:
testing.tRunner.func1.2({0x805500, 0xb9eb50})
/usr/local/go/src/testing/testing.go:1545 +0x238
testing.tRunner.func1()
/usr/local/go/src/testing/testing.go:1548 +0x397
panic({0x805500?, 0xb9eb50?})
/usr/local/go/src/runtime/panic.go:914 +0x21f
github.com/goccy/go-json/internal/encoder.copyOpcode(0x0)
/.../go-json/internal/encoder/opcode.go:324 +0x27
github.com/goccy/go-json/internal/encoder.(*Compiler).linkRecursiveCode(0xc0000ab890?, 0xc0000aba70)
/.../go-json/internal/encoder/compiler.go:908 +0x185
github.com/goccy/go-json/internal/encoder.(*Compiler).codeToOpcode(0xc0000f1ce0?, 0xc0000aba70, 0x7dbd00, {0x931488?, 0xc0000ab890?})
/.../go-json/internal/encoder/compiler.go:894 +0xe5
github.com/goccy/go-json/internal/encoder.(*Compiler).codeToOpcodeSet(0x40ec45?, 0x7dbd00, {0x931488?, 0xc0000ab890})
/.../go-json/internal/encoder/compiler.go:108 +0xd8
github.com/goccy/go-json/internal/encoder.(*Compiler).compile(0xc00006c598?, 0x7dbd00)
/.../go-json/internal/encoder/compiler.go:104 +0x4d
github.com/goccy/go-json/internal/encoder.CompileToGetCodeSet(0xc00006c670?, 0x477645?)
/.../go-json/internal/encoder/compiler_norace.go:22 +0x145
github.com/goccy/go-json.encode(0xc0000ad2b0, {0x7dbd00, 0xc00006e1e8})
/.../go-json/encode.go:226 +0xae
github.com/goccy/go-json.marshal({0x7dbd00, 0xc00006e1e8}, {0x0, 0x0, 0x4ed801?})
/.../go-json/encode.go:150 +0xb9
github.com/goccy/go-json.MarshalWithOption(...)
/.../go-json/json.go:186
github.com/goccy/go-json.Marshal({0x7dbd00?, 0xc00006e1e8?})
/.../go-json/json.go:171 +0x25
github.com/goccy/go-json_test.TestBrokenRecursion(0xc0000f6340)
/.../go-json/recursion_test.go:10 +0x2e
testing.tRunner(0xc0000f6340, 0x8b1f00)
/usr/local/go/src/testing/testing.go:1595 +0xff
created by testing.(*T).Run in goroutine 1
/usr/local/go/src/testing/testing.go:1648 +0x3ad
exit status 2
FAIL github.com/goccy/go-json 0.007s
In the case below ctx.structTypeToCodes[typeptr]
is unset in Compiler.linkRecursiveCode
when trying to link json_test.Inner
. ctx.structTypeToCodes
only contains json_test.Outer
at this point.
Minimized test case
package json_test
import (
"testing"
"github.com/goccy/go-json"
)
func TestBrokenRecursion(t *testing.T) {
_, err := json.Marshal(&Outer{})
if err != nil {
t.Fail()
}
}
type Outer struct {
*Inner
}
type Inner struct {
Inner *Inner `json:"inner"`
}
Possible duplicate of #459