From fed4391f8752dcc1bdd738d8580b65af81c05146 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Mon, 30 Nov 2015 17:46:28 -0500 Subject: [PATCH] Fix issue in UriTemplate parsing The recent commit 971f04 replaced the use of a NAMES_PATTERN regex in favor of direct parsing in order to deal with nested curly braces. The change also incorrectly replicated this logic which removes a trailing slash after Pattern quoting (and not before): https://github.com/spring-projects/spring-framework/blob/cca037a74df9b87f99858154b47696a9eccf69c8/spring-web/src/main/java/org/springframework/web/util/UriTemplate.java#L207-L210 After some more investigation there doesn't appear to be any scenario where the quoted pattern would end with a trailing slash. It should always end with \E (end of quote) or a ")" (end of group). Nor are there any failing tests so this commit removes the logic altogether. Issue: SPR-13705 --- .../org/springframework/web/util/UriTemplate.java | 11 +++++------ .../springframework/web/util/UriTemplateTests.java | 8 ++++++++ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/util/UriTemplate.java b/spring-web/src/main/java/org/springframework/web/util/UriTemplate.java index 95e8c2d6b7..43d6094396 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UriTemplate.java +++ b/spring-web/src/main/java/org/springframework/web/util/UriTemplate.java @@ -197,6 +197,7 @@ public class UriTemplate implements Serializable { if (c == '{') { level++; if (level == 1) { + // start of URI variable pattern.append(quote(builder)); builder = new StringBuilder(); continue; @@ -205,6 +206,7 @@ public class UriTemplate implements Serializable { else if (c == '}') { level--; if (level == 0) { + // end of URI variable String variable = builder.toString(); int idx = variable.indexOf(':'); if (idx == -1) { @@ -227,14 +229,11 @@ public class UriTemplate implements Serializable { continue; } } - if (i + 1 == uriTemplate.length()) { - if (c != '/') { - builder.append(c); - } - pattern.append(quote(builder)); - } builder.append(c); } + if (builder.length() > 0) { + pattern.append(quote(builder)); + } return new TemplateInfo(variableNames, Pattern.compile(pattern.toString())); } diff --git a/spring-web/src/test/java/org/springframework/web/util/UriTemplateTests.java b/spring-web/src/test/java/org/springframework/web/util/UriTemplateTests.java index 1e0d6c2316..a047af03eb 100644 --- a/spring-web/src/test/java/org/springframework/web/util/UriTemplateTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/UriTemplateTests.java @@ -185,6 +185,14 @@ public class UriTemplateTests { assertTrue(template.matches("/search?query=foo#bar")); } + // SPR-13705 + + @Test + public void matchesWithSlashAtTheEnd() { + UriTemplate uriTemplate = new UriTemplate("/test/"); + assertTrue(uriTemplate.matches("/test/")); + } + @Test public void expandWithDollar() { UriTemplate template = new UriTemplate("/{a}");