From e4caf0e671210f8956e6f06ba78a396be23b0c1a Mon Sep 17 00:00:00 2001 From: srpvpn Date: Sun, 3 Aug 2025 21:56:33 +0300 Subject: [PATCH] refactor: iterative wildcard collapsing and add test for consecutive wildcards --- context.go | 9 +++++---- context_test.go | 11 +++++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/context.go b/context.go index aacf6eff..82220730 100644 --- a/context.go +++ b/context.go @@ -133,11 +133,12 @@ func (x *Context) RoutePattern() string { return routePattern } -// replaceWildcards takes a route pattern and recursively replaces all -// occurrences of "/*/" to "/". +// replaceWildcards takes a route pattern and replaces all occurrences of +// "/*/" with "/". It iteratively runs until no wildcards remain to +// correctly handle consecutive wildcards. func replaceWildcards(p string) string { - if strings.Contains(p, "/*/") { - return replaceWildcards(strings.Replace(p, "/*/", "/", -1)) + for strings.Contains(p, "/*/") { + p = strings.ReplaceAll(p, "/*/", "/") } return p } diff --git a/context_test.go b/context_test.go index fa3c9f5b..fa432852 100644 --- a/context_test.go +++ b/context_test.go @@ -91,3 +91,14 @@ func TestRoutePattern(t *testing.T) { t.Fatalf("unexpected non-empty route pattern for nil context: %q", p) } } + +// TestReplaceWildcardsConsecutive ensures multiple consecutive wildcards are +// collapsed into a single slash. +func TestReplaceWildcardsConsecutive(t *testing.T) { + if p := replaceWildcards("/foo/*/*/*/bar"); p != "/foo/bar" { + t.Fatalf("unexpected wildcard replacement: %s", p) + } + if p := replaceWildcards("/foo/*/*/*/bar/*"); p != "/foo/bar/*" { + t.Fatalf("unexpected trailing wildcard behavior: %s", p) + } +}