From 4ce3eaececfe2adfca1190a03b708a8d24864982 Mon Sep 17 00:00:00 2001 From: ahaostudy <1993584108@qq.com> Date: Tue, 31 Oct 2023 22:00:27 +0800 Subject: [PATCH 1/2] fix: issue where Decoder panics when decoding an Object containing a Map with int8/int16 as key or value type --- map.go | 11 ++++++++++- map_test.go | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/map.go b/map.go index f005324e..b360c9e4 100644 --- a/map.go +++ b/map.go @@ -219,7 +219,16 @@ func (d *Decoder) decMapByValue(value reflect.Value) error { return perrors.WithStack(err) } - m.Elem().SetMapIndex(EnsurePackValue(entryKey), EnsureRawValue(entryValue)) + // add a layer of conversion to make the map compatible with more types during decoding + key := EnsurePackValue(entryKey) + if mKey := m.Elem().Type().Key(); key.Type().ConvertibleTo(mKey) { + key = key.Convert(mKey) + } + val := EnsureRawValue(entryValue) + if mVal := m.Elem().Type().Elem(); val.Type().ConvertibleTo(mVal) { + val = val.Convert(mVal) + } + m.Elem().SetMapIndex(key, val) } SetValue(value, m) diff --git a/map_test.go b/map_test.go index 4d79ecd1..0d712739 100644 --- a/map_test.go +++ b/map_test.go @@ -182,3 +182,42 @@ func TestJavaMap(t *testing.T) { RegisterPOJO(customMap) testJavaDecode(t, "customArgTypedFixed_CustomMap", customMap) } + +type Obj struct { + Map8 map[int8]int8 + Map16 map[int16]int16 + Map32 map[int32]int32 +} + +func (Obj) JavaClassName() string { + return "" +} + +func TestMapInObject(t *testing.T) { + var ( + obj Obj + e *Encoder + d *Decoder + err error + res interface{} + ) + + obj = Obj{ + Map8: map[int8]int8{1: 2, 3: 4}, + Map16: map[int16]int16{1: 2, 3: 4}, + Map32: map[int32]int32{1: 2, 3: 4}, + } + + e = NewEncoder() + e.Encode(obj) + if len(e.Buffer()) == 0 { + t.Fail() + } + + d = NewDecoder(e.Buffer()) + res, err = d.Decode() + if err != nil { + t.Errorf("Decode() = %+v", err) + } + t.Logf("decode(%v) = %v, %v\n", obj, res, err) +} From fbdccbed27dec8135ea7d90bee5a4f3d819cb815 Mon Sep 17 00:00:00 2001 From: ahaostudy <1993584108@qq.com> Date: Wed, 1 Nov 2023 14:42:17 +0800 Subject: [PATCH 2/2] test: check if TestMapInObject decoded value is equal to original value --- map_test.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/map_test.go b/map_test.go index 0d712739..f86b8b64 100644 --- a/map_test.go +++ b/map_test.go @@ -18,6 +18,7 @@ package hessian import ( + "reflect" "testing" ) @@ -195,21 +196,21 @@ func (Obj) JavaClassName() string { func TestMapInObject(t *testing.T) { var ( - obj Obj + req *Obj e *Encoder d *Decoder err error res interface{} ) - obj = Obj{ + req = &Obj{ Map8: map[int8]int8{1: 2, 3: 4}, Map16: map[int16]int16{1: 2, 3: 4}, Map32: map[int32]int32{1: 2, 3: 4}, } e = NewEncoder() - e.Encode(obj) + e.Encode(req) if len(e.Buffer()) == 0 { t.Fail() } @@ -219,5 +220,9 @@ func TestMapInObject(t *testing.T) { if err != nil { t.Errorf("Decode() = %+v", err) } - t.Logf("decode(%v) = %v, %v\n", obj, res, err) + t.Logf("decode(%v) = %v, %v\n", req, res, err) + + if !reflect.DeepEqual(req, res) { + t.Fatalf("req: %#v != res: %#v", req, res) + } }