From 47565dc0f8c9ceaeeb84f32271eea9ab4b7bdd98 Mon Sep 17 00:00:00 2001 From: wongoo Date: Sun, 4 Dec 2022 18:33:27 +0800 Subject: [PATCH 1/2] fix issue #340 --- ref.go | 25 ++++---- testcases/issue340/issue340_test.go | 89 +++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 10 deletions(-) create mode 100644 testcases/issue340/issue340_test.go diff --git a/ref.go b/ref.go index e23d688c..601aff5f 100644 --- a/ref.go +++ b/ref.go @@ -26,6 +26,9 @@ import ( perrors "github.com/pkg/errors" ) +// Empty slice is not nil, but the addresses of all empty slice are the same. +var _emptySliceAddr = unsafe.Pointer(reflect.ValueOf([]interface{}{}).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 @@ -124,18 +127,20 @@ func (e *Encoder) checkRefMap(v reflect.Value) (int, bool) { } } - 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 { + 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/issue340/issue340_test.go b/testcases/issue340/issue340_test.go new file mode 100644 index 00000000..67d42182 --- /dev/null +++ b/testcases/issue340/issue340_test.go @@ -0,0 +1,89 @@ +/* + * 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 issue340 + +import ( + "reflect" + "testing" +) + +import ( + hessian "github.com/apache/dubbo-go-hessian2" +) + +import ( + "github.com/stretchr/testify/assert" +) + +type Point struct { + X int + Y int +} + +func (Point) JavaClassName() string { + return "com.test.Point" +} + +type SpPoint struct { + X int + Y int + Sp int +} + +func (SpPoint) JavaClassName() string { + return "com.test.SpPoint" +} + +type ReqInfo struct { + Name string + Points []*Point + SpPoints []*SpPoint +} + +func (ReqInfo) JavaClassName() string { + return "com.test.ReqInfo" +} + +func TestIssue340Case(t *testing.T) { + req := &ReqInfo{ + Name: "test", + Points: []*Point{}, + SpPoints: []*SpPoint{}, + } + + hessian.RegisterPOJO(&Point{}) + hessian.RegisterPOJO(&SpPoint{}) + hessian.RegisterPOJO(req) + + encoder := hessian.NewEncoder() + err := encoder.Encode(req) + if err != nil { + t.Error(err) + return + } + + enBuf := encoder.Buffer() + + decoder := hessian.NewDecoder(enBuf) + deReq, err := decoder.Decode() + assert.Nil(t, err) + + t.Log(deReq) + + assert.True(t, reflect.DeepEqual(req, deReq)) +} From 97fab4f72930b001068b9b12e53b11e734ef91da Mon Sep 17 00:00:00 2001 From: wongoo Date: Sun, 4 Dec 2022 18:41:47 +0800 Subject: [PATCH 2/2] format code --- ref.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ref.go b/ref.go index 601aff5f..f8926013 100644 --- a/ref.go +++ b/ref.go @@ -27,7 +27,7 @@ import ( ) // Empty slice is not nil, but the addresses of all empty slice are the same. -var _emptySliceAddr = unsafe.Pointer(reflect.ValueOf([]interface{}{}).Pointer()) +var _emptySliceAddr = unsafe.Pointer(reflect.ValueOf([]interface{}{}).Pointer()) // used to ref object,list,map type _refElem struct {