Skip to content

Commit 62f66e5

Browse files
authored
🩹 Fix (v3): handle un-matched open brackets in the query params (#3126)
* Add logic for handling unmatched square brackets in query params * Add UTs * Fix lint: fieldalignment error * Add UTs
1 parent f668537 commit 62f66e5

File tree

2 files changed

+88
-5
lines changed

2 files changed

+88
-5
lines changed

binder/mapping.go

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
package binder
22

33
import (
4+
"errors"
45
"reflect"
56
"strings"
67
"sync"
78

8-
"github.com/gofiber/fiber/v3/internal/schema"
99
"github.com/gofiber/utils/v2"
1010
"github.com/valyala/bytebufferpool"
11+
12+
"github.com/gofiber/fiber/v3/internal/schema"
1113
)
1214

1315
// ParserConfig form decoder config for SetParserDecoder
@@ -132,15 +134,24 @@ func parseParamSquareBrackets(k string) (string, error) {
132134
defer bytebufferpool.Put(bb)
133135

134136
kbytes := []byte(k)
137+
openBracketsCount := 0
135138

136139
for i, b := range kbytes {
137-
if b == '[' && kbytes[i+1] != ']' {
138-
if err := bb.WriteByte('.'); err != nil {
139-
return "", err //nolint:wrapcheck // unnecessary to wrap it
140+
if b == '[' {
141+
openBracketsCount++
142+
if i+1 < len(kbytes) && kbytes[i+1] != ']' {
143+
if err := bb.WriteByte('.'); err != nil {
144+
return "", err //nolint:wrapcheck // unnecessary to wrap it
145+
}
140146
}
147+
continue
141148
}
142149

143-
if b == '[' || b == ']' {
150+
if b == ']' {
151+
openBracketsCount--
152+
if openBracketsCount < 0 {
153+
return "", errors.New("unmatched brackets")
154+
}
144155
continue
145156
}
146157

@@ -149,6 +160,10 @@ func parseParamSquareBrackets(k string) (string, error) {
149160
}
150161
}
151162

163+
if openBracketsCount > 0 {
164+
return "", errors.New("unmatched brackets")
165+
}
166+
152167
return bb.String(), nil
153168
}
154169

binder/mapping_test.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package binder
22

33
import (
4+
"errors"
45
"reflect"
56
"testing"
67

@@ -29,3 +30,70 @@ func Test_EqualFieldType(t *testing.T) {
2930
require.True(t, equalFieldType(&user, reflect.Int, "AGE"))
3031
require.True(t, equalFieldType(&user, reflect.Int, "age"))
3132
}
33+
34+
func Test_ParseParamSquareBrackets(t *testing.T) {
35+
tests := []struct {
36+
err error
37+
input string
38+
expected string
39+
}{
40+
{
41+
err: nil,
42+
input: "foo[bar]",
43+
expected: "foo.bar",
44+
},
45+
{
46+
err: nil,
47+
input: "foo[bar][baz]",
48+
expected: "foo.bar.baz",
49+
},
50+
{
51+
err: errors.New("unmatched brackets"),
52+
input: "foo[bar",
53+
expected: "",
54+
},
55+
{
56+
err: errors.New("unmatched brackets"),
57+
input: "foo[bar][baz",
58+
expected: "",
59+
},
60+
{
61+
err: errors.New("unmatched brackets"),
62+
input: "foo]bar[",
63+
expected: "",
64+
},
65+
{
66+
err: nil,
67+
input: "foo[bar[baz]]",
68+
expected: "foo.bar.baz",
69+
},
70+
{
71+
err: nil,
72+
input: "",
73+
expected: "",
74+
},
75+
{
76+
err: nil,
77+
input: "[]",
78+
expected: "",
79+
},
80+
{
81+
err: nil,
82+
input: "foo[]",
83+
expected: "foo",
84+
},
85+
}
86+
87+
for _, tt := range tests {
88+
t.Run(tt.input, func(t *testing.T) {
89+
result, err := parseParamSquareBrackets(tt.input)
90+
if tt.err != nil {
91+
require.Error(t, err)
92+
require.EqualError(t, err, tt.err.Error())
93+
} else {
94+
require.NoError(t, err)
95+
require.Equal(t, tt.expected, result)
96+
}
97+
})
98+
}
99+
}

0 commit comments

Comments
 (0)