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 15850ae805 reject out-of-range values in range and content-range
parsers
15850ae805 is described below
commit 15850ae805a38ed223595721ada1eecd2ba4b82c
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 0d81ef38b9..60d84c9b16 100644
--- a/java/org/apache/tomcat/util/http/parser/Ranges.java
+++ b/java/org/apache/tomcat/util/http/parser/Ranges.java
@@ -131,12 +131,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 7de9dba29b..77d8757b10 100644
--- a/test/org/apache/tomcat/util/http/parser/TestRanges.java
+++ b/test/org/apache/tomcat/util/http/parser/TestRanges.java
@@ -72,6 +72,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");
@@ -109,6 +123,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 08da484694..522202efc5 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -201,6 +201,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]