Skip to content

Simplify wildcard replacement in route patterns#1012

Merged
VojtechVitek merged 1 commit intogo-chi:masterfrom
srpvpn:fix-wildcard-collapse
Aug 26, 2025
Merged

Simplify wildcard replacement in route patterns#1012
VojtechVitek merged 1 commit intogo-chi:masterfrom
srpvpn:fix-wildcard-collapse

Conversation

@srpvpn
Copy link
Contributor

@srpvpn srpvpn commented Aug 3, 2025

Replace recursive wildcard collapsing with iterative strings.ReplaceAll
Add tests for consecutive wildcard segments and trailing wildcard behavior

Comment on lines +140 to +141
for strings.Contains(p, "/*/") {
p = strings.ReplaceAll(p, "/*/", "/")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this ever run more than two times?

Do we need the for loop?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used a loop because the original implementation was recursive — I assumed /*/ could appear multiple times, so I kept the behavior but replaced recursion with a loop

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@srpvpn I hear you, it makes sense.

Can you please find out if this needs to be done once, twice or many more times please? I'd rather remove the for loop unless necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@VojtechVitek
ReplaceAll doesn’t handle overlapping patterns — for example, /// becomes /*/, so we need to run it multiple times.
Since paths can have several wildcards in a row, a loop ensures they're all collapsed. The test with three wildcards confirms this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry. My question was if if it ever overlaps more than two times, since you introduced ReplaceAll()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@VojtechVitek
Docs say “ReplaceAll returns a copy of the string s with all non-overlapping instances of old replaced by new”.
Because the scan resumes after the piece it just wrote, any overlap is skipped:

/// --1st pass--> /*/ --2nd pass--> /

So if a router tacks on three-plus /* segments, one call isn’t enough.

Copy link
Contributor

@VojtechVitek VojtechVitek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thank you for you contribution!

@VojtechVitek VojtechVitek merged commit 0265fcd into go-chi:master Aug 26, 2025
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants