1
0
mirror of https://github.com/gofiber/fiber.git synced 2025-02-22 04:52:42 +00:00

🐛 Fix unexpected result when QueryParser parse slice data type (#1238)

This commit is contained in:
SianLoong 2021-03-25 03:12:57 +08:00 committed by GitHub
parent f3b07df828
commit 861e5d21fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 7 deletions

9
ctx.go
View File

@ -30,6 +30,8 @@ import (
// maxParams defines the maximum number of parameters per route.
const maxParams = 30
const queryTag = "query"
// Ctx represents the Context which hold the HTTP request and response.
// It has methods for the request query string, parameters, body, HTTP headers and so on.
type Ctx struct {
@ -725,7 +727,7 @@ func (c *Ctx) QueryParser(out interface{}) error {
defer decoderPool.Put(decoder)
// Set correct alias tag
decoder.SetAliasTag("query")
decoder.SetAliasTag(queryTag)
data := make(map[string][]string)
c.fasthttp.QueryArgs().VisitAll(func(key []byte, val []byte) {
@ -747,6 +749,7 @@ func (c *Ctx) QueryParser(out interface{}) error {
func equalFieldType(out interface{}, kind reflect.Kind, key string) bool {
// Get type of interface
outTyp := reflect.TypeOf(out).Elem()
key = utils.ToLower(key)
// Must be a struct to match a field
if outTyp.Kind() != reflect.Struct {
return false
@ -770,9 +773,11 @@ func equalFieldType(out interface{}, kind reflect.Kind, key string) bool {
continue
}
// Get tag from field if exist
inputFieldName := typeField.Tag.Get(key)
inputFieldName := typeField.Tag.Get(queryTag)
if inputFieldName == "" {
inputFieldName = typeField.Name
} else {
inputFieldName = strings.Split(inputFieldName, ",")[0]
}
// Compare field/tag with provided key
if utils.ToLower(inputFieldName) == key {

View File

@ -2003,22 +2003,27 @@ func Test_Ctx_QueryParser(t *testing.T) {
utils.AssertEqual(t, 0, len(empty.Hobby))
type Query2 struct {
ID int
Name string
Hobby string
ID int
Name string
Hobby string
FavouriteDrinks []string
Empty []string
No []int64
}
c.Request().URI().SetQueryString("id=1&name=tom&hobby=basketball,football")
c.Request().URI().SetQueryString("id=1&name=tom&hobby=basketball,football&favouriteDrinks=milo,coke,pepsi&empty=&no=1")
q2 := new(Query2)
utils.AssertEqual(t, nil, c.QueryParser(q2))
utils.AssertEqual(t, "basketball,football", q2.Hobby)
utils.AssertEqual(t, []string{"milo", "coke", "pepsi"}, q2.FavouriteDrinks)
utils.AssertEqual(t, []string{}, q2.Empty)
utils.AssertEqual(t, []int64{1}, q2.No)
type RequiredQuery struct {
Name string `query:"name,required"`
}
rq := new(RequiredQuery)
c.Request().URI().SetQueryString("")
fmt.Println(c.QueryParser(rq))
utils.AssertEqual(t, "name is empty", c.QueryParser(rq).Error())
}
@ -2028,6 +2033,21 @@ func Test_Ctx_EqualFieldType(t *testing.T) {
var dummy struct{ f string }
utils.AssertEqual(t, false, equalFieldType(&dummy, reflect.String, "key"))
var dummy2 struct{ f string }
utils.AssertEqual(t, false, equalFieldType(&dummy2, reflect.String, "f"))
var user struct {
Name string
Address string `query:"address"`
Age int `query:"AGE"`
}
utils.AssertEqual(t, true, equalFieldType(&user, reflect.String, "name"))
utils.AssertEqual(t, true, equalFieldType(&user, reflect.String, "Name"))
utils.AssertEqual(t, true, equalFieldType(&user, reflect.String, "address"))
utils.AssertEqual(t, true, equalFieldType(&user, reflect.String, "Address"))
utils.AssertEqual(t, true, equalFieldType(&user, reflect.Int, "AGE"))
utils.AssertEqual(t, true, equalFieldType(&user, reflect.Int, "age"))
}
// go test -v -run=^$ -bench=Benchmark_Ctx_QueryParser -benchmem -count=4