Fix <TracePathMatcher should match pattern "**" with paths end by "/"> (#81)

Co-authored-by: Dominik Hubacek <dominik.hubacek@student.tuke.sk>
Co-authored-by: Kanro <higan@live.cn>
This commit is contained in:
DominikHubacek 2021-12-10 12:45:39 +01:00 committed by GitHub
parent ee5bb80fc3
commit 438f287961
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 69 additions and 37 deletions

View File

@ -15,6 +15,7 @@ Release Notes.
* Increase `ProfileTaskChannelService.snapshotQueue` default size from 50 to 4500
* Support 2.8 and 2.9 of pulsar client.
* Add dubbo 3.x plugin.
* Fix TracePathMatcher should match pattern "**" with paths end by "/"
#### Documentation

View File

@ -84,6 +84,22 @@ public class FastPathMatcher implements TracePathMatcher {
private boolean wildcardMatch(String pat, int p, String str, int s) {
char pc = safeCharAt(pat, p);
// End of pattern, check string only has zero or one '/' at end.
//
// pattern: a/* a/*
//
// string: a/bc/ a/bc
if (pc == 0) {
while (true) {
char sc = safeCharAt(str, s);
// No '/' found
if (sc == 0) return true;
// Check '/' is the last char of string
if (sc == '/') return s == str.length() - 1;
s++;
}
}
while (true) {
char sc = safeCharAt(str, s);
@ -122,9 +138,11 @@ public class FastPathMatcher implements TracePathMatcher {
}
private boolean multiWildcardMatch(String pat, int p, String str, int s) {
// End of pattern, just check the end of string is '/' quickly.
if (p >= pat.length() && s < str.length()) {
return str.charAt(str.length() - 1) != '/';
switch (safeCharAt(pat, p)) {
// End of pattern, just return true quickly.
case 0: return true;
// Skip next '/' for pattern to match zero path part.
case '/': p++;
}
while (true) {

View File

@ -28,87 +28,100 @@ public class TracePathMatcherTest {
@Test
public void testAntPathMatcher() {
TracePathMatcher pathMatcher = new FastPathMatcher();
String patten = "/eureka/*";
String pattern = "/eureka/*";
String path = "/eureka/apps";
boolean match = pathMatcher.match(patten, path);
boolean match = pathMatcher.match(pattern, path);
Assert.assertTrue(match);
path = "/eureka/";
match = pathMatcher.match(patten, path);
match = pathMatcher.match(pattern, path);
Assert.assertTrue(match);
path = "/eureka/apps/";
match = pathMatcher.match(patten, path);
Assert.assertFalse(match);
match = pathMatcher.match(pattern, path);
Assert.assertTrue(match);
patten = "/eureka/*/";
pattern = "/eureka/**";
path = "/eureka/apps/";
match = pathMatcher.match(patten, path);
match = pathMatcher.match(pattern, path);
Assert.assertTrue(match);
pattern = "/eureka/*/";
path = "/eureka/apps/";
match = pathMatcher.match(pattern, path);
Assert.assertTrue(match);
path = "/eureka/";
match = pathMatcher.match(patten, path);
match = pathMatcher.match(pattern, path);
Assert.assertFalse(match);
path = "/eureka/apps/list";
match = pathMatcher.match(patten, path);
match = pathMatcher.match(pattern, path);
Assert.assertFalse(match);
path = "/eureka/test";
match = pathMatcher.match(pattern, path);
Assert.assertFalse(match);
patten = "/eureka/**";
pattern = "/eureka/**";
path = "/eureka/";
match = pathMatcher.match(patten, path);
match = pathMatcher.match(pattern, path);
Assert.assertTrue(match);
path = "/eureka/apps/test";
match = pathMatcher.match(patten, path);
match = pathMatcher.match(pattern, path);
Assert.assertTrue(match);
path = "/eureka/apps/test/";
match = pathMatcher.match(patten, path);
Assert.assertFalse(match);
match = pathMatcher.match(pattern, path);
Assert.assertTrue(match);
patten = "eureka/apps/?";
pattern = "eureka/apps/?";
path = "eureka/apps/list";
match = pathMatcher.match(patten, path);
match = pathMatcher.match(pattern, path);
Assert.assertFalse(match);
path = "eureka/apps/";
match = pathMatcher.match(patten, path);
match = pathMatcher.match(pattern, path);
Assert.assertFalse(match);
path = "eureka/apps/a";
match = pathMatcher.match(patten, path);
match = pathMatcher.match(pattern, path);
Assert.assertTrue(match);
patten = "eureka/**/lists";
pattern = "eureka/**/lists";
path = "eureka/apps/lists";
match = pathMatcher.match(patten, path);
match = pathMatcher.match(pattern, path);
Assert.assertTrue(match);
path = "eureka/apps/test/lists";
match = pathMatcher.match(patten, path);
match = pathMatcher.match(pattern, path);
Assert.assertTrue(match);
path = "eureka/apps/test/";
match = pathMatcher.match(patten, path);
match = pathMatcher.match(pattern, path);
Assert.assertFalse(match);
path = "eureka/apps/test";
match = pathMatcher.match(patten, path);
match = pathMatcher.match(pattern, path);
Assert.assertFalse(match);
patten = "eureka/**/test/**";
pattern = "eureka/**/test/**";
path = "eureka/apps/test/list";
match = pathMatcher.match(patten, path);
match = pathMatcher.match(pattern, path);
Assert.assertTrue(match);
path = "eureka/apps/foo/test/list/bar";
match = pathMatcher.match(patten, path);
match = pathMatcher.match(pattern, path);
Assert.assertTrue(match);
path = "eureka/apps/foo/test/list/bar/";
match = pathMatcher.match(patten, path);
Assert.assertFalse(match);
match = pathMatcher.match(pattern, path);
Assert.assertTrue(match);
path = "eureka/apps/test/list";
match = pathMatcher.match(patten, path);
match = pathMatcher.match(pattern, path);
Assert.assertTrue(match);
path = "eureka/test/list";
match = pathMatcher.match(patten, path);
Assert.assertFalse(match);
match = pathMatcher.match(pattern, path);
Assert.assertTrue(match);
patten = "/eureka/**/b/**/*.txt";
pattern = "/eureka/**/b/**/*.txt";
path = "/eureka/a/aa/aaa/b/bb/bbb/xxxxxx.txt";
match = pathMatcher.match(patten, path);
match = pathMatcher.match(pattern, path);
Assert.assertTrue(match);
path = "/eureka/a/aa/aaa/b/bb/bbb/xxxxxx";
match = pathMatcher.match(patten, path);
match = pathMatcher.match(pattern, path);
Assert.assertFalse(match);
pattern = "abc/*";
path = "abc/foo/bar";
match = pathMatcher.match(pattern, path);
Assert.assertFalse(match);
}
}