ugorji / go

idiomatic codec and rpc lib for msgpack, cbor, json, etc. msgpack.org[Go]
MIT License
1.83k stars 294 forks source link

Go 1.20 - invalid memory address or nil pointer dereference #388

Closed GlennRicaud closed 1 year ago

GlennRicaud commented 1 year ago

Getting some issues after compiling with go 1.20

json decode error [pos 230]: runtime error: invalid memory address or nil pointer dereference

To reproduce:

type Query struct{
  Segments []Segment `json:"segments"`
}
type Segment struct {
  SegmentName  string
  SegmentColor string
  Subsegments  []Subsegment
}
type Subsegment struct {
  SubsegmentName  string
  SubsegmentColor string
}
func TestDecode(t *testing.T) {
  f := &Query{}
  dec := codec.NewDecoderBytes([]byte("{\"segments\":[[\"a\",\"A\",[[\"b\",\"B\"],[\"c\",\"C\"],[\"d\",\"D\"],[\"e\",\"E\"],[\"f\",\"F\"],[\"g\",\"G\"],[\"h\",\"H\"],[\"i\",\"I\"],[\"j\",\"J\"]]]]}"), new(codec.JsonHandle))
  err := dec.Decode(f)
  require.NoError(t, err)
}
hypirion commented 1 year ago

As an observation, running this with -tags=codec.safe works fine on Go 1.20. Removing the last element in the last list (,[\"j\",\"J\"]) avoids the panic, which means that last list can be 8 elements or smaller. My wild guess (without looking into the code) is that this is related the updated slice API in the unsafe package.

(Require here is the "github.com/stretchr/testify/require" package, could as well be replaced with a manual check using testing)

ugorji commented 1 year ago

@GlennRicaud I just ran this on go 1.20, and it worked.

$ go version
go version go1.20 linux/amd64

$ go test -run Github388 -v
=== RUN   TestGithub388
    github_issue_388_test.go:26: 388: decoded: f: &{[{a A [{b B} {c C} {d D} {e E} {f F} {g G} {h H} {i I} {j J}]}]}
--- PASS: TestGithub388 (0.00s)
PASS

See test code (same as yours - just put into a single function)

func TestGithub388(t *testing.T) {
    type Subsegment struct {
        SubsegmentName  string
        SubsegmentColor string
    }
    type Segment struct {
        SegmentName  string
        SegmentColor string
        Subsegments  []Subsegment
    }
    type Query struct {
        Segments []Segment `json:"segments"`
    }

    f := &Query{}
    dec := codec.NewDecoderBytes([]byte("{\"segments\":[[\"a\",\"A\",[[\"b\",\"B\"],[\"c\",\"C\"],[\"d\",\"D\"],[\"e\",\"E\"],[\"f\",\"F\"],[\"g\",\"G\"],[\"h\",\"H\"],[\"i\",\"I\"],[\"j\",\"J\"]]]]}"), new(codec.JsonHandle))
    err := dec.Decode(f)
    t.Logf("388: decoded: f: %v", f)
    if err != nil {
        panic(err)
    }
}

Can you please re-run this, and let me know your result? @hypirion did you reproduce his results without codec.safe?

hypirion commented 1 year ago

If it's working for you then I suspect we just have an older version – sorry about the noise in that case, and thanks for trying it out locally.

I see we're running 1.2.7, so I'll see what happens if we go to 1.2.9.

cvermilion commented 1 year ago

Hit the same issue and can confirm upgrading from 1.2.7 to 1.2.9 seems to fix.

ugorji commented 1 year ago

thanks folks.