Skip to content

Commit

Permalink
bugfix: fix map decode (#2979)
Browse files Browse the repository at this point in the history
* fix map decode

* fix lint

* fix lint
  • Loading branch information
tonybase authored Aug 30, 2023
1 parent a09f4d8 commit 6c026bc
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 11 deletions.
17 changes: 15 additions & 2 deletions encoding/form/proto_decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ import (
"google.golang.org/protobuf/types/known/wrapperspb"
)

var ErrInvalidFormatMapKey = errors.New("invalid formatting for map key")
const fieldSeparater = "."

var errInvalidFormatMapKey = errors.New("invalid formatting for map key")

// DecodeValues decode url value into proto message.
func DecodeValues(msg proto.Message, values url.Values) error {
Expand Down Expand Up @@ -91,6 +93,8 @@ func getFieldDescriptor(v protoreflect.Message, fieldName string) protoreflect.F
fd = getDescriptorByFieldAndName(fields, strings.TrimSuffix(fieldName, "[]"))
default:
// If the type is map, you get the string "map[kratos]", where "map" is a field of proto and "kratos" is a key of map
// Use symbol . for separating fields/structs. (eg. structfield.field)
// ref: https://github.com/go-playground/form
field, _, err := parseURLQueryMapKey(fieldName)
if err != nil {
break
Expand Down Expand Up @@ -357,8 +361,17 @@ func parseURLQueryMapKey(key string) (string, string, error) {
startIndex = strings.IndexByte(key, '[')
endIndex = strings.IndexByte(key, ']')
)
if startIndex < 0 {
//nolint:gomnd
values := strings.SplitN(key, fieldSeparater, 2)
//nolint:gomnd
if len(values) != 2 {
return "", "", errInvalidFormatMapKey
}
return values[0], values[1], nil
}
if startIndex <= 0 || startIndex >= endIndex || len(key) != endIndex+1 {
return "", "", ErrInvalidFormatMapKey
return "", "", errInvalidFormatMapKey
}
return key[:startIndex], key[startIndex+1 : endIndex], nil
}
36 changes: 27 additions & 9 deletions encoding/form/proto_decode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,24 @@ func TestPopulateMapField(t *testing.T) {
}
}

func TestPopulateMapSepField(t *testing.T) {
query, err := url.ParseQuery("map.name=kratos")
if err != nil {
t.Fatal(err)
}
comp := &complex.Complex{}
field := getFieldDescriptor(comp.ProtoReflect(), "map")
// Fill the comp map field with the url query values
err = populateMapField(field, comp.ProtoReflect().Mutable(field).Map(), []string{"map.name"}, query["map.name"])
if err != nil {
t.Fatal(err)
}
// Get the comp map field value
if query["map.name"][0] != comp.Map["name"] {
t.Errorf("want: %s, got: %s", query, comp.Map)
}
}

func TestParseField(t *testing.T) {
tests := []struct {
name string
Expand Down Expand Up @@ -230,31 +248,31 @@ func TestParseURLQueryMapKey(t *testing.T) {
fieldName: "map[]", field: "map", fieldKey: "", err: nil,
},
{
fieldName: "", field: "", fieldKey: "", err: ErrInvalidFormatMapKey,
fieldName: "", field: "", fieldKey: "", err: errInvalidFormatMapKey,
},
{
fieldName: "[[]", field: "", fieldKey: "", err: ErrInvalidFormatMapKey,
fieldName: "[[]", field: "", fieldKey: "", err: errInvalidFormatMapKey,
},
{
fieldName: "map[kratos]=", field: "", fieldKey: "", err: ErrInvalidFormatMapKey,
fieldName: "map[kratos]=", field: "", fieldKey: "", err: errInvalidFormatMapKey,
},
{
fieldName: "[kratos]", field: "", fieldKey: "", err: ErrInvalidFormatMapKey,
fieldName: "[kratos]", field: "", fieldKey: "", err: errInvalidFormatMapKey,
},
{
fieldName: "map", field: "", fieldKey: "", err: ErrInvalidFormatMapKey,
fieldName: "map", field: "", fieldKey: "", err: errInvalidFormatMapKey,
},
{
fieldName: "map[", field: "", fieldKey: "", err: ErrInvalidFormatMapKey,
fieldName: "map[", field: "", fieldKey: "", err: errInvalidFormatMapKey,
},
{
fieldName: "]kratos[", field: "", fieldKey: "", err: ErrInvalidFormatMapKey,
fieldName: "]kratos[", field: "", fieldKey: "", err: errInvalidFormatMapKey,
},
{
fieldName: "[kratos", field: "", fieldKey: "", err: ErrInvalidFormatMapKey,
fieldName: "[kratos", field: "", fieldKey: "", err: errInvalidFormatMapKey,
},
{
fieldName: "kratos]", field: "", fieldKey: "", err: ErrInvalidFormatMapKey,
fieldName: "kratos]", field: "", fieldKey: "", err: errInvalidFormatMapKey,
},
}
for _, test := range tests {
Expand Down

0 comments on commit 6c026bc

Please sign in to comment.