This is an automated email from the ASF dual-hosted git repository.

markt-asf pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/main by this push:
     new 4e5268e895 Additional per-message deflate validation
4e5268e895 is described below

commit 4e5268e895882980b69fd9f99ba849fdab01b182
Author: Mark Thomas <[email protected]>
AuthorDate: Wed Nov 4 19:17:36 2026 +0000

    Additional per-message deflate validation
---
 java/org/apache/tomcat/websocket/PerMessageDeflate.java  |  5 +++++
 java/org/apache/tomcat/websocket/Util.java               |  7 ++++++-
 .../apache/tomcat/websocket/TestPerMessageDeflate.java   | 16 ++++++++++++++++
 test/org/apache/tomcat/websocket/TestUtil.java           | 14 ++++++++++++++
 4 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/java/org/apache/tomcat/websocket/PerMessageDeflate.java 
b/java/org/apache/tomcat/websocket/PerMessageDeflate.java
index 1d71f6860d..903b8b0bff 100644
--- a/java/org/apache/tomcat/websocket/PerMessageDeflate.java
+++ b/java/org/apache/tomcat/websocket/PerMessageDeflate.java
@@ -165,6 +165,11 @@ public class PerMessageDeflate implements Transformation {
                     } else if (CLIENT_MAX_WINDOW_BITS.equals(param.getName())) 
{
                         if (clientMaxWindowBits == -1) {
                             if (param.getValue() == null) {
+                                if (!isServer) {
+                                    // RFC 7692, section 7.1.2.2: a response 
must include a value
+                                    throw new 
IllegalArgumentException(sm.getString(
+                                            
"perMessageDeflate.invalidParameterValue", CLIENT_MAX_WINDOW_BITS, null));
+                                }
                                 // Hint to server that the client supports this
                                 // option. Java SE API (as of Java 11) does not
                                 // expose the API to control the Window size. 
It is
diff --git a/java/org/apache/tomcat/websocket/Util.java 
b/java/org/apache/tomcat/websocket/Util.java
index e33ba12f21..dc8b5a1e6f 100644
--- a/java/org/apache/tomcat/websocket/Util.java
+++ b/java/org/apache/tomcat/websocket/Util.java
@@ -51,6 +51,7 @@ import jakarta.websocket.PongMessage;
 import jakarta.websocket.Session;
 
 import org.apache.tomcat.InstanceManager;
+import org.apache.tomcat.util.http.parser.HttpParser;
 import org.apache.tomcat.util.res.StringManager;
 import org.apache.tomcat.websocket.pojo.PojoMessageHandlerPartialBinary;
 import org.apache.tomcat.websocket.pojo.PojoMessageHandlerWholeBinary;
@@ -513,7 +514,11 @@ public class Util {
                     int len = value.length();
                     if (len > 1) {
                         if (value.charAt(0) == '\"' && value.charAt(len - 1) 
== '\"') {
-                            value = value.substring(1, value.length() - 1);
+                            String unquoted = HttpParser.unquote(value);
+                            if (unquoted == null) {
+                                throw new 
IllegalArgumentException(sm.getString("util.invalidValue", value));
+                            }
+                            value = unquoted;
                         }
                     }
                 }
diff --git a/test/org/apache/tomcat/websocket/TestPerMessageDeflate.java 
b/test/org/apache/tomcat/websocket/TestPerMessageDeflate.java
index 16c440c6fe..a2ac9021e5 100644
--- a/test/org/apache/tomcat/websocket/TestPerMessageDeflate.java
+++ b/test/org/apache/tomcat/websocket/TestPerMessageDeflate.java
@@ -809,6 +809,22 @@ public class TestPerMessageDeflate {
     }
 
 
+    /*
+     * RFC 7692 section 7.1.2.2: client_max_window_bits may be sent without a 
value in an offer but a response must
+     * include a value. A client must therefore decline a response without a 
value.
+     */
+    @Test
+    public void testClientMaxWindowBitsWithoutValueInResponse() {
+        List<Parameter> parameters = new ArrayList<>();
+        parameters.add(new WsExtensionParameter("client_max_window_bits", 
null));
+        List<List<Parameter>> preferences = new ArrayList<>();
+        preferences.add(parameters);
+
+        Assert.assertNull(PerMessageDeflate.build(preferences, false));
+        Assert.assertNotNull(PerMessageDeflate.build(preferences, true));
+    }
+
+
     private static void assertAccepted(String name, String value) {
         List<Parameter> parameters = new ArrayList<>();
         parameters.add(new WsExtensionParameter(name, value));
diff --git a/test/org/apache/tomcat/websocket/TestUtil.java 
b/test/org/apache/tomcat/websocket/TestUtil.java
index 2dc2b7998c..3837882ecc 100644
--- a/test/org/apache/tomcat/websocket/TestUtil.java
+++ b/test/org/apache/tomcat/websocket/TestUtil.java
@@ -368,6 +368,20 @@ public class TestUtil {
         doTestParseExtensionHeaderSimple(" ext ; a = 1 ; b = 2 ");
     }
 
+    @Test
+    public void testParseExtensionHeaderQuotedPair() {
+        List<Extension> result = new ArrayList<>();
+        Util.parseExtensionHeader(result, "ext;a=\"\\1\\5\"");
+
+        Assert.assertEquals(1, result.size());
+        Assert.assertEquals("15", 
result.get(0).getParameters().get(0).getValue());
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testParseExtensionHeaderQuotedPairEscapedQuote() {
+        Util.parseExtensionHeader(new ArrayList<>(), "ext;a=\"1\\\"5\"");
+    }
+
     private void doTestParseExtensionHeaderSimple(String header) {
         // Simple test
         List<Extension> result = new ArrayList<>();


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to