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))
+}

Reply via email to