From 7a16098f38e59887534958a8e79af133d33f794e Mon Sep 17 00:00:00 2001 From: git-hulk Date: Fri, 13 Aug 2021 13:10:29 +0800 Subject: [PATCH 1/2] 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 eb549591d6..6dce1515c7 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 ea13c30ee9..94e6d9c7ba 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"}}}, From a1f62a5bc38e318513688feccf770027a5bf27fe Mon Sep 17 00:00:00 2001 From: git-hulk Date: Tue, 24 Aug 2021 10:01:55 +0800 Subject: [PATCH 2/2] Add integration test case --- gin_integration_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/gin_integration_test.go b/gin_integration_test.go index 094c46e871..4369baff30 100644 --- a/gin_integration_test.go +++ b/gin_integration_test.go @@ -524,4 +524,5 @@ func TestTreeRunDynamicRouting(t *testing.T) { testRequest(t, ts.URL+"/a/dd", "404 Not Found") testRequest(t, ts.URL+"/addr/dd/aa", "404 Not Found") testRequest(t, ts.URL+"/something/secondthing/121", "404 Not Found") + testRequest(t, ts.URL+"/cc/dd/ee/ff/gg/hh1", "404 Not Found") }