Skip to content

Commit c1dafed

Browse files
author
Phillip Webb
committed
Refine AntPathMatcher.combine when p1 contains '.'
Refine AntPathMatcher.combine rules to allow direct concatenation of patterns when pattern1 does not contain '*.'. Prior to this commit direct concatenation was allowed when pattern1 did not contain '.', this prevented calls of the form: pathMatcher.combine("/1.0", "/foo/test") from working as expected. This commit also applies some general cleanup to the `combine` method. Issue: SPR-10554
1 parent 57dfc13 commit c1dafed

File tree

2 files changed

+31
-47
lines changed

2 files changed

+31
-47
lines changed

spring-core/src/main/java/org/springframework/util/AntPathMatcher.java

Lines changed: 29 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -317,10 +317,10 @@ public String combine(String pattern1, String pattern2) {
317317
if (!StringUtils.hasText(pattern1) && !StringUtils.hasText(pattern2)) {
318318
return "";
319319
}
320-
else if (!StringUtils.hasText(pattern1)) {
320+
if (!StringUtils.hasText(pattern1)) {
321321
return pattern2;
322322
}
323-
else if (!StringUtils.hasText(pattern2)) {
323+
if (!StringUtils.hasText(pattern2)) {
324324
return pattern1;
325325
}
326326

@@ -330,55 +330,37 @@ else if (!StringUtils.hasText(pattern2)) {
330330
// However /user + /user -> /usr/user ; /{foo} + /bar -> /{foo}/bar
331331
return pattern2;
332332
}
333-
else if (pattern1.endsWith("/*")) {
334-
if (pattern2.startsWith("/")) {
335-
// /hotels/* + /booking -> /hotels/booking
336-
return pattern1.substring(0, pattern1.length() - 1) + pattern2.substring(1);
337-
}
338-
else {
339-
// /hotels/* + booking -> /hotels/booking
340-
return pattern1.substring(0, pattern1.length() - 1) + pattern2;
341-
}
333+
334+
// /hotels/* + /booking -> /hotels/booking
335+
// /hotels/* + booking -> /hotels/booking
336+
if (pattern1.endsWith("/*")) {
337+
return slashConcat(pattern1.substring(0, pattern1.length() - 2), pattern2);
342338
}
343-
else if (pattern1.endsWith("/**")) {
344-
if (pattern2.startsWith("/")) {
345-
// /hotels/** + /booking -> /hotels/**/booking
346-
return pattern1 + pattern2;
347-
}
348-
else {
349-
// /hotels/** + booking -> /hotels/**/booking
350-
return pattern1 + "/" + pattern2;
351-
}
339+
340+
// /hotels/** + /booking -> /hotels/**/booking
341+
// /hotels/** + booking -> /hotels/**/booking
342+
if (pattern1.endsWith("/**")) {
343+
return slashConcat(pattern1, pattern2);
352344
}
353-
else {
354-
int dotPos1 = pattern1.indexOf('.');
355-
if (dotPos1 == -1 || pattern1ContainsUriVar) {
356-
// simply concatenate the two patterns
357-
if (pattern1.endsWith("/") || pattern2.startsWith("/")) {
358-
return pattern1 + pattern2;
359-
}
360-
else {
361-
return pattern1 + "/" + pattern2;
362-
}
363-
}
364-
String fileName1 = pattern1.substring(0, dotPos1);
365-
String extension1 = pattern1.substring(dotPos1);
366-
String fileName2;
367-
String extension2;
368-
int dotPos2 = pattern2.indexOf('.');
369-
if (dotPos2 != -1) {
370-
fileName2 = pattern2.substring(0, dotPos2);
371-
extension2 = pattern2.substring(dotPos2);
372-
}
373-
else {
374-
fileName2 = pattern2;
375-
extension2 = "";
376-
}
377-
String fileName = fileName1.endsWith("*") ? fileName2 : fileName1;
378-
String extension = extension1.startsWith("*") ? extension2 : extension1;
379345

380-
return fileName + extension;
346+
int starDotPos1 = pattern1.indexOf("*.");
347+
if (pattern1ContainsUriVar || starDotPos1 == -1) {
348+
// simply concatenate the two patterns
349+
return slashConcat(pattern1, pattern2);
350+
}
351+
String extension1 = pattern1.substring(starDotPos1 + 1);
352+
int dotPos2 = pattern2.indexOf('.');
353+
String fileName2 = (dotPos2 == -1 ? pattern2 : pattern2.substring(0, dotPos2));
354+
String extension2 = (dotPos2 == -1 ? "" : pattern2.substring(dotPos2));
355+
String extension = extension1.startsWith("*") ? extension2 : extension1;
356+
return fileName2 + extension;
357+
}
358+
359+
private String slashConcat(String path1, String path2) {
360+
if (path1.endsWith("/") || path2.startsWith("/")) {
361+
return path1 + path2;
381362
}
363+
return path1 + "/" + path2;
382364
}
383365

384366
/**

spring-core/src/test/java/org/springframework/util/AntPathMatcherTests.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,7 @@ public void combine() {
399399
assertEquals("/hotels/**/booking", pathMatcher.combine("/hotels/**", "/booking"));
400400
assertEquals("/hotels/booking", pathMatcher.combine("/hotels", "/booking"));
401401
assertEquals("/hotels/booking", pathMatcher.combine("/hotels", "booking"));
402+
assertEquals("/hotels/booking", pathMatcher.combine("/hotels/", "booking"));
402403
assertEquals("/hotels/{hotel}", pathMatcher.combine("/hotels/*", "{hotel}"));
403404
assertEquals("/hotels/**/{hotel}", pathMatcher.combine("/hotels/**", "{hotel}"));
404405
assertEquals("/hotels/{hotel}", pathMatcher.combine("/hotels", "{hotel}"));
@@ -413,6 +414,7 @@ public void combine() {
413414
assertEquals("/{foo}/bar", pathMatcher.combine("/{foo}", "/bar")); // SPR-8858
414415
assertEquals("/user/user", pathMatcher.combine("/user", "/user")); // SPR-7970
415416
assertEquals("/{foo:.*[^0-9].*}/edit/", pathMatcher.combine("/{foo:.*[^0-9].*}", "/edit/")); // SPR-10062
417+
assertEquals("/1.0/foo/test", pathMatcher.combine("/1.0", "/foo/test")); // SPR-10554
416418
}
417419

418420
@Test

0 commit comments

Comments
 (0)