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 / memory corruption when decoding msgpack struct with embedded maps #367

Closed
philipatl opened this issue Feb 15, 2022 · 0 comments
Closed

Comments

@philipatl
Copy link

Please see my example below. The issue occurs when you have a certain nesting of structs with maps. In this case, we have a struct with a map of string to slice of pointer to struct with a map of string to slice of string. This appears to cause the kMap decode function, which is called recursively, to assign memory where it should not.

package main

import (
	"bytes"
	"fmt"

	"github.com/ugorji/go/codec"
)

type Inner struct {
	InnerMap map[string][]string
}

type Outer struct {
	OuterMap map[string][]*Inner
}

func reproPanic() {
	inner := &Inner{}
	inner.InnerMap = map[string][]string{
		"foo": {
			"bar",
		},
	}

	outer := &Outer{}
	outer.OuterMap = make(map[string][]*Inner)
	outer.OuterMap["blah"] = []*Inner{
		inner,
	}

	outer2 := &Outer{}

	encodeDecodeEncodeRoundtrip(outer, outer2)

	// not expected to get here
	fmt.Printf("NOT REACHED!?")
}

func encodeDecodeEncodeRoundtrip(obj, dest interface{}) {

	handle := &codec.MsgpackHandle{}
	encoder := codec.NewEncoder(nil, handle)
	decoder := codec.NewDecoder(nil, handle)

	buf := bytes.NewBuffer(nil)
	encoder.Reset(buf)
	encoder.MustEncode(obj)

	decoder.Reset(bytes.NewBuffer(buf.Bytes()))
	decoder.MustDecode(dest)

	buf = bytes.NewBuffer(nil)
	encoder.Reset(buf)
	encoder.MustEncode(dest)
}

func main() {
	reproPanic()
}
@ugorji ugorji closed this as completed in ad33c37 Feb 26, 2022
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

1 participant