This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 9.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/9.0.x by this push: new ca5f5c5770 Align encodedSolidusHandling with servlet spec ca5f5c5770 is described below commit ca5f5c5770263367227880d94583778ed4e7ab25 Author: Mark Thomas <ma...@apache.org> AuthorDate: Mon Nov 11 15:01:00 2024 +0000 Align encodedSolidusHandling with servlet spec --- java/org/apache/tomcat/util/buf/UDecoder.java | 17 +++++++++ test/org/apache/tomcat/util/buf/TestUDecoder.java | 42 +++++++++++++++++++++++ webapps/docs/config/ajp.xml | 9 ++++- webapps/docs/config/http.xml | 9 ++++- 4 files changed, 75 insertions(+), 2 deletions(-) diff --git a/java/org/apache/tomcat/util/buf/UDecoder.java b/java/org/apache/tomcat/util/buf/UDecoder.java index 42f08f6ed6..7eb9ca0266 100644 --- a/java/org/apache/tomcat/util/buf/UDecoder.java +++ b/java/org/apache/tomcat/util/buf/UDecoder.java @@ -149,6 +149,23 @@ public final class UDecoder { buff[idx] = buff[j]; } } + } else if (res == '%') { + /* + * If encoded '/' is going to be left encoded then so must encoded '%' else the subsequent %nn + * decoding will either fail or corrupt the output. + */ + switch (encodedSolidusHandling) { + case DECODE: + case REJECT: { + buff[idx] = (byte) res; + break; + } + case PASS_THROUGH: { + buff[idx++] = buff[j - 2]; + buff[idx++] = buff[j - 1]; + buff[idx] = buff[j]; + } + } } else { buff[idx] = (byte) res; } diff --git a/test/org/apache/tomcat/util/buf/TestUDecoder.java b/test/org/apache/tomcat/util/buf/TestUDecoder.java index b2ca73dd16..94dbd14fb6 100644 --- a/test/org/apache/tomcat/util/buf/TestUDecoder.java +++ b/test/org/apache/tomcat/util/buf/TestUDecoder.java @@ -219,6 +219,48 @@ public class TestUDecoder { } + @Test + public void testURLDecodeStringSolidus10a() throws IOException { + String result = doTestSolidus("xx%25xx", EncodedSolidusHandling.REJECT); + Assert.assertEquals("xx%xx", result); + } + + + @Test + public void testURLDecodeStringSolidus10b() throws IOException { + String result = doTestSolidus("xx%25xx", EncodedSolidusHandling.PASS_THROUGH); + Assert.assertEquals("xx%25xx", result); + } + + + @Test + public void testURLDecodeStringSolidus10c() throws IOException { + String result = doTestSolidus("xx%25xx", EncodedSolidusHandling.DECODE); + Assert.assertEquals("xx%xx", result); + } + + + @Test(expected = CharConversionException.class) + public void testURLDecodeStringSolidus11a() throws IOException { + String result = doTestSolidus("xx%2f%25xx", EncodedSolidusHandling.REJECT); + Assert.assertEquals("xx%xx", result); + } + + + @Test + public void testURLDecodeStringSolidus11b() throws IOException { + String result = doTestSolidus("xx%2f%25xx", EncodedSolidusHandling.PASS_THROUGH); + Assert.assertEquals("xx%2f%25xx", result); + } + + + @Test + public void testURLDecodeStringSolidus11c() throws IOException { + String result = doTestSolidus("xx%2f%25xx", EncodedSolidusHandling.DECODE); + Assert.assertEquals("xx/%xx", result); + } + + private void doTestSolidus(String input, String expected) throws IOException { for (EncodedSolidusHandling solidusHandling : EncodedSolidusHandling.values()) { String result = doTestSolidus(input, solidusHandling); diff --git a/webapps/docs/config/ajp.xml b/webapps/docs/config/ajp.xml index 4c450e94f8..9969f8dc42 100644 --- a/webapps/docs/config/ajp.xml +++ b/webapps/docs/config/ajp.xml @@ -122,7 +122,14 @@ time other <code>%nn</code> sequences are decoded. When set to <code>passthrough</code> request paths containing a <code>%2f</code> sequence will be processed with the <code>%2f</code> sequence unchanged. - If not specified the default value is <code>reject</code>. This default + </p> + <p>If <code>passthrough</code> is used then it is the application's + resposibility to perform any further <code>%nn</code> decoding required. + Any <code>%25</code> sequences (encoded <code>%</code>) in the request + path with also be processed with the <code>%25</code> sequence unchanged + to avoid potential corruption and/or decoding failure when the path is + subsequently <code>%nn</code> decoded by the application.</p> + <p>If not specified the default value is <code>reject</code>. This default may be modified if the deprecated <a href="systemprops.html">system property</a> <code>org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH</code> is diff --git a/webapps/docs/config/http.xml b/webapps/docs/config/http.xml index c20646d2ff..8583da3ecf 100644 --- a/webapps/docs/config/http.xml +++ b/webapps/docs/config/http.xml @@ -120,7 +120,14 @@ time other <code>%nn</code> sequences are decoded. When set to <code>passthrough</code> request paths containing a <code>%2f</code> sequence will be processed with the <code>%2f</code> sequence unchanged. - If not specified the default value is <code>reject</code>. This default + </p> + <p>If <code>passthrough</code> is used then it is the application's + resposibility to perform any further <code>%nn</code> decoding required. + Any <code>%25</code> sequences (encoded <code>%</code>) in the request + path with also be processed with the <code>%25</code> sequence unchanged + to avoid potential corruption and/or decoding failure when the path is + subsequently <code>%nn</code> decoded by the application.</p> + <p>If not specified the default value is <code>reject</code>. This default may be modified if the deprecated <a href="systemprops.html">system property</a> <code>org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH</code> is --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org