This is an automated email from the ASF dual-hosted git repository.
wongoo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo-go-hessian2.git
The following commit(s) were added to refs/heads/master by this push:
new 33f7e9d fix issue 356 that ref to wrong type of map for nil value
(#357)
33f7e9d is described below
commit 33f7e9deb352bb7eccf305a806172ae52781b166
Author: tiltwind(斜风) <[email protected]>
AuthorDate: Sun Apr 9 23:59:16 2023 +0800
fix issue 356 that ref to wrong type of map for nil value (#357)
* fix issue 356
* fix issue 356
* fix issue 356
---
map.go | 2 +-
ref.go | 29 +++++++++-------
testcases/issue356/issue356_test.go | 68 +++++++++++++++++++++++++++++++++++++
3 files changed, 86 insertions(+), 13 deletions(-)
diff --git a/map.go b/map.go
index 1336756..f005324 100644
--- a/map.go
+++ b/map.go
@@ -117,7 +117,7 @@ func (e *Encoder) encMap(m interface{}) error {
value = UnpackPtrValue(value)
// check nil map
- if value.Kind() == reflect.Ptr && !value.Elem().IsValid() {
+ if value.IsNil() || (value.Kind() == reflect.Ptr &&
!value.Elem().IsValid()) {
e.buffer = EncNull(e.buffer)
return nil
}
diff --git a/ref.go b/ref.go
index f892601..0767ca0 100644
--- a/ref.go
+++ b/ref.go
@@ -29,6 +29,9 @@ import (
// Empty slice is not nil, but the addresses of all empty slice are the same.
var _emptySliceAddr =
unsafe.Pointer(reflect.ValueOf([]interface{}{}).Pointer())
+// The addresses of all nil map are the same.
+var _nilMapAddr =
unsafe.Pointer(reflect.ValueOf(map[interface{}]interface{}(nil)).Pointer())
+
// used to ref object,list,map
type _refElem struct {
// record the kind of target, objects are the same only if the address
and kind are the same
@@ -127,20 +130,22 @@ func (e *Encoder) checkRefMap(v reflect.Value) (int,
bool) {
}
}
- if addr != _emptySliceAddr {
- if elem, ok := e.refMap[addr]; ok {
- if elem.kind == kind {
- // If kind is not struct, just return the
index. Otherwise,
- // check whether the types are same, because
the different
- // empty struct may share the same address and
kind.
- if elem.kind != reflect.Struct {
- return elem.index, ok
- } else if elem.tp == tp {
- return elem.index, ok
- }
+ if addr == _emptySliceAddr || addr == _nilMapAddr {
+ return 0, false
+ }
+
+ if elem, ok := e.refMap[addr]; ok {
+ if elem.kind == kind {
+ // If kind is not struct, just return the index.
Otherwise,
+ // check whether the types are same, because the
different
+ // empty struct may share the same address and kind.
+ if elem.kind != reflect.Struct {
+ return elem.index, ok
+ } else if elem.tp == tp {
+ return elem.index, ok
}
- return 0, false
}
+ return 0, false
}
n := len(e.refMap)
diff --git a/testcases/issue356/issue356_test.go
b/testcases/issue356/issue356_test.go
new file mode 100644
index 0000000..d6175d5
--- /dev/null
+++ b/testcases/issue356/issue356_test.go
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package issue356
+
+import (
+ "reflect"
+ "testing"
+)
+
+import (
+ hessian "github.com/apache/dubbo-go-hessian2"
+)
+
+import (
+ "github.com/stretchr/testify/assert"
+)
+
+type UserInfo struct {
+ Name string
+ Address map[string]string
+ Family map[string]int
+}
+
+func (UserInfo) JavaClassName() string {
+ return "com.test.UserInfo"
+}
+
+func TestIssue356Case(t *testing.T) {
+ info := &UserInfo{
+ Name: "test",
+ Address: nil,
+ Family: nil,
+ }
+
+ hessian.RegisterPOJO(info)
+
+ encoder := hessian.NewEncoder()
+ err := encoder.Encode(info)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+
+ enBuf := encoder.Buffer()
+
+ decoder := hessian.NewDecoder(enBuf)
+ dec, err := decoder.Decode()
+ assert.Nil(t, err)
+
+ t.Log(dec)
+
+ assert.True(t, reflect.DeepEqual(info, dec))
+}