This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 9.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 2a881a2ee9e54e75443e15676e03b8bca41f22a4 Author: Chenjp <ch...@msn.com> AuthorDate: Thu Nov 28 01:36:53 2024 +0800 Partial put - enhance content range verification (#778) * enhance content range verification ContentRange - add isValid(), more length check. ContentRange - parse(): make sure the not-null return of parse() is valid. force content-range unit in lowercase internally. TestDefaultServletPut - partial put * isValid: remove unnecessary condition. --------- Co-authored-by: Mark Thomas <ma...@apache.org> --- .../apache/catalina/servlets/DefaultServlet.java | 8 +------ .../tomcat/util/http/parser/ContentRange.java | 26 ++++++++++++++++++++-- .../catalina/servlets/TestDefaultServletPut.java | 4 ++++ webapps/docs/changelog.xml | 5 +++++ 4 files changed, 34 insertions(+), 9 deletions(-) diff --git a/java/org/apache/catalina/servlets/DefaultServlet.java b/java/org/apache/catalina/servlets/DefaultServlet.java index 7d5b54bc00..db1cb6dbc9 100644 --- a/java/org/apache/catalina/servlets/DefaultServlet.java +++ b/java/org/apache/catalina/servlets/DefaultServlet.java @@ -1375,9 +1375,8 @@ public class DefaultServlet extends HttpServlet { return null; } - // bytes is the only range unit supported - if (!contentRange.getUnits().equals("bytes")) { + if (!"bytes".equals(contentRange.getUnits())) { response.sendError(HttpServletResponse.SC_BAD_REQUEST); return null; } @@ -1389,11 +1388,6 @@ public class DefaultServlet extends HttpServlet { range.end = contentRange.getEnd(); range.length = contentRange.getLength(); - if (!range.validate()) { - response.sendError(HttpServletResponse.SC_BAD_REQUEST); - return null; - } - return range; } diff --git a/java/org/apache/tomcat/util/http/parser/ContentRange.java b/java/org/apache/tomcat/util/http/parser/ContentRange.java index d77a0e4c41..62a67c4221 100644 --- a/java/org/apache/tomcat/util/http/parser/ContentRange.java +++ b/java/org/apache/tomcat/util/http/parser/ContentRange.java @@ -18,6 +18,7 @@ package org.apache.tomcat.util.http.parser; import java.io.IOException; import java.io.StringReader; +import java.util.Locale; public class ContentRange { @@ -28,13 +29,21 @@ public class ContentRange { public ContentRange(String units, long start, long end, long length) { - this.units = units; + // Units are lower case (RFC 9110, section 14.1) + if (units == null) { + this.units = null; + } else { + this.units = units.toLowerCase(Locale.ENGLISH); + } this.start = start; this.end = end; this.length = length; } + /** + * @return rangeUnits in lower case. + */ public String getUnits() { return units; } @@ -103,6 +112,19 @@ public class ContentRange { return null; } - return new ContentRange(units, start, end, length); + ContentRange contentRange = new ContentRange(units, start, end, length); + if (!contentRange.isValid()) { + // Invalid content range + return null; + } + return contentRange; + } + + + /** + * @return <code>true</code> if the content range is valid, per RFC 9110 section 14.4 + */ + public boolean isValid() { + return start >= 0 && end >= start && length > end; } } diff --git a/test/org/apache/catalina/servlets/TestDefaultServletPut.java b/test/org/apache/catalina/servlets/TestDefaultServletPut.java index 74262979c3..d19b95684d 100644 --- a/test/org/apache/catalina/servlets/TestDefaultServletPut.java +++ b/test/org/apache/catalina/servlets/TestDefaultServletPut.java @@ -53,6 +53,8 @@ public class TestDefaultServletPut extends TomcatBaseTest { // Valid partial PUT parameterSets.add(new Object[] { "Content-Range: bytes 0-" + PATCH_LEN + "/" + START_LEN + CRLF, Boolean.TRUE, END_TEXT, Boolean.TRUE }); + parameterSets.add(new Object[] { + "Content-Range: ByTeS 0-" + PATCH_LEN + "/" + START_LEN + CRLF, Boolean.TRUE, END_TEXT, Boolean.TRUE }); // Full PUT parameterSets.add(new Object[] { "", null, PATCH_TEXT, Boolean.TRUE }); @@ -79,6 +81,8 @@ public class TestDefaultServletPut extends TomcatBaseTest { "Content-Range: bytes 0-5/" + CRLF, Boolean.FALSE, START_TEXT, Boolean.TRUE }); parameterSets.add(new Object[] { "Content-Range: bytes 0-5/0x5" + CRLF, Boolean.FALSE, START_TEXT, Boolean.TRUE }); + parameterSets.add(new Object[] { + "Content-Range: bytes 0-" + PATCH_LEN + "/" + PATCH_LEN + CRLF, Boolean.FALSE, START_TEXT, Boolean.TRUE }); // Valid partial PUT but partial PUT is disabled parameterSets.add(new Object[] { "Content-Range: bytes 0-" + PATCH_LEN + "/" + START_LEN + CRLF, Boolean.TRUE, START_TEXT, Boolean.FALSE }); diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 3eff5efc7c..b2d06183db 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -198,6 +198,11 @@ the requested ranges overlap. Based on pull request <pr>782</pr> provided by Chenjp. (markt) </fix> + <fix> + Enhance Content-Range verification for partial PUT requests handled by + the default swervlet. Provided by Chenjp in pull request <pr>778</pr>. + (markt) + </fix> </changelog> </subsection> <subsection name="Coyote"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org