This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 11.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/11.0.x by this push: new 6d16ccb45f Refactor creation of RequestDispatcher instances for consistency 6d16ccb45f is described below commit 6d16ccb45ff7f726f87800c3952b824630a2eb4c Author: Mark Thomas <ma...@apache.org> AuthorDate: Wed Jan 22 16:43:15 2025 +0000 Refactor creation of RequestDispatcher instances for consistency Paths should always be processed in this order before mapping - remove query string - remove path parameters - decode - normalize --- .../apache/catalina/core/ApplicationContext.java | 39 ++++++++++------------ ...TestApplicationContextGetRequestDispatcher.java | 14 ++++---- webapps/docs/changelog.xml | 5 +++ 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/java/org/apache/catalina/core/ApplicationContext.java b/java/org/apache/catalina/core/ApplicationContext.java index 806ce3710d..353a16b597 100644 --- a/java/org/apache/catalina/core/ApplicationContext.java +++ b/java/org/apache/catalina/core/ApplicationContext.java @@ -372,36 +372,31 @@ public class ApplicationContext implements ServletContext { queryString = null; } + // From this point, the removal of path parameters, decoding and normalization is only for mapping purposes. // Remove path parameters - String uriNoParams = stripPathParams(uri); + String uriToMap = stripPathParams(uri); + + // Decode only if the uri derived from the provided path is expected to be encoded + if (getContext().getDispatchersUseEncodedPaths()) { + uriToMap = UDecoder.URLDecode(uriToMap, StandardCharsets.UTF_8); + } // Then normalize - String normalizedUri = RequestUtil.normalize(uriNoParams); - if (normalizedUri == null) { + uriToMap = RequestUtil.normalize(uriToMap); + if (uriToMap == null) { + getContext().getLogger().warn(sm.getString("applicationContext.illegalDispatchPath", path), + new IllegalArgumentException()); return null; } - // Mapping is against the normalized uri - + /* + * uri is passed to the constructor for ApplicationDispatcher and is ultimately used as the value for + * getRequestURI() which returns encoded values. getContextPath() returns a decoded value. uri may be encoded or + * not. Need to prepend the context path to uri and ensure the result is correctly encoded. + */ if (getContext().getDispatchersUseEncodedPaths()) { - // Decode - String decodedUri = UDecoder.URLDecode(normalizedUri, StandardCharsets.UTF_8); - - // Security check to catch attempts to encode /../ sequences - normalizedUri = RequestUtil.normalize(decodedUri); - if (!decodedUri.equals(normalizedUri)) { - getContext().getLogger().warn(sm.getString("applicationContext.illegalDispatchPath", path), - new IllegalArgumentException()); - return null; - } - - // URI needs to include the context path uri = URLEncoder.DEFAULT.encode(getContextPath(), StandardCharsets.UTF_8) + uri; } else { - // uri is passed to the constructor for ApplicationDispatcher and is - // ultimately used as the value for getRequestURI() which returns - // encoded values. Therefore, since the value passed in for path - // was decoded, encode uri here. uri = URLEncoder.DEFAULT.encode(getContextPath() + uri, StandardCharsets.UTF_8); } @@ -422,7 +417,7 @@ public class ApplicationContext implements ServletContext { CharChunk uriCC = uriMB.getCharChunk(); try { uriCC.append(context.getPath()); - uriCC.append(normalizedUri); + uriCC.append(uriToMap); service.getMapper().map(context, uriMB, mappingData); if (mappingData.wrapper == null) { return null; diff --git a/test/org/apache/catalina/core/TestApplicationContextGetRequestDispatcher.java b/test/org/apache/catalina/core/TestApplicationContextGetRequestDispatcher.java index ff19ec187c..8845de0a0f 100644 --- a/test/org/apache/catalina/core/TestApplicationContextGetRequestDispatcher.java +++ b/test/org/apache/catalina/core/TestApplicationContextGetRequestDispatcher.java @@ -85,13 +85,6 @@ public class TestApplicationContextGetRequestDispatcher extends TomcatBaseTest { } - @Test - public void testGetRequestDispatcherEncodedTraversal() throws Exception { - doTestGetRequestDispatcher( - true, "/prefix/start", null, "%2E%2E/target", "/target", DispatcherServlet.NULL); - } - - @Test public void testGetRequestDispatcherTraversal01() throws Exception { doTestGetRequestDispatcher( @@ -134,6 +127,13 @@ public class TestApplicationContextGetRequestDispatcher extends TomcatBaseTest { } + @Test + public void testGetRequestDispatcherTraversal07() throws Exception { + doTestGetRequestDispatcher( + true, "/prefix/start", null, "../../target", "/target", DispatcherServlet.NULL); + } + + @Test public void testGetRequestDispatcher01() throws Exception { doTestGetRequestDispatcher( diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index e3f00b3499..d68b16333e 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -165,6 +165,11 @@ <code>DELETE</code> request because the target resource cannot be deleted. Pull request <pr>802</pr> provided by Chenjp. (markt) </fix> + <scode> + Refactor creation of <code>RequestDispatcher</code> instances so that + the processing of the provided path is consistent with normal request + processing. (markt) + </scode> </changelog> </subsection> <subsection name="Coyote"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org