goccy / go-json

Fast JSON encoder/decoder compatible with encoding/json for Go
MIT License
3.11k stars 148 forks source link

Panic in Go Application When Marshaling Structs #519

Open aleksei-u opened 3 months ago

aleksei-u commented 3 months ago

Our application panics when trying to marshal a struct using the github.com/goccy/go-json package. The issue seems to occur when attempting to serialize a struct.

Steps to Reproduce: Create a new Go file with the following code:

package main

import (
    "fmt"

    "github.com/goccy/go-json"
)

type Body struct {
    Payload *Detail `json:"p,omitempty"`
}

type Detail struct {
    I Item `json:"i"`
}

type Item struct {
    A string `json:"a"`
    B string `json:"b,omitempty"`
}

func main() {
    b, err := json.Marshal(Body{
        Payload: &Detail{
            I: Item{
                A: "a",
                B: "b",
            },
        },
    })
    fmt.Println(err)
    fmt.Println(string(b))
}

Run the program using the go run command.

Expected Result: The program should output the JSON string without any errors, similar to: {"p":{"i":{"a":"a","b":"b"}}}

Actual Result: The program panics and does not output the expected JSON string.

Additional Information: go.mod

module my.com/app

go 1.22.5

require github.com/goccy/go-json v0.10.3
goroutine 1 gp=0xc0000061c0 m=0 mp=0x4cee8c0 [running]:
runtime.throw({0x4bb6cef?, 0x0?})
/usr/local/go/src/runtime/panic.go:1023 +0x5c fp=0xc0000278d0 sp=0xc0000278a0 pc=0x4ad121c
runtime.sigpanic()
/usr/local/go/src/runtime/signal_unix.go:895 +0x285 fp=0xc000027930 sp=0xc0000278d0 pc=0x4ae7565
github.com/goccy/go-json/internal/encoder.appendNormalizedHTMLString({0xc00012c000?, 0x0?, 0x0?}, {0x3d3a3c4d29306061, 0x2829202c29694c5f})
/Users/al/go/pkg/mod/github.com/goccy/go-json@v0.10.3/internal/encoder/string.go:73 +0xe34 fp=0xc0000279f8 sp=0xc000027930 pc=0x4b5b534
github.com/goccy/go-json/internal/encoder.AppendString(0x0?, {0xc00012c000?, 0x0?, 0x0?}, {0x3d3a3c4d29306061?, 0x0?})
/Users/al/go/pkg/mod/github.com/goccy/go-json@v0.10.3/internal/encoder/string.go:52 +0x45 fp=0xc000027a30 sp=0xc0000279f8 pc=0x4b5a645
github.com/goccy/go-json/internal/encoder/vm.Run(0xc000104750, {0xc00012c000?, 0x0?, 0x400?}, 0xc00012a070?)
/Users/al/go/pkg/mod/github.com/goccy/go-json@v0.10.3/internal/encoder/vm/vm.go:1718 +0x4db1 fp=0xc000029d88 sp=0xc000027a30 pc=0x4b949f1
github.com/goccy/go-json.encodeRunCode(0xc000104750?, {0xc00012c000?, 0xc000186dc0?, 0xc000102040?}, 0xc00012c400?)
/Users/al/go/pkg/mod/github.com/goccy/go-json@v0.10.3/encode.go:310 +0x56 fp=0xc000029dc0 sp=0xc000029d88 pc=0x4bb64b6
github.com/goccy/go-json.encode(0xc000104750, {0x4c07140, 0xc00007a060})
/Users/al/go/pkg/mod/github.com/goccy/go-json@v0.10.3/encode.go:235 +0x205 fp=0xc000029e40 sp=0xc000029dc0 pc=0x4bb63c5
github.com/goccy/go-json.marshal({0x4c07140, 0xc00007a060}, {0x0, 0x0, 0x1?})
/Users/al/go/pkg/mod/github.com/goccy/go-json@v0.10.3/encode.go:150 +0xb9 fp=0xc000029ea0 sp=0xc000029e40 pc=0x4bb60b9
github.com/goccy/go-json.MarshalWithOption(...)
/Users/al/go/pkg/mod/github.com/goccy/go-json@v0.10.3/json.go:185
github.com/goccy/go-json.Marshal({0x4c07140?, 0xc00007a060?})
/Users/al/go/pkg/mod/github.com/goccy/go-json@v0.10.3/json.go:170 +0x25 fp=0xc000029ed8 sp=0xc000029ea0 pc=0x4bb6525
main.main()
/Users/al/src/test/main.go:25 +0x90 fp=0xc000029f50 sp=0xc000029ed8 pc=0x4bb66d0
runtime.main()
/usr/local/go/src/runtime/proc.go:271 +0x29d fp=0xc000029fe0 sp=0xc000029f50 pc=0x4ad3c7d
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc000029fe8 sp=0xc000029fe0 pc=0x4b01e81

goroutine 2 gp=0xc000006700 m=nil [force gc (idle)]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc00005efa8 sp=0xc00005ef88 pc=0x4ad40ae
runtime.goparkunlock(...)
/usr/local/go/src/runtime/proc.go:408
runtime.forcegchelper()
/usr/local/go/src/runtime/proc.go:326 +0xb3 fp=0xc00005efe0 sp=0xc00005efa8 pc=0x4ad3f33
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00005efe8 sp=0xc00005efe0 pc=0x4b01e81
created by runtime.init.6 in goroutine 1
/usr/local/go/src/runtime/proc.go:314 +0x1a

goroutine 3 gp=0xc000006c40 m=nil [GC sweep wait]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc00005f780 sp=0xc00005f760 pc=0x4ad40ae
runtime.goparkunlock(...)
/usr/local/go/src/runtime/proc.go:408
runtime.bgsweep(0xc000078000)
/usr/local/go/src/runtime/mgcsweep.go:278 +0x94 fp=0xc00005f7c8 sp=0xc00005f780 pc=0x4ac0dd4
runtime.gcenable.gowrap1()
/usr/local/go/src/runtime/mgc.go:203 +0x25 fp=0xc00005f7e0 sp=0xc00005f7c8 pc=0x4ab5925
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00005f7e8 sp=0xc00005f7e0 pc=0x4b01e81
created by runtime.gcenable in goroutine 1
/usr/local/go/src/runtime/mgc.go:203 +0x66

goroutine 4 gp=0xc000006e00 m=nil [GC scavenge wait]:
runtime.gopark(0xc000078000?, 0x4bf0f20?, 0x1?, 0x0?, 0xc000006e00?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc00005ff78 sp=0xc00005ff58 pc=0x4ad40ae
runtime.goparkunlock(...)
/usr/local/go/src/runtime/proc.go:408
runtime.(*scavengerState).park(0x4cee160)
/usr/local/go/src/runtime/mgcscavenge.go:425 +0x49 fp=0xc00005ffa8 sp=0xc00005ff78 pc=0x4abe7c9
runtime.bgscavenge(0xc000078000)
/usr/local/go/src/runtime/mgcscavenge.go:653 +0x3c fp=0xc00005ffc8 sp=0xc00005ffa8 pc=0x4abed5c
runtime.gcenable.gowrap2()
/usr/local/go/src/runtime/mgc.go:204 +0x25 fp=0xc00005ffe0 sp=0xc00005ffc8 pc=0x4ab58c5
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc00005ffe8 sp=0xc00005ffe0 pc=0x4b01e81
created by runtime.gcenable in goroutine 1
/usr/local/go/src/runtime/mgc.go:204 +0xa5

goroutine 5 gp=0xc000007340 m=nil [finalizer wait]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc000060620 sp=0xc000060600 pc=0x4ad40ae
runtime.runfinq()
/usr/local/go/src/runtime/mfinal.go:194 +0x107 fp=0xc0000607e0 sp=0xc000060620 pc=0x4ab4967
runtime.goexit({})
/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc0000607e8 sp=0xc0000607e0 pc=0x4b01e81
created by runtime.createfing in goroutine 1
/usr/local/go/src/runtime/mfinal.go:164 +0x3d
exit status 2