fix(routing): guarantee rune-boundary safety during wildcard parameter slicing (#3654)

This commit is contained in:
Harshal Patel 2026-06-05 22:48:39 +05:30
parent d75fcd4c9a
commit 68e3a3d4fe
2 changed files with 40 additions and 0 deletions

View File

@ -3868,3 +3868,38 @@ func BenchmarkGetMapFromFormData(b *testing.B) {
}) })
} }
} }
func TestWildcardParamUnicodeConcurrency(t *testing.T) {
router := New()
router.GET("/user/:name", func(c *Context) {
name := c.Param("name")
assert.NotEmpty(t, name)
})
router.GET("/files/*filepath", func(c *Context) {
filepath := c.Param("filepath")
assert.NotEmpty(t, filepath)
})
var wg sync.WaitGroup
paths := []string{
"/user/जयेश",
"/files/🎉/photo.png",
"/user/こんにちは",
}
for i := 0; i < 20; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for _, p := range paths {
req, _ := http.NewRequest(http.MethodGet, p, nil)
w := httptest.NewRecorder()
router.ServeHTTP(w, req)
assert.Equal(t, http.StatusOK, w.Code)
}
}()
}
wg.Wait()
}

View File

@ -509,6 +509,11 @@ walk: // Outer loop for walking the tree
// Expand slice within preallocated capacity // Expand slice within preallocated capacity
i := len(*value.params) i := len(*value.params)
*value.params = (*value.params)[:i+1] *value.params = (*value.params)[:i+1]
// Ensure 'end' index lands exactly on a valid UTF-8 rune boundary
for end > 0 && end < len(path) && !utf8.RuneStart(path[end]) {
end--
}
val := path[:end] val := path[:end]
if unescape { if unescape {
if v, err := url.QueryUnescape(val); err == nil { if v, err := url.QueryUnescape(val); err == nil {