Skip to content

Commit 386d244

Browse files
fix(tree): correctly expand the capacity of params (#3502)
1 parent 44d0dd7 commit 386d244

File tree

3 files changed

+85
-4
lines changed

3 files changed

+85
-4
lines changed

routes_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,45 @@ func TestRouteParamsByNameWithExtraSlash(t *testing.T) {
337337
assert.Equal(t, "/is/super/great", wild)
338338
}
339339

340+
// TestRouteParamsNotEmpty tests that context parameters will be set
341+
// even if a route with params/wildcards is registered after the context
342+
// initialisation (which happened in a previous requets).
343+
func TestRouteParamsNotEmpty(t *testing.T) {
344+
name := ""
345+
lastName := ""
346+
wild := ""
347+
router := New()
348+
349+
w := PerformRequest(router, http.MethodGet, "/test/john/smith/is/super/great")
350+
351+
assert.Equal(t, http.StatusNotFound, w.Code)
352+
353+
router.GET("/test/:name/:last_name/*wild", func(c *Context) {
354+
name = c.Params.ByName("name")
355+
lastName = c.Params.ByName("last_name")
356+
var ok bool
357+
wild, ok = c.Params.Get("wild")
358+
359+
assert.True(t, ok)
360+
assert.Equal(t, name, c.Param("name"))
361+
assert.Equal(t, lastName, c.Param("last_name"))
362+
363+
assert.Empty(t, c.Param("wtf"))
364+
assert.Empty(t, c.Params.ByName("wtf"))
365+
366+
wtf, ok := c.Params.Get("wtf")
367+
assert.Empty(t, wtf)
368+
assert.False(t, ok)
369+
})
370+
371+
w = PerformRequest(router, http.MethodGet, "/test/john/smith/is/super/great")
372+
373+
assert.Equal(t, http.StatusOK, w.Code)
374+
assert.Equal(t, "john", name)
375+
assert.Equal(t, "smith", lastName)
376+
assert.Equal(t, "/is/super/great", wild)
377+
}
378+
340379
// TestHandleStaticFile - ensure the static file handles properly
341380
func TestRouteStaticFile(t *testing.T) {
342381
// SETUP file

tree.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,14 @@ walk: // Outer loop for walking the tree
497497
}
498498

499499
// Save param value
500-
if params != nil && cap(*params) > 0 {
500+
if params != nil {
501+
// Preallocate capacity if necessary
502+
if cap(*params) < int(globalParamsCount) {
503+
newParams := make(Params, len(*params), globalParamsCount)
504+
copy(newParams, *params)
505+
*params = newParams
506+
}
507+
501508
if value.params == nil {
502509
value.params = params
503510
}
@@ -544,6 +551,13 @@ walk: // Outer loop for walking the tree
544551
case catchAll:
545552
// Save param value
546553
if params != nil {
554+
// Preallocate capacity if necessary
555+
if cap(*params) < int(globalParamsCount) {
556+
newParams := make(Params, len(*params), globalParamsCount)
557+
copy(newParams, *params)
558+
*params = newParams
559+
}
560+
547561
if value.params == nil {
548562
value.params = params
549563
}

tree_test.go

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -893,9 +893,9 @@ func TestTreeInvalidNodeType(t *testing.T) {
893893

894894
func TestTreeInvalidParamsType(t *testing.T) {
895895
tree := &node{}
896-
tree.wildChild = true
897-
tree.children = append(tree.children, &node{})
898-
tree.children[0].nType = 2
896+
// add a child with wildcard
897+
route := "/:path"
898+
tree.addRoute(route, fakeHandler(route))
899899

900900
// set invalid Params type
901901
params := make(Params, 0)
@@ -904,6 +904,34 @@ func TestTreeInvalidParamsType(t *testing.T) {
904904
tree.getValue("/test", &params, getSkippedNodes(), false)
905905
}
906906

907+
func TestTreeExpandParamsCapacity(t *testing.T) {
908+
data := []struct {
909+
path string
910+
}{
911+
{"/:path"},
912+
{"/*path"},
913+
}
914+
915+
for _, item := range data {
916+
tree := &node{}
917+
tree.addRoute(item.path, fakeHandler(item.path))
918+
params := make(Params, 0)
919+
920+
value := tree.getValue("/test", &params, getSkippedNodes(), false)
921+
922+
if value.params == nil {
923+
t.Errorf("Expected %s params to be set, but they weren't", item.path)
924+
continue
925+
}
926+
927+
if len(*value.params) != 1 {
928+
t.Errorf("Wrong number of %s params: got %d, want %d",
929+
item.path, len(*value.params), 1)
930+
continue
931+
}
932+
}
933+
}
934+
907935
func TestTreeWildcardConflictEx(t *testing.T) {
908936
conflicts := [...]struct {
909937
route string

0 commit comments

Comments
 (0)