Skip to content

Commit e115c08

Browse files
authored
Merge commit from fork
* BodyParser: slice/array invalid range - add test case * BodyParser: slice/array invalid range
1 parent d153551 commit e115c08

File tree

2 files changed

+39
-1
lines changed

2 files changed

+39
-1
lines changed

ctx_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,31 @@ func Test_Ctx_BodyParser(t *testing.T) {
654654
})
655655
}
656656

657+
func Test_Ctx_BodyParser_InvalidRequestData(t *testing.T) {
658+
t.Parallel()
659+
660+
type RequestBody struct {
661+
NestedContent []*struct {
662+
Value string `form:"value"`
663+
} `form:"nested-content"`
664+
}
665+
app := New()
666+
c := app.AcquireCtx(&fasthttp.RequestCtx{})
667+
defer app.ReleaseCtx(c)
668+
669+
c.Request().Reset()
670+
c.Request().Header.SetContentType(MIMEApplicationForm)
671+
// Test with invalid form data
672+
c.Request().SetBody([]byte("nested-content[-1].value=Foo&nested-content[0].value=Bar&nested-content[1].value=FooBar"))
673+
c.Request().Header.SetContentLength(len(c.Body()))
674+
675+
subject := new(RequestBody)
676+
err := c.BodyParser(subject)
677+
678+
utils.AssertEqual(t, true, nil != err)
679+
utils.AssertEqual(t, "failed to decode: schema: panic while decoding: reflect: slice index out of range", fmt.Sprintf("%v", err))
680+
}
681+
657682
func Test_Ctx_ParamParser(t *testing.T) {
658683
t.Parallel()
659684
app := New()

internal/schema/decoder.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,24 @@ func (d *Decoder) RegisterConverter(value interface{}, converterFunc Converter)
6767
// Keys are "paths" in dotted notation to the struct fields and nested structs.
6868
//
6969
// See the package documentation for a full explanation of the mechanics.
70-
func (d *Decoder) Decode(dst interface{}, src map[string][]string) error {
70+
func (d *Decoder) Decode(dst interface{}, src map[string][]string) (err error) {
7171
v := reflect.ValueOf(dst)
7272
if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct {
7373
return errors.New("schema: interface must be a pointer to struct")
7474
}
75+
76+
// Catch panics from the decoder and return them as an error.
77+
// This is needed because the decoder calls reflect and reflect panics
78+
defer func() {
79+
if r := recover(); r != nil {
80+
if e, ok := r.(error); ok {
81+
err = e
82+
} else {
83+
err = fmt.Errorf("schema: panic while decoding: %v", r)
84+
}
85+
}
86+
}()
87+
7588
v = v.Elem()
7689
t := v.Type()
7790
multiError := MultiError{}

0 commit comments

Comments
 (0)