This is an automated email from the ASF dual-hosted git repository.
markt-asf 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 6d0831dd83 Additional per-message deflate validation
6d0831dd83 is described below
commit 6d0831dd839bea92542186a71e3e46f630098291
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 0e00e9f534..a4ef21f5fc 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 4f63fc5553..80fb1024d9 100644
--- a/java/org/apache/tomcat/websocket/Util.java
+++ b/java/org/apache/tomcat/websocket/Util.java
@@ -50,6 +50,7 @@ import javax.websocket.PongMessage;
import javax.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;
@@ -541,7 +542,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 e62e825371..83e5acee20 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 b578fb61ee..ed5234b26d 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]