From 37f96bdf2b3c654a92289617ccba1509a663d130 Mon Sep 17 00:00:00 2001 From: Olivier Lamy Date: Wed, 11 Sep 2019 17:22:14 +1000 Subject: [PATCH] Issue #4075 Accept pattern such /On* and do exact path match (#4080) * Issue #4075 accept url-pattern such /On* as exact match Signed-off-by: olivier lamy * changes after review from Greg Signed-off-by: olivier lamy --- .../jetty/http/pathmap/ServletPathSpec.java | 19 ++++++++++++------- .../jetty/http/pathmap/PathMappingsTest.java | 3 ++- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/ServletPathSpec.java b/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/ServletPathSpec.java index 612e2df5ea7..d214323e6e7 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/ServletPathSpec.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/ServletPathSpec.java @@ -20,9 +20,14 @@ package org.eclipse.jetty.http.pathmap; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.URIUtil; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; public class ServletPathSpec extends PathSpec { + + private static final Logger LOG = Log.getLogger(ServletPathSpec.class); + /** * If a servlet or filter path mapping isn't a suffix mapping, ensure * it starts with '/' @@ -69,13 +74,13 @@ public class ServletPathSpec extends PathSpec super.pathDepth = 0; char lastChar = servletPathSpec.charAt(specLength - 1); // prefix based - if ((servletPathSpec.charAt(0) == '/') && (specLength > 1) && (lastChar == '*')) + if (servletPathSpec.charAt(0) == '/' && servletPathSpec.endsWith("/*")) { this.group = PathSpecGroup.PREFIX_GLOB; this.prefix = servletPathSpec.substring(0, specLength - 2); } // suffix based - else if (servletPathSpec.charAt(0) == '*') + else if (servletPathSpec.charAt(0) == '*' && servletPathSpec.length() > 1) { this.group = PathSpecGroup.SUFFIX_GLOB; this.suffix = servletPathSpec.substring(2, specLength); @@ -84,6 +89,11 @@ public class ServletPathSpec extends PathSpec { this.group = PathSpecGroup.EXACT; this.prefix = servletPathSpec; + if (servletPathSpec.endsWith("*") ) + { + LOG.warn("Suspicious URL pattern: '{}'; see sections 12.1 and 12.2 of the Servlet specification", + servletPathSpec); + } } for (int i = 0; i < specLength; i++) @@ -130,11 +140,6 @@ public class ServletPathSpec extends PathSpec { throw new IllegalArgumentException("Servlet Spec 12.2 violation: glob '*' can only exist at end of prefix based matches: bad spec \"" + servletPathSpec + "\""); } - - if (idx < 1 || servletPathSpec.charAt(idx - 1) != '/') - { - throw new IllegalArgumentException("Servlet Spec 12.2 violation: suffix glob '*' can only exist after '/': bad spec \"" + servletPathSpec + "\""); - } } else if (servletPathSpec.startsWith("*.")) { diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/PathMappingsTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/PathMappingsTest.java index 018dc430f43..a609f55d8ba 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/PathMappingsTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/PathMappingsTest.java @@ -231,6 +231,8 @@ public class PathMappingsTest assertTrue(!new ServletPathSpec("/foo/*").matches("/bar/anything"), "!match /foo/*"); assertTrue(new ServletPathSpec("*.foo").matches("anything.foo"), "match *.foo"); assertTrue(!new ServletPathSpec("*.foo").matches("anything.bar"), "!match *.foo"); + assertTrue(new ServletPathSpec("/On*").matches("/On*"), "match /On*"); + assertTrue(!new ServletPathSpec("/On*").matches("/One"), "!match /One"); assertEquals("10", p.getMatch("/").getResource(), "match / with ''"); @@ -287,7 +289,6 @@ public class PathMappingsTest @ValueSource(strings = { "*", "/foo/*/bar", - "/foo*", "*/foo", "*.foo/*" })