Skip to content

Commit 6c026bc

Browse files
authored
bugfix: fix map decode (go-kratos#2979)
* fix map decode * fix lint * fix lint
1 parent a09f4d8 commit 6c026bc

File tree

2 files changed

+42
-11
lines changed

2 files changed

+42
-11
lines changed

encoding/form/proto_decode.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ import (
2020
"google.golang.org/protobuf/types/known/wrapperspb"
2121
)
2222

23-
var ErrInvalidFormatMapKey = errors.New("invalid formatting for map key")
23+
const fieldSeparater = "."
24+
25+
var errInvalidFormatMapKey = errors.New("invalid formatting for map key")
2426

2527
// DecodeValues decode url value into proto message.
2628
func DecodeValues(msg proto.Message, values url.Values) error {
@@ -91,6 +93,8 @@ func getFieldDescriptor(v protoreflect.Message, fieldName string) protoreflect.F
9193
fd = getDescriptorByFieldAndName(fields, strings.TrimSuffix(fieldName, "[]"))
9294
default:
9395
// 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
96+
// Use symbol . for separating fields/structs. (eg. structfield.field)
97+
// ref: https://github.com/go-playground/form
9498
field, _, err := parseURLQueryMapKey(fieldName)
9599
if err != nil {
96100
break
@@ -357,8 +361,17 @@ func parseURLQueryMapKey(key string) (string, string, error) {
357361
startIndex = strings.IndexByte(key, '[')
358362
endIndex = strings.IndexByte(key, ']')
359363
)
364+
if startIndex < 0 {
365+
//nolint:gomnd
366+
values := strings.SplitN(key, fieldSeparater, 2)
367+
//nolint:gomnd
368+
if len(values) != 2 {
369+
return "", "", errInvalidFormatMapKey
370+
}
371+
return values[0], values[1], nil
372+
}
360373
if startIndex <= 0 || startIndex >= endIndex || len(key) != endIndex+1 {
361-
return "", "", ErrInvalidFormatMapKey
374+
return "", "", errInvalidFormatMapKey
362375
}
363376
return key[:startIndex], key[startIndex+1 : endIndex], nil
364377
}

encoding/form/proto_decode_test.go

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,24 @@ func TestPopulateMapField(t *testing.T) {
9797
}
9898
}
9999

100+
func TestPopulateMapSepField(t *testing.T) {
101+
query, err := url.ParseQuery("map.name=kratos")
102+
if err != nil {
103+
t.Fatal(err)
104+
}
105+
comp := &complex.Complex{}
106+
field := getFieldDescriptor(comp.ProtoReflect(), "map")
107+
// Fill the comp map field with the url query values
108+
err = populateMapField(field, comp.ProtoReflect().Mutable(field).Map(), []string{"map.name"}, query["map.name"])
109+
if err != nil {
110+
t.Fatal(err)
111+
}
112+
// Get the comp map field value
113+
if query["map.name"][0] != comp.Map["name"] {
114+
t.Errorf("want: %s, got: %s", query, comp.Map)
115+
}
116+
}
117+
100118
func TestParseField(t *testing.T) {
101119
tests := []struct {
102120
name string
@@ -230,31 +248,31 @@ func TestParseURLQueryMapKey(t *testing.T) {
230248
fieldName: "map[]", field: "map", fieldKey: "", err: nil,
231249
},
232250
{
233-
fieldName: "", field: "", fieldKey: "", err: ErrInvalidFormatMapKey,
251+
fieldName: "", field: "", fieldKey: "", err: errInvalidFormatMapKey,
234252
},
235253
{
236-
fieldName: "[[]", field: "", fieldKey: "", err: ErrInvalidFormatMapKey,
254+
fieldName: "[[]", field: "", fieldKey: "", err: errInvalidFormatMapKey,
237255
},
238256
{
239-
fieldName: "map[kratos]=", field: "", fieldKey: "", err: ErrInvalidFormatMapKey,
257+
fieldName: "map[kratos]=", field: "", fieldKey: "", err: errInvalidFormatMapKey,
240258
},
241259
{
242-
fieldName: "[kratos]", field: "", fieldKey: "", err: ErrInvalidFormatMapKey,
260+
fieldName: "[kratos]", field: "", fieldKey: "", err: errInvalidFormatMapKey,
243261
},
244262
{
245-
fieldName: "map", field: "", fieldKey: "", err: ErrInvalidFormatMapKey,
263+
fieldName: "map", field: "", fieldKey: "", err: errInvalidFormatMapKey,
246264
},
247265
{
248-
fieldName: "map[", field: "", fieldKey: "", err: ErrInvalidFormatMapKey,
266+
fieldName: "map[", field: "", fieldKey: "", err: errInvalidFormatMapKey,
249267
},
250268
{
251-
fieldName: "]kratos[", field: "", fieldKey: "", err: ErrInvalidFormatMapKey,
269+
fieldName: "]kratos[", field: "", fieldKey: "", err: errInvalidFormatMapKey,
252270
},
253271
{
254-
fieldName: "[kratos", field: "", fieldKey: "", err: ErrInvalidFormatMapKey,
272+
fieldName: "[kratos", field: "", fieldKey: "", err: errInvalidFormatMapKey,
255273
},
256274
{
257-
fieldName: "kratos]", field: "", fieldKey: "", err: ErrInvalidFormatMapKey,
275+
fieldName: "kratos]", field: "", fieldKey: "", err: errInvalidFormatMapKey,
258276
},
259277
}
260278
for _, test := range tests {

0 commit comments

Comments
 (0)