Skip to content

Commit

Permalink
Fix decode enum not correctly (#332)
Browse files Browse the repository at this point in the history
* fix enum decode

* fix duplicate name struct unit test

* add unit tests in sub directories

* add unit test for type convert

* format code

* format import
  • Loading branch information
wongoo authored Oct 31, 2022
1 parent 5e88953 commit d520464
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 21 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/github-actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ jobs:
run: golangci-lint run --timeout=10m -v

- name: Go Test
run: GO111MODULE=on && go mod vendor && go test -race -v && go test -bench . -race -coverprofile=coverage.txt
run: GO111MODULE=on && go mod vendor && go test ./... -race -v && go test -bench . -race -coverprofile=coverage.txt

- name: Coverage
run: bash <(curl -s https://codecov.io/bash)
Expand Down
14 changes: 0 additions & 14 deletions hessian_test/dup_struct_name_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,6 @@ func TestDupStructNameResponse(t *testing.T) {
assert.Nil(t, err)

decodedResponse := &hessian.Response{}
decodedResponse.RspObj = &dupclass.CaseZ{}
err = codecR.ReadBody(decodedResponse)
assert.NotNil(t, err)
assert.Equal(t, ExpectedErrorMsg, err.Error())

decodedResponse = &hessian.Response{}
decodedResponse.RspObj = &CaseZ{}
err = codecR.ReadBody(decodedResponse)
assert.Nil(t, err)

Expand All @@ -134,13 +127,6 @@ func TestDupStructNameResponse2(t *testing.T) {
assert.Nil(t, err)

decodedResponse := &hessian.Response{}
decodedResponse.RspObj = &CaseZ{}
err = codecR.ReadBody(decodedResponse)
assert.NotNil(t, err)
assert.Equal(t, ExpectedErrorMsg, err.Error())

decodedResponse = &hessian.Response{}
decodedResponse.RspObj = &dupclass.CaseZ{}
err = codecR.ReadBody(decodedResponse)
assert.Nil(t, err)

Expand Down
15 changes: 9 additions & 6 deletions object.go
Original file line number Diff line number Diff line change
Expand Up @@ -508,17 +508,20 @@ func (d *Decoder) decInstance(typ reflect.Type, cls *ClassInfo) (interface{}, er
if err != nil {
// java enum
if fldRawValue.Type().Implements(javaEnumType) {
d.unreadByte() // Enum parsing, decInt64 above has read a byte, so you need to return a byte here
s, decErr := d.DecodeValue()
_ = d.unreadByte() // Enum parsing, decInt64 above has read a byte, so you need to return a byte here
enumVal, decErr := d.DecodeValue()
if decErr != nil {
return nil, perrors.Wrapf(decErr, "decInstance->decObject field name:%s", fieldName)
}
enumValue, _ := s.(JavaEnum)
num = int32(enumValue)
} else {
return nil, perrors.Wrapf(err, "decInstance->decInt32, field name:%s", fieldName)

SetValue(fldRawValue, reflect.ValueOf(enumVal))

continue
}

return nil, perrors.Wrapf(err, "decInstance->decInt32, field name:%s", fieldName)
}

fldRawValue.SetInt(int64(num))
case reflect.Uint16, reflect.Uint8:
num, err := d.decInt32(TAG_READ)
Expand Down
87 changes: 87 additions & 0 deletions testcases/user/user.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* 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 user

import (
"fmt"
"strconv"
"time"
)

import (
hessian "github.com/apache/dubbo-go-hessian2"
)

type Gender hessian.JavaEnum

const (
MAN Gender = iota
WOMAN
)

var genderName = map[Gender]string{
MAN: "MAN",
WOMAN: "WOMAN",
}

var genderValue = map[string]Gender{
"MAN": MAN,
"WOMAN": WOMAN,
}

func (g Gender) JavaClassName() string {
return "org.apache.dubbo.sample.Gender"
}

func (g Gender) String() string {
s, ok := genderName[g]
if ok {
return s
}

return strconv.Itoa(int(g))
}

func (g Gender) EnumValue(s string) hessian.JavaEnum {
v, ok := genderValue[s]
if ok {
return hessian.JavaEnum(v)
}

return hessian.InvalidJavaEnum
}

type User struct {
// !!! Cannot define lowercase names of variable
ID string
Name string
Age int32
Time time.Time
Sex Gender // notice: java enum Object <--> go string
}

func (u User) String() string {
return fmt.Sprintf(
"User{ID:%s, Name:%s, Age:%d, Time:%s, Sex:%s}",
u.ID, u.Name, u.Age, u.Time, u.Sex,
)
}

func (u *User) JavaClassName() string {
return "org.apache.dubbo.sample.User"
}
57 changes: 57 additions & 0 deletions testcases/user/user_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* 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 user

import (
"testing"
"time"
)

import (
hessian "github.com/apache/dubbo-go-hessian2"
)

import (
"github.com/stretchr/testify/assert"
)

func TestEnumConvert(t *testing.T) {
var g interface{}
g = WOMAN

// new defined type cant be converted to the original type.
failConvertedValue, ok := g.(hessian.JavaEnum)
assert.False(t, ok)
assert.Equal(t, hessian.JavaEnum(0), failConvertedValue)
}

func TestUserEncodeDecode(t *testing.T) {
ts, _ := time.Parse("2006-01-02 15:04:05", "2019-01-01 12:34:56")
u1 := &User{ID: "001", Name: "Lily", Age: 18, Time: ts.Local(), Sex: WOMAN}
hessian.RegisterPOJO(u1)

encoder := hessian.NewEncoder()
err := encoder.Encode(u1)
assert.Nil(t, err)

buf := encoder.Buffer()
decoder := hessian.NewDecoder(buf)
dec, err := decoder.Decode()
assert.Nil(t, err)
assert.Equal(t, u1, dec)
}

0 comments on commit d520464

Please sign in to comment.