From 7a16098f38e59887534958a8e79af133d33f794e Mon Sep 17 00:00:00 2001 From: git-hulk Date: Fri, 13 Aug 2021 13:10:29 +0800 Subject: [PATCH] Fix params would out of range with the wrong latest node getValue didn't update the latest node after walking through the path and may regard the static route as the param type, but the params cap was prealloc and cause out of range. For Example: the route was "/a/b/:c/d" and we send the request path "/a/b/c/d1", the params cap was 1 but the `d` would also be regarded as param then would be out of range. --- tree.go | 1 + tree_test.go | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/tree.go b/tree.go index eb549591..6dce1515 100644 --- a/tree.go +++ b/tree.go @@ -496,6 +496,7 @@ walk: // Outer loop for walking the tree if len(n.children) > 0 { path = path[end:] n = n.children[0] + latestNode = n continue walk } diff --git a/tree_test.go b/tree_test.go index ea13c30e..94e6d9c7 100644 --- a/tree_test.go +++ b/tree_test.go @@ -28,8 +28,12 @@ type testRequests []struct { ps Params } -func getParams() *Params { - ps := make(Params, 0, 20) +func getParams(path string) *Params { + paramCnt := countParams(path) + if paramCnt == 0 { + paramCnt = 20 + } + ps := make(Params, 0, paramCnt) return &ps } @@ -40,7 +44,7 @@ func checkRequests(t *testing.T, tree *node, requests testRequests, unescapes .. } for _, request := range requests { - value := tree.getValue(request.path, getParams(), unescape) + value := tree.getValue(request.path, getParams(request.path), unescape) if value.handlers == nil { if !request.nilHandler { @@ -261,6 +265,7 @@ func TestTreeWildcard(t *testing.T) { {"/c/d/e/f/gg", false, "/:cc/:dd/:ee/:ff/gg", Params{Param{Key: "cc", Value: "c"}, Param{Key: "dd", Value: "d"}, Param{Key: "ee", Value: "e"}, Param{Key: "ff", Value: "f"}}}, {"/c/d/e/f/g/hh", false, "/:cc/:dd/:ee/:ff/:gg/hh", Params{Param{Key: "cc", Value: "c"}, Param{Key: "dd", Value: "d"}, Param{Key: "ee", Value: "e"}, Param{Key: "ff", Value: "f"}, Param{Key: "gg", Value: "g"}}}, {"/cc/dd/ee/ff/gg/hh", false, "/:cc/:dd/:ee/:ff/:gg/hh", Params{Param{Key: "cc", Value: "cc"}, Param{Key: "dd", Value: "dd"}, Param{Key: "ee", Value: "ee"}, Param{Key: "ff", Value: "ff"}, Param{Key: "gg", Value: "gg"}}}, + {"/cc/dd/ee/ff/gg/hh1", true, "/:cc/:dd/:ee/:ff/:gg/hh", Params{Param{Key: "cc", Value: "cc"}, Param{Key: "dd", Value: "dd"}, Param{Key: "ee", Value: "ee"}, Param{Key: "ff", Value: "ff"}, Param{Key: "gg", Value: "gg"}}}, {"/get/abc", false, "/get/abc", nil}, {"/get/a", false, "/get/:param", Params{Param{Key: "param", Value: "a"}}}, {"/get/abz", false, "/get/:param", Params{Param{Key: "param", Value: "abz"}}},