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

Reply via email to