You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2026/10/07 16:48:55 UTC
(tomcat) 10/16: Ignore malformed Accept-Encoding q-values in DefaultServlet precompressed handling
This is an automated email from the ASF dual-hosted git repository.
rmaucher pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 449e4ebd189334fee3d15b0becd404b9775eac53
Author: opencode <re...@apache.org>
AuthorDate: Wed Oct 7 16:48:49 2026 +0200
Ignore malformed Accept-Encoding q-values in DefaultServlet precompressed handling
Double.parseDouble() of the q-value in getBestPrecompressedResource()
was unprotected, so a client header such as Accept-Encoding: br;q=abc
triggered a NumberFormatException and the request failed with a 500
whenever a precompressed variant of the requested resource existed.
Skip a preference with an unparsable q-value instead, consistent with
treating it as not expressed.
---
.../apache/catalina/servlets/DefaultServlet.java | 7 ++-
.../catalina/servlets/TestDefaultServlet.java | 65 ++++++++++++++++++++++
2 files changed, 71 insertions(+), 1 deletion(-)
diff --git a/java/org/apache/catalina/servlets/DefaultServlet.java b/java/org/apache/catalina/servlets/DefaultServlet.java
index 6f2afb6b48..988bd894e6 100644
--- a/java/org/apache/catalina/servlets/DefaultServlet.java
+++ b/java/org/apache/catalina/servlets/DefaultServlet.java
@@ -1487,7 +1487,12 @@ public class DefaultServlet extends HttpServlet {
if (equalsIdx == -1) {
continue;
}
- quality = Double.parseDouble(preference.substring(equalsIdx + 1).trim());
+ try {
+ quality = Double.parseDouble(preference.substring(equalsIdx + 1).trim());
+ } catch (NumberFormatException nfe) {
+ // Invalid q-value: ignore this preference
+ continue;
+ }
}
if (quality >= bestResourceQuality) {
String encoding = preference;
diff --git a/test/org/apache/catalina/servlets/TestDefaultServlet.java b/test/org/apache/catalina/servlets/TestDefaultServlet.java
index 13a4dd09ce..ca7ef94873 100644
--- a/test/org/apache/catalina/servlets/TestDefaultServlet.java
+++ b/test/org/apache/catalina/servlets/TestDefaultServlet.java
@@ -381,6 +381,71 @@ public class TestDefaultServlet extends TomcatBaseTest {
Assert.assertTrue(responseHeaders.contains("vary: accept-encoding"));
}
+ /*
+ * Verify that a malformed q-value in Accept-Encoding does not fail the
+ * request and only causes the affected preference to be ignored.
+ */
+ @Test
+ public void testMalformedPrecompressedQValue() throws Exception {
+
+ Tomcat tomcat = getTomcatInstance();
+
+ File appDir = new File("test/webapp");
+
+ long gzSize = new File(appDir, "index.html.gz").length();
+ long indexSize = new File(appDir, "index.html").length();
+
+ // app dir is relative to server home
+ Context ctxt = tomcat.addContext("", appDir.getAbsolutePath());
+ Wrapper defaultServlet = Tomcat.addServlet(ctxt, "default",
+ DefaultServlet.class.getName());
+ defaultServlet.addInitParameter("precompressed", "br=.br,gzip=.gz");
+ defaultServlet.addInitParameter("fileEncoding", "ISO-8859-1");
+
+ ctxt.addServletMapping("/", "default");
+ ctxt.addMimeMapping("html", "text/html");
+
+ tomcat.start();
+
+ TestCompressedClient client = new TestCompressedClient(getPort());
+
+ client.reset();
+ // @formatter:off
+ client.setRequest(new String[] {
+ "GET /index.html HTTP/1.1" + CRLF +
+ "Host: localhost" + CRLF +
+ "Connection: Close" + CRLF +
+ "Accept-Encoding: br;q=abc" + CRLF +
+ CRLF
+ });
+ // @formatter:on
+ client.connect();
+ client.processRequest();
+ Assert.assertTrue(client.isResponse200());
+ List<String> responseHeaders = client.getResponseHeaders();
+ Assert.assertFalse(responseHeaders.contains("Content-Encoding"));
+ Assert.assertTrue(responseHeaders.contains("Content-Length: " + indexSize));
+ Assert.assertTrue(responseHeaders.contains("vary: accept-encoding"));
+
+ client.reset();
+ // @formatter:off
+ client.setRequest(new String[] {
+ "GET /index.html HTTP/1.1" + CRLF +
+ "Host: localhost" + CRLF +
+ "Connection: Close" + CRLF +
+ "Accept-Encoding: br;q=abc,gzip" + CRLF +
+ CRLF
+ });
+ // @formatter:on
+ client.connect();
+ client.processRequest();
+ Assert.assertTrue(client.isResponse200());
+ responseHeaders = client.getResponseHeaders();
+ Assert.assertTrue(responseHeaders.contains("Content-Encoding: gzip"));
+ Assert.assertTrue(responseHeaders.contains("Content-Length: " + gzSize));
+ Assert.assertTrue(responseHeaders.contains("vary: accept-encoding"));
+ }
+
/*
* Verify preferring of brotli in default configuration for actual Firefox and Chrome requests.
*/
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org