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

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


The following commit(s) were added to refs/heads/10.1.x by this push:
     new 83f43ce443 reject out-of-range values in range and content-range 
parsers
83f43ce443 is described below

commit 83f43ce4436c194cb5a23eccf933d7dfdacbdd8c
Author: sahvx655-wq <[email protected]>
AuthorDate: Wed May 27 16:17:34 2026 +0530

    reject out-of-range values in range and content-range parsers
    
    A numeric field larger than Long.MAX_VALUE let a NumberFormatException 
escape readLong instead of the documented null return, turning a malformed 
range into a 500 in DefaultServlet.
---
 .../tomcat/util/http/parser/ContentRange.java      | 40 +++++++++++++---------
 .../org/apache/tomcat/util/http/parser/Ranges.java | 15 +++++---
 .../apache/tomcat/util/http/parser/TestRanges.java | 26 ++++++++++++++
 webapps/docs/changelog.xml                         |  6 ++++
 4 files changed, 67 insertions(+), 20 deletions(-)

diff --git a/java/org/apache/tomcat/util/http/parser/ContentRange.java 
b/java/org/apache/tomcat/util/http/parser/ContentRange.java
index c0a988e41d..9bae83c905 100644
--- a/java/org/apache/tomcat/util/http/parser/ContentRange.java
+++ b/java/org/apache/tomcat/util/http/parser/ContentRange.java
@@ -113,25 +113,33 @@ public class ContentRange {
         // token and if that something was anything other than LWS the 
following
         // call to readLong() will fail.
 
-        // Start
-        long start = HttpParser.readLong(input);
-
-        // Must be followed by '-'
-        if (HttpParser.skipConstant(input, "-") == SkipResult.NOT_FOUND) {
-            return null;
-        }
-
-        // End
-        long end = HttpParser.readLong(input);
-
-        // Must be followed by '/'
-        if (HttpParser.skipConstant(input, "/") == SkipResult.NOT_FOUND) {
+        long start;
+        long end;
+        long length;
+        try {
+            // Start
+            start = HttpParser.readLong(input);
+
+            // Must be followed by '-'
+            if (HttpParser.skipConstant(input, "-") == SkipResult.NOT_FOUND) {
+                return null;
+            }
+
+            // End
+            end = HttpParser.readLong(input);
+
+            // Must be followed by '/'
+            if (HttpParser.skipConstant(input, "/") == SkipResult.NOT_FOUND) {
+                return null;
+            }
+
+            // Length
+            length = HttpParser.readLong(input);
+        } catch (NumberFormatException nfe) {
+            // A value that doesn't fit in a long can't be a valid content 
range
             return null;
         }
 
-        // Length
-        long length = HttpParser.readLong(input);
-
         // Doesn't matter what we look for, result should be EOF
         SkipResult skipResult = HttpParser.skipConstant(input, "X");
 
diff --git a/java/org/apache/tomcat/util/http/parser/Ranges.java 
b/java/org/apache/tomcat/util/http/parser/Ranges.java
index c2729bf51c..4084ab2a71 100644
--- a/java/org/apache/tomcat/util/http/parser/Ranges.java
+++ b/java/org/apache/tomcat/util/http/parser/Ranges.java
@@ -137,12 +137,19 @@ public class Ranges {
 
         SkipResult skipResult;
         do {
-            long start = HttpParser.readLong(input);
-            // Must be followed by '-'
-            if (HttpParser.skipConstant(input, "-") != SkipResult.FOUND) {
+            long start;
+            long end;
+            try {
+                start = HttpParser.readLong(input);
+                // Must be followed by '-'
+                if (HttpParser.skipConstant(input, "-") != SkipResult.FOUND) {
+                    return null;
+                }
+                end = HttpParser.readLong(input);
+            } catch (NumberFormatException nfe) {
+                // A value that doesn't fit in a long can't be a valid range
                 return null;
             }
-            long end = HttpParser.readLong(input);
 
             if (start == -1 && end == -1) {
                 // Invalid range
diff --git a/test/org/apache/tomcat/util/http/parser/TestRanges.java 
b/test/org/apache/tomcat/util/http/parser/TestRanges.java
index 0e973e0748..06769d0da4 100644
--- a/test/org/apache/tomcat/util/http/parser/TestRanges.java
+++ b/test/org/apache/tomcat/util/http/parser/TestRanges.java
@@ -73,6 +73,20 @@ public class TestRanges {
     }
 
 
+    @Test
+    public void testInvalid07() throws Exception {
+        // End does not fit in a long
+        doTestInvalid("bytes=0-99999999999999999999");
+    }
+
+
+    @Test
+    public void testInvalid08() throws Exception {
+        // Start does not fit in a long
+        doTestInvalid("bytes=99999999999999999999-50");
+    }
+
+
     @Test
     public void testValid01() throws Exception {
         Ranges r = parse("bytes=1-10,21-30");
@@ -118,6 +132,18 @@ public class TestRanges {
     }
 
 
+    @Test
+    public void testValid04() throws Exception {
+        // Long.MAX_VALUE must still be accepted
+        Ranges r = parse("bytes=0-9223372036854775807");
+        List<Entry> l = r.getEntries();
+        Assert.assertEquals(1, l.size());
+        Entry e1 = l.get(0);
+        Assert.assertEquals(0, e1.getStart());
+        Assert.assertEquals(Long.MAX_VALUE, e1.getEnd());
+    }
+
+
     private void doTestInvalid(String s) throws IOException {
         Ranges r = parse(s);
         Assert.assertNull(r);
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index d4f624ea20..65705c6299 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -205,6 +205,12 @@
         looking up resources and behave as if the resources were not found in
         that case. (markt)
       </fix>
+      <fix>
+        Improve validation of <code>Range</code> and <code>Content-Range</code>
+        parsers so invalid ranges trigger a <code>4xx</code> response rather
+        than a <code>500</code> response. Pull request <pr>1012</pr> provided 
by
+        Sahana Surendra Bogar. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">


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

Reply via email to