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

remm 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 88c43c7964 Return 400 for content and range mismatch
88c43c7964 is described below

commit 88c43c79641024b0f8d0b642aeabbb8be24896e7
Author: remm <r...@apache.org>
AuthorDate: Wed Mar 5 11:31:02 2025 +0100

    Return 400 for content and range mismatch
    
    Still hacked together since the existing DefaultServlet
    executePartialPut method signature is not appropriate.
    As suggested in PR#810.
---
 .../apache/catalina/servlets/DefaultServlet.java    | 21 +++++++++++++++++----
 .../catalina/servlets/LocalStrings.properties       |  1 +
 .../catalina/servlets/TestDefaultServletPut.java    |  5 +++++
 webapps/docs/changelog.xml                          |  4 ++++
 4 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/java/org/apache/catalina/servlets/DefaultServlet.java 
b/java/org/apache/catalina/servlets/DefaultServlet.java
index 5ec84477cf..2cd14a2638 100644
--- a/java/org/apache/catalina/servlets/DefaultServlet.java
+++ b/java/org/apache/catalina/servlets/DefaultServlet.java
@@ -612,10 +612,12 @@ public class DefaultServlet extends HttpServlet {
                 resourceInputStream = req.getInputStream();
             } else {
                 tempContentFile = executePartialPut(req, range, path);
-                resourceInputStream = new FileInputStream(tempContentFile);
+                if (tempContentFile != null) {
+                    resourceInputStream = new FileInputStream(tempContentFile);
+                }
             }
 
-            if (resources.write(path, resourceInputStream, true)) {
+            if (resourceInputStream != null && resources.write(path, 
resourceInputStream, true)) {
                 if (resource.exists()) {
                     resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
                 } else {
@@ -623,7 +625,8 @@ public class DefaultServlet extends HttpServlet {
                 }
             } else {
                 try {
-                    resp.sendError(HttpServletResponse.SC_CONFLICT);
+                    resp.sendError(resourceInputStream != null ?
+                            HttpServletResponse.SC_CONFLICT : 
HttpServletResponse.SC_BAD_REQUEST);
                 } catch (IllegalStateException e) {
                     // Already committed, ignore
                 }
@@ -687,12 +690,22 @@ public class DefaultServlet extends HttpServlet {
 
             // Append data in request input stream to contentFile
             randAccessContentFile.seek(range.getStart());
+            long received = 0;
             int numBytesRead;
             byte[] transferBuffer = new byte[BUFFER_SIZE];
             try (BufferedInputStream requestBufInStream = new 
BufferedInputStream(req.getInputStream(), BUFFER_SIZE)) {
                 while ((numBytesRead = 
requestBufInStream.read(transferBuffer)) != -1) {
+                    received += numBytesRead;
+                    if (received > range.getEnd() - range.getStart()) {
+                        throw new 
IllegalStateException(sm.getString("defaultServlet.wrongByteCountForRange",
+                                String.valueOf(received), 
String.valueOf(range.getEnd() - range.getStart())));
+                    }
                     randAccessContentFile.write(transferBuffer, 0, 
numBytesRead);
                 }
+                if (received < range.getEnd() - range.getStart()) {
+                    throw new 
IllegalStateException(sm.getString("defaultServlet.wrongByteCountForRange",
+                            String.valueOf(received), 
String.valueOf(range.getEnd() - range.getStart())));
+                }
             }
 
         } catch (IOException | RuntimeException | Error e) {
@@ -700,7 +713,7 @@ public class DefaultServlet extends HttpServlet {
             if (!contentFile.delete()) {
                 log(sm.getString("defaultServlet.deleteTempFileFailed", 
contentFile.getAbsolutePath()));
             }
-            throw e;
+            return null;
         }
 
         return contentFile;
diff --git a/java/org/apache/catalina/servlets/LocalStrings.properties 
b/java/org/apache/catalina/servlets/LocalStrings.properties
index c09a862802..cf55fcc832 100644
--- a/java/org/apache/catalina/servlets/LocalStrings.properties
+++ b/java/org/apache/catalina/servlets/LocalStrings.properties
@@ -53,6 +53,7 @@ defaultServlet.resource.name=Name
 defaultServlet.resource.size=Size
 defaultServlet.skipfail=Read failed because only [{0}] bytes were available 
but needed to skip [{1}] bytes to reach the start of the requested range
 defaultServlet.unknownBomConfig=Unrecognised value of [{0}] provided for 
useBomIfPresent initialization parameter
+defaultServlet.wrongByteCountForRange=An invalid amount [{0}] of bytes were 
received for range with length [{1}]
 defaultServlet.xslError=XSL transformer error
 
 webdavservlet.externalEntityIgnored=The request included a reference to an 
external entity with PublicID [{0}] and SystemID [{1}] which was ignored
diff --git a/test/org/apache/catalina/servlets/TestDefaultServletPut.java 
b/test/org/apache/catalina/servlets/TestDefaultServletPut.java
index d19b95684d..55a04b79d6 100644
--- a/test/org/apache/catalina/servlets/TestDefaultServletPut.java
+++ b/test/org/apache/catalina/servlets/TestDefaultServletPut.java
@@ -86,6 +86,11 @@ public class TestDefaultServletPut extends TomcatBaseTest {
         // 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 });
+        // Errors due to incorrect length
+        parameterSets.add(new Object[] {
+                "Content-Range: bytes 0-1/" + PATCH_LEN + CRLF, Boolean.FALSE, 
START_TEXT, Boolean.TRUE });
+        parameterSets.add(new Object[] {
+                "Content-Range: bytes 0-19/20" + CRLF, Boolean.FALSE, 
START_TEXT, Boolean.TRUE });
 
         return parameterSets;
     }
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 6f969f1ed0..b2d6b20990 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -150,6 +150,10 @@
         <code>/</code>. (markt)
       </fix>
       <!-- Entries for backport and removal before 12.0.0-M1 below this line 
-->
+      <fix>
+        Return 400 if the amount of content sent for a partial PUT is
+        inconsistent with the range that was specified. (remm)
+      </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

Reply via email to