From 63655425afec4897ad09048a5f85f3af16120130 Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Sat, 1 Mar 2025 14:27:26 +0100 Subject: [PATCH] Fixed incorrect path traversal --- README.md | 1 + Router_test.go | 30 ++++++++++++++++++++++++++++-- Tree.go | 17 +++++++++++++---- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 6dd27c4..2532d80 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,7 @@ data := router.LookupNoAlloc("GET", "/users/42", func(key string, value string) ``` PASS: TestStatic PASS: TestParameter +PASS: TestMixed PASS: TestWildcard PASS: TestMap PASS: TestMethods diff --git a/Router_test.go b/Router_test.go index 4d82073..94ce016 100644 --- a/Router_test.go +++ b/Router_test.go @@ -72,9 +72,35 @@ func TestParameter(t *testing.T) { assert.Equal(t, data, "Comment") } +func TestMixed(t *testing.T) { + r := router.New[string]() + r.Add("GET", "/", "Frontpage") + r.Add("GET", "/blog", "Blog") + r.Add("GET", "/:post", "Post") + r.Add("GET", "/sitemap.txt", "Sitemap") + + data, params := r.Lookup("GET", "/") + assert.Equal(t, len(params), 0) + assert.Equal(t, data, "Frontpage") + + data, params = r.Lookup("GET", "/blog") + assert.Equal(t, len(params), 0) + assert.Equal(t, data, "Blog") + + data, params = r.Lookup("GET", "/software") + assert.Equal(t, len(params), 1) + assert.Equal(t, params[0].Key, "post") + assert.Equal(t, params[0].Value, "software") + assert.Equal(t, data, "Post") + + data, params = r.Lookup("GET", "/sitemap.txt") + assert.Equal(t, len(params), 0) + assert.Equal(t, data, "Sitemap") +} + func TestWildcard(t *testing.T) { r := router.New[string]() - r.Add("GET", "/", "Front page") + r.Add("GET", "/", "Frontpage") r.Add("GET", "/users/:id", "Parameter") r.Add("GET", "/images/static", "Static") r.Add("GET", "/images/*path", "Wildcard") @@ -84,7 +110,7 @@ func TestWildcard(t *testing.T) { data, params := r.Lookup("GET", "/") assert.Equal(t, len(params), 0) - assert.Equal(t, data, "Front page") + assert.Equal(t, data, "Frontpage") data, params = r.Lookup("GET", "/blog-post") assert.Equal(t, len(params), 1) diff --git a/Tree.go b/Tree.go index e1f6bb0..5a72491 100644 --- a/Tree.go +++ b/Tree.go @@ -92,10 +92,12 @@ func (tree *Tree[T]) Lookup(path string) (T, []Parameter) { // LookupNoAlloc finds the data for the given path without using any memory allocations. func (tree *Tree[T]) LookupNoAlloc(path string, addParameter func(key string, value string)) T { var ( - i uint - wildcardPath string - wildcard *treeNode[T] - node = &tree.root + i uint + parameterPath string + wildcardPath string + parameter *treeNode[T] + wildcard *treeNode[T] + node = &tree.root ) // Skip the first loop iteration if the starting characters are equal @@ -115,6 +117,8 @@ begin: wildcardPath = path[i:] } + parameter = node.parameter + parameterPath = path[i:] char := path[i] if char >= node.startIndex && char < node.endIndex { @@ -178,6 +182,11 @@ begin: // node: /|*any // path: /|image.png notFound: + if parameter != nil { + addParameter(parameter.prefix, parameterPath) + return parameter.data + } + if wildcard != nil { addParameter(wildcard.prefix, wildcardPath) return wildcard.data