fix(context): prevent PostForm panic when Request is nil

initFormCache called ParseMultipartForm without checking c.Request,
so PostForm getters panicked on contexts from CreateTestContext.
Match initQueryCache by initializing an empty form cache when there
is no request.

Fixes #4772

Signed-off-by: elix3r <157088510+22elix3r@users.noreply.github.com>
This commit is contained in:
elix3r 2026-08-27 07:27:33 +05:30
parent dcaa4296d1
commit 2a5c1cf7ee
2 changed files with 37 additions and 6 deletions

View File

@ -647,14 +647,18 @@ func (c *Context) PostFormArray(key string) (values []string) {
func (c *Context) initFormCache() {
if c.formCache == nil {
c.formCache = make(url.Values)
req := c.Request
if err := req.ParseMultipartForm(c.engine.MaxMultipartMemory); err != nil {
if !errors.Is(err, http.ErrNotMultipart) {
debugPrint("error on parse multipart form array: %v", err)
if c.Request != nil {
c.formCache = make(url.Values)
req := c.Request
if err := req.ParseMultipartForm(c.engine.MaxMultipartMemory); err != nil {
if !errors.Is(err, http.ErrNotMultipart) {
debugPrint("error on parse multipart form array: %v", err)
}
}
c.formCache = req.PostForm
} else {
c.formCache = url.Values{}
}
c.formCache = req.PostForm
}
}

View File

@ -903,6 +903,33 @@ func TestContextDefaultQueryOnEmptyRequest(t *testing.T) {
})
}
func TestContextPostFormOnEmptyRequest(t *testing.T) {
c, _ := CreateTestContext(httptest.NewRecorder()) // here c.Request == nil
assert.NotPanics(t, func() {
value, ok := c.GetPostForm("key")
assert.False(t, ok)
assert.Empty(t, value)
})
assert.NotPanics(t, func() {
assert.Empty(t, c.PostForm("key"))
})
assert.NotPanics(t, func() {
assert.Equal(t, "fallback", c.DefaultPostForm("key", "fallback"))
})
assert.NotPanics(t, func() {
values, ok := c.GetPostFormArray("key")
assert.False(t, ok)
assert.Empty(t, values)
assert.Empty(t, c.PostFormArray("key"))
})
assert.NotPanics(t, func() {
dicts, ok := c.GetPostFormMap("key")
assert.False(t, ok)
assert.Empty(t, dicts)
assert.Empty(t, c.PostFormMap("key"))
})
}
func TestContextQueryAndPostForm(t *testing.T) {
c, _ := CreateTestContext(httptest.NewRecorder())
body := strings.NewReader("foo=bar&page=11&both=&foo=second")