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 59d0d02d4756bb410c54254d0dfef532a2c676e5
Author: opencode <[email protected]>
AuthorDate: Mon Oct 12 23:08:50 2026 +0200

    Log a warning for an invalid compression attribute value
    
    The setCompression() method of CompressionConfig caught any exception
    raised while parsing the value of the compression attribute of an HTTP
    connector and silently set the compression level to off. An
    administrator typo in server.xml therefore resulted in a silent and
    undetectable loss of response compression. Invalid values are now
    logged with a warning before compression is disabled.
    
    The value is no longer matched strictly. Surrounding whitespace is now
    ignored, so values like "on " or " 2048" behave as intended rather
    than silently disabling compression. A null value previously triggered
    a NullPointerException when the value was matched. It is now treated as
    an invalid value and disables compression.
    
    The broad exception catch was narrowed to the NumberFormatException
    that the parsing of the value can actually raise.
    
    Add unit tests covering the standard values, the minimum response size,
    values with surrounding whitespace and invalid values, including null.
---
 java/org/apache/coyote/CompressionConfig.java      | 13 ++--
 java/org/apache/coyote/LocalStrings.properties     |  1 +
 .../coyote/TestCompressionConfigSetters.java       | 78 ++++++++++++++++++++++
 3 files changed, 88 insertions(+), 4 deletions(-)

diff --git a/java/org/apache/coyote/CompressionConfig.java 
b/java/org/apache/coyote/CompressionConfig.java
index 9f038c8caa..5b30da26f4 100644
--- a/java/org/apache/coyote/CompressionConfig.java
+++ b/java/org/apache/coyote/CompressionConfig.java
@@ -99,10 +99,14 @@ public class CompressionConfig {
      * Set compression level.
      *
      * @param compression One of <code>on</code>, <code>force</code>, 
<code>off</code> or the minimum compression size
-     *                        in bytes which implies <code>on</code>
+     *                        in bytes which implies <code>on</code>. 
Surrounding whitespace is ignored. An invalid
+     *                        value is logged and disables compression.
      */
     public void setCompression(String compression) {
-        switch (compression) {
+        // Trim the value so that surrounding whitespace in the configuration
+        // does not silently disable compression
+        String value = compression == null ? "" : compression.trim();
+        switch (value) {
             case "on" -> this.compressionLevel = 1;
             case "force" -> this.compressionLevel = 2;
             case "off" -> this.compressionLevel = 0;
@@ -110,9 +114,10 @@ public class CompressionConfig {
                 try {
                     // Try to parse compression as an int, which would give the
                     // minimum compression size
-                    setCompressionMinSize(Integer.parseInt(compression));
+                    setCompressionMinSize(Integer.parseInt(value));
                     this.compressionLevel = 1;
-                } catch (Exception e) {
+                } catch (NumberFormatException e) {
+                    
log.warn(sm.getString("compressionConfig.invalidCompressionValue", value));
                     this.compressionLevel = 0;
                 }
             }
diff --git a/java/org/apache/coyote/LocalStrings.properties 
b/java/org/apache/coyote/LocalStrings.properties
index 385f9713fd..a575f15789 100644
--- a/java/org/apache/coyote/LocalStrings.properties
+++ b/java/org/apache/coyote/LocalStrings.properties
@@ -59,6 +59,7 @@ asyncStateMachine.invalidAsyncState=Calling [{0}] is not 
valid for a request wit
 asyncStateMachine.stateChange=Changing async state from [{0}] to [{1}]
 
 compressionConfig.ContentEncodingParseFail=Failed to parse Content-Encoding 
header when checking to see if compression was already in use
+compressionConfig.invalidCompressionValue=The value [{0}] provided for the 
compression attribute is not valid. Compression has been disabled.
 
 continueResponseTiming.invalid=The value [{0}] is not a valid configuration 
option for continueResponseTiming
 
diff --git a/test/org/apache/coyote/TestCompressionConfigSetters.java 
b/test/org/apache/coyote/TestCompressionConfigSetters.java
new file mode 100644
index 0000000000..73d25f72f6
--- /dev/null
+++ b/test/org/apache/coyote/TestCompressionConfigSetters.java
@@ -0,0 +1,78 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.coyote;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestCompressionConfigSetters {
+
+    @Test
+    public void testSetCompressionStandardValues() {
+        CompressionConfig compressionConfig = new CompressionConfig();
+
+        compressionConfig.setCompression("off");
+        Assert.assertEquals("off", compressionConfig.getCompression());
+
+        compressionConfig.setCompression("on");
+        Assert.assertEquals("on", compressionConfig.getCompression());
+
+        compressionConfig.setCompression("force");
+        Assert.assertEquals("force", compressionConfig.getCompression());
+    }
+
+    @Test
+    public void testSetCompressionMinSize() {
+        CompressionConfig compressionConfig = new CompressionConfig();
+
+        compressionConfig.setCompression("1024");
+        Assert.assertEquals("on", compressionConfig.getCompression());
+        Assert.assertEquals(1024, compressionConfig.getCompressionMinSize());
+    }
+
+    @Test
+    public void testSetCompressionTrimmed() {
+        CompressionConfig compressionConfig = new CompressionConfig();
+
+        compressionConfig.setCompression(" on ");
+        Assert.assertEquals("on", compressionConfig.getCompression());
+
+        compressionConfig.setCompression(" force ");
+        Assert.assertEquals("force", compressionConfig.getCompression());
+
+        compressionConfig.setCompression(" 1024 ");
+        Assert.assertEquals("on", compressionConfig.getCompression());
+        Assert.assertEquals(1024, compressionConfig.getCompressionMinSize());
+    }
+
+    @Test
+    public void testSetCompressionInvalid() {
+        CompressionConfig compressionConfig = new CompressionConfig();
+
+        compressionConfig.setCompression("on2");
+        Assert.assertEquals("off", compressionConfig.getCompression());
+
+        compressionConfig.setCompression("");
+        Assert.assertEquals("off", compressionConfig.getCompression());
+
+        compressionConfig.setCompression("   ");
+        Assert.assertEquals("off", compressionConfig.getCompression());
+
+        compressionConfig.setCompression(null);
+        Assert.assertEquals("off", compressionConfig.getCompression());
+    }
+}


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

Reply via email to