Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Panic when using a custom type with MarshalJSON() + omitempty + specific order of fields in a struct #147

Closed
knadh opened this issue Mar 10, 2021 · 2 comments

Comments

@knadh
Copy link

knadh commented Mar 10, 2021

The panic happens when:

  • There's a custom type with a MarshalJSON + there's an omitempty in the field + the field (Field2) has a value

The panic does not happen when:

  • Field2 is empty.
  • The order of Field1 and Field2 in the struct definition are interchanged (!)
package main

import (
	"fmt"

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

type NullStr string

type Test struct {
	Field1 string  `json:"field1"`
	Field2 NullStr `json:"field2,omitempty"`
}

func main() {

	b, err := gojson.Marshal(Test{
		Field1: "a",
		Field2: "b",
	})

	fmt.Println(string(b), err)
}

func (v *NullStr) MarshalJSON() ([]byte, error) {
	if *v == "" {
		return []byte("null"), nil
	}

	return []byte(*v), nil
}
$ go run main.go                                                                                                                                      
runtime: out of memory: cannot allocate 2317421039983788032-byte block (66781184 in use)
fatal error: out of memory

goroutine 1 [running]:
runtime.throw(0x55eca4, 0xd)
        /usr/local/go/src/runtime/panic.go:1117 +0x72 fp=0xc000414190 sp=0xc000414160 pc=0x4335f2
runtime.(*mcache).allocLarge(0x7fa7bf2fe108, 0x202922285b206000, 0x400100, 0x545180)
        /usr/local/go/src/runtime/mcache.go:226 +0x29e fp=0xc0004141e8 sp=0xc000414190 pc=0x4162be
runtime.mallocgc(0x202922285b206000, 0x0, 0x0, 0x538c36)
        /usr/local/go/src/runtime/malloc.go:1078 +0x925 fp=0xc000414270 sp=0xc0004141e8 pc=0x40d445
runtime.rawbyteslice(0x202922285b205020, 0x0, 0x0, 0x0)
        /usr/local/go/src/runtime/string.go:276 +0xb1 fp=0xc0004142b0 sp=0xc000414270 pc=0x44dc91
runtime.stringtoslicebyte(0x0, 0x40202b20736d6862, 0x202922285b205020, 0x545180, 0x545100, 0x7fa798632858)
        /usr/local/go/src/runtime/string.go:171 +0xbf fp=0xc0004142f8 sp=0xc0004142b0 pc=0x44d65f
main.(*NullStr).MarshalJSON(0x55d516, 0x545180, 0x55d516, 0x7fa798632858, 0x55d516, 0xc000404000)
        /code/go/my/go-json-benchmark/main.go:31 +0x90 fp=0xc000414338 sp=0xc0004142f8 pc=0x535ed0
github.com/goccy/go-json.encodeRunEscaped(0xc000406000, 0xc000404000, 0xe, 0x400, 0xc0000102f0, 0x1, 0x0, 0x0, 0x0, 0x0, ...)
        /code/go/pkg/mod/github.com/goccy/go-json@v0.4.7/encode_vm_escaped.go:5195 +0x3c9ef fp=0xc000415cc8 sp=0xc000414338 pc=0x52ed2f
github.com/goccy/go-json.encodeRunCode(0xc000406000, 0xc000404000, 0x0, 0x400, 0xc0000102f0, 0x1, 0x5352f7, 0x553d60, 0xc000406000, 0x8, ...)
        /code/go/pkg/mod/github.com/goccy/go-json@v0.4.7/encode.go:276 +0x74 fp=0xc000415d30 sp=0xc000415cc8 pc=0x49fc34
github.com/goccy/go-json.encode(0xc000406000, 0x54a640, 0xc000026040, 0x1, 0xc000026040, 0x20, 0x20, 0x54a640, 0x6316e0)
        /code/go/pkg/mod/github.com/goccy/go-json@v0.4.7/encode.go:205 +0x1df fp=0xc000415df8 sp=0xc000415d30 pc=0x49f8ff
github.com/goccy/go-json.marshal(0x54a640, 0xc000026040, 0x1, 0x40aadf, 0x54a640, 0xc000026040, 0xc000064f58, 0xc000026040)
        /code/go/pkg/mod/github.com/goccy/go-json@v0.4.7/encode.go:131 +0x85 fp=0xc000415e80 sp=0xc000415df8 pc=0x49f5a5
github.com/goccy/go-json.MarshalWithOption(0x54a640, 0xc000026040, 0x0, 0x0, 0x0, 0x7fa7bf2fe108, 0x60, 0xc00001e060, 0xc000036748, 0x64a4a0)
        /code/go/pkg/mod/github.com/goccy/go-json@v0.4.7/json.go:171 +0x76 fp=0xc000415ed8 sp=0xc000415e80 pc=0x5346f6
github.com/goccy/go-json.Marshal(...)
        /code/go/pkg/mod/github.com/goccy/go-json@v0.4.7/json.go:157
main.main()
        /code/go/my/go-json-benchmark/main.go:18 +0xce fp=0xc000415f88 sp=0xc000415ed8 pc=0x535d4e
runtime.main()
        /usr/local/go/src/runtime/proc.go:225 +0x256 fp=0xc000415fe0 sp=0xc000415f88 pc=0x435e36
runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:1371 +0x1 fp=0xc000415fe8 sp=0xc000415fe0 pc=0x465041
exit status 2
@goccy
Copy link
Owner

goccy commented Mar 11, 2021

Thank you for the reporting.
Currently, I will try to fix any encoder's bug with #148 .
This issue will fix by that PR .

goccy added a commit that referenced this issue Mar 11, 2021
- fix some issues ( #104 #118 #144 #147 )
- fix recursive call operation
- use json.Number of encoding/json
- fix encoding of MarshalJSON and MarshalText
- fix pointer operation
- remove 'anonymous' and 'only' operation
- add test cases for array/slice/map/marshaler
@goccy
Copy link
Owner

goccy commented Mar 11, 2021

I fixed this issue with #148

@goccy goccy closed this as completed Mar 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants