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


The following commit(s) were added to refs/heads/main by this push:
     new 7b7565dc08 Avoid exceptions on invalid content-length
7b7565dc08 is described below

commit 7b7565dc087e53c3ca57823d7111228c197fd1d5
Author: remm <[email protected]>
AuthorDate: Mon Aug 31 15:25:38 2026 +0200

    Avoid exceptions on invalid content-length
---
 java/org/apache/coyote/http2/LocalStrings.properties    |  1 +
 java/org/apache/coyote/http2/Stream.java                | 17 +++++++++++++----
 .../org/apache/tomcat/util/http/LocalStrings.properties |  1 +
 java/org/apache/tomcat/util/http/MimeHeaders.java       |  2 +-
 webapps/docs/changelog.xml                              |  4 ++++
 5 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/java/org/apache/coyote/http2/LocalStrings.properties 
b/java/org/apache/coyote/http2/LocalStrings.properties
index 397de3363b..1663fb0e18 100644
--- a/java/org/apache/coyote/http2/LocalStrings.properties
+++ b/java/org/apache/coyote/http2/LocalStrings.properties
@@ -98,6 +98,7 @@ stream.clientResetRequest=Client reset the stream before the 
request was fully r
 stream.closed=Connection [{0}], Stream [{1}], Unable to write to stream once 
it has been closed
 stream.header.connection=Connection [{0}], Stream [{1}], HTTP header [{2}] is 
not permitted in an HTTP/2 request
 stream.header.contentLength=Connection [{0}], Stream [{1}], The content length 
header value [{2}] does not agree with the size of the data received [{3}]
+stream.header.contentLength.invalid=Connection [{0}], Stream [{1}], The 
content length header was invalid
 stream.header.debug=Connection [{0}], Stream [{1}], HTTP header [{2}], Value 
[{3}]
 stream.header.duplicate=Connection [{0}], Stream [{1}], received multiple 
[{2}] headers
 stream.header.empty=Connection [{0}], Stream [{1}], Invalid empty header name
diff --git a/java/org/apache/coyote/http2/Stream.java 
b/java/org/apache/coyote/http2/Stream.java
index 2d412b318b..0bbbd05b04 100644
--- a/java/org/apache/coyote/http2/Stream.java
+++ b/java/org/apache/coyote/http2/Stream.java
@@ -738,7 +738,7 @@ class Stream extends AbstractNonZeroStream implements 
HeaderEmitter {
     @Override
     final void receivedData(int dataLength) throws Http2Exception {
         contentLengthReceived += dataLength;
-        long contentLengthHeader = coyoteRequest.getContentLengthLong();
+        long contentLengthHeader = getContentLengthLong();
         if (contentLengthHeader > -1 && contentLengthReceived > 
contentLengthHeader) {
             throw new StreamException(
                     sm.getString("stream.header.contentLength", 
getConnectionId(), getIdAsString(),
@@ -752,16 +752,25 @@ class Stream extends AbstractNonZeroStream implements 
HeaderEmitter {
         if (isContentLengthInconsistent()) {
             throw new StreamException(
                     sm.getString("stream.header.contentLength", 
getConnectionId(), getIdAsString(),
-                            
Long.valueOf(coyoteRequest.getContentLengthLong()), 
Long.valueOf(contentLengthReceived)),
+                            Long.valueOf(getContentLengthLong()), 
Long.valueOf(contentLengthReceived)),
                     Http2Error.PROTOCOL_ERROR, getIdAsInt());
         }
         state.receivedEndOfStream();
         inputBuffer.notifyEof();
     }
 
+    final long getContentLengthLong() throws Http2Exception {
+        try {
+            return coyoteRequest.getContentLengthLong();
+        } catch (Exception e) {
+            throw new StreamException(
+                    sm.getString("stream.header.contentLength.invalid", 
getConnectionId(), getIdAsString()),
+                    Http2Error.PROTOCOL_ERROR, getIdAsInt(), e);
+        }
+    }
 
-    final boolean isContentLengthInconsistent() {
-        long contentLengthHeader = coyoteRequest.getContentLengthLong();
+    final boolean isContentLengthInconsistent() throws Http2Exception {
+        long contentLengthHeader = getContentLengthLong();
         return contentLengthHeader > -1 && contentLengthReceived != 
contentLengthHeader;
     }
 
diff --git a/java/org/apache/tomcat/util/http/LocalStrings.properties 
b/java/org/apache/tomcat/util/http/LocalStrings.properties
index 9d0a6f0b3e..432f4424fd 100644
--- a/java/org/apache/tomcat/util/http/LocalStrings.properties
+++ b/java/org/apache/tomcat/util/http/LocalStrings.properties
@@ -22,6 +22,7 @@ cookies.maxCountFail=More than the maximum allowed number of 
cookies, [{0}], wer
 
 cookiesWithoutEquals.invalid=The value [{0}] is not recognised
 
+headers.duplicateUniqueHeader=Duplicate unique header [{0}] found
 headers.maxCountFail=More than the maximum allowed number of headers, [{0}], 
were detected.
 
 parameters.bytes=Start processing with input [{0}]
diff --git a/java/org/apache/tomcat/util/http/MimeHeaders.java 
b/java/org/apache/tomcat/util/http/MimeHeaders.java
index 7b4ba0b58d..3a61c6a5b7 100644
--- a/java/org/apache/tomcat/util/http/MimeHeaders.java
+++ b/java/org/apache/tomcat/util/http/MimeHeaders.java
@@ -388,7 +388,7 @@ public class MimeHeaders {
                 if (result == null) {
                     result = headers[i].getValue();
                 } else {
-                    throw new IllegalArgumentException();
+                    throw new 
IllegalArgumentException(sm.getString("headers.duplicateUniqueHeader", name));
                 }
             }
         }
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 4b9e608d19..8a68f6562d 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -349,6 +349,10 @@
         Fix incorrect initial window size calculation when upgrading to HTTP/2.
         (remm)
       </fix>
+      <fix>
+        Avoid HTTP/2 exceptions with invalid <code>content-length</code>
+        values. (remm)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Jasper">


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

Reply via email to