diff --git a/ctx.go b/ctx.go index 2589f0e3e7..6f414ed56a 100644 --- a/ctx.go +++ b/ctx.go @@ -1306,15 +1306,24 @@ func parseParamSquareBrackets(k string) (string, error) { defer bytebufferpool.Put(bb) kbytes := []byte(k) + openBracketsCount := 0 for i, b := range kbytes { - if b == '[' && kbytes[i+1] != ']' { - if err := bb.WriteByte('.'); err != nil { - return "", fmt.Errorf("failed to write: %w", err) + if b == '[' { + openBracketsCount++ + if i+1 < len(kbytes) && kbytes[i+1] != ']' { + if err := bb.WriteByte('.'); err != nil { + return "", fmt.Errorf("failed to write: %w", err) + } } + continue } - if b == '[' || b == ']' { + if b == ']' { + openBracketsCount-- + if openBracketsCount < 0 { + return "", errors.New("unmatched brackets") + } continue } @@ -1323,6 +1332,10 @@ func parseParamSquareBrackets(k string) (string, error) { } } + if openBracketsCount > 0 { + return "", errors.New("unmatched brackets") + } + return bb.String(), nil } diff --git a/ctx_test.go b/ctx_test.go index a278d2f250..76ee3fa5f7 100644 --- a/ctx_test.go +++ b/ctx_test.go @@ -4508,6 +4508,10 @@ func Test_Ctx_QueryParser(t *testing.T) { utils.AssertEqual(t, nil, c.QueryParser(empty)) utils.AssertEqual(t, 0, len(empty.Hobby)) + c.Request().URI().SetQueryString("id=1&name[=tom") + q = new(Query) + utils.AssertEqual(t, "unmatched brackets", c.QueryParser(q).Error()) + type Query2 struct { Bool bool ID int @@ -4790,6 +4794,10 @@ func Test_Ctx_QueryParser_Schema(t *testing.T) { utils.AssertEqual(t, "doe", cq.Data[1].Name) utils.AssertEqual(t, 12, cq.Data[1].Age) + c.Request().URI().SetQueryString("data[0][name]=john&data[0][age]=10&data[1]name]=doe&data[1][age]=12") + cq = new(CollectionQuery) + utils.AssertEqual(t, "unmatched brackets", c.QueryParser(cq).Error()) + c.Request().URI().SetQueryString("data.0.name=john&data.0.age=10&data.1.name=doe&data.1.age=12") cq = new(CollectionQuery) utils.AssertEqual(t, nil, c.QueryParser(cq))