Skip to content

Commit

Permalink
fix wrong way of Unmarshal,when struct have byte Slice([]byte) use js…
Browse files Browse the repository at this point in the history
…onx.Marshal but jsonx.Umarshal works wrong way
  • Loading branch information
wangshiben committed Sep 27, 2024
1 parent 5b8126c commit d4e13cd
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 2 deletions.
14 changes: 14 additions & 0 deletions core/mapping/unmarshaler.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package mapping

import (
"encoding"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
Expand Down Expand Up @@ -611,6 +612,19 @@ func (u *Unmarshaler) processFieldNotFromString(fieldType reflect.Type, value re
case valueKind == reflect.String && typeKind == reflect.Map:
return u.fillMapFromString(value, mapValue)
case valueKind == reflect.String && typeKind == reflect.Slice:
// try to find out if it's a byte slice, golang use []byte Marshal to base64 but there only SliceOf uint8/bytes can convert to []byte
// more details https://pkg.go.dev/encoding/json#Marshal
//> Array and slice values encode as JSON arrays, except that []byte encodes as a base64-encoded string, and a nil slice encodes as the null JSON value.
//and also u can find this https://stackoverflow.com/questions/34089750/marshal-byte-to-json-giving-a-strange-string
if fieldType.Elem().Kind() == reflect.Uint8 {
strVal := mapValue.(string)
decodedBytes, err := base64.StdEncoding.DecodeString(strVal)
// if err !=nil do next
if err == nil {
value.Set(reflect.ValueOf(decodedBytes))
return nil
}
}
return u.fillSliceFromString(fieldType, value, mapValue, fullName)
case valueKind == reflect.String && derefedFieldType == durationType:
return fillDurationValue(fieldType, value, mapValue.(string))
Expand Down
18 changes: 16 additions & 2 deletions core/mapping/unmarshaler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/zeromicro/go-zero/core/jsonx"
"reflect"
"strconv"
"strings"
Expand Down Expand Up @@ -4761,14 +4762,27 @@ func TestUnmarshal_EnvWithOptionsWrongValueString(t *testing.T) {

func TestUnmarshalJsonReaderMultiArray(t *testing.T) {
t.Run("reader multi array", func(t *testing.T) {
var res struct {
type testRes struct {
A string `json:"a"`
B [][]string `json:"b"`
C []byte `json:"c"`
}
var res testRes
marshal := testRes{
A: "133",
B: [][]string{
{"add", "cccd"},
{"eeee"},
},
C: []byte("11122344wsss"),
}
payload := `{"a": "133", "b": [["add", "cccd"], ["eeee"]]}`
bytes, err := jsonx.Marshal(marshal)
assert.NoError(t, err)
payload := string(bytes)
reader := strings.NewReader(payload)
if assert.NoError(t, UnmarshalJsonReader(reader, &res)) {
assert.Equal(t, 2, len(res.B))
assert.Equal(t, string(marshal.C), string(res.C))
}
})

Expand Down

0 comments on commit d4e13cd

Please sign in to comment.