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

rmaucher pushed a commit to branch 11.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 0c9837fd065aa4deacf5e7e807473ac0f9e18368
Author: opencode <[email protected]>
AuthorDate: Wed Sep 30 10:53:16 2026 +0200

    Return 0 rather than -1 for zero-length reads from InputBuffer at end of 
stream, as required by the InputStream/Reader contract, and avoid the 
unnecessary blocking fill these requests previously triggered
---
 .../org/apache/catalina/connector/InputBuffer.java |  8 +++++
 .../apache/catalina/connector/TestInputBuffer.java | 39 ++++++++++++++++++++++
 2 files changed, 47 insertions(+)

diff --git a/java/org/apache/catalina/connector/InputBuffer.java 
b/java/org/apache/catalina/connector/InputBuffer.java
index 5fc9285b5e..1c50a0781e 100644
--- a/java/org/apache/catalina/connector/InputBuffer.java
+++ b/java/org/apache/catalina/connector/InputBuffer.java
@@ -395,6 +395,10 @@ public class InputBuffer extends Reader implements 
ByteChunk.ByteInputChannel, A
     public int read(byte[] b, int off, int len) throws IOException {
         throwIfClosed();
 
+        if (len == 0) {
+            return 0;
+        }
+
         if (checkByteBufferEof()) {
             return -1;
         }
@@ -501,6 +505,10 @@ public class InputBuffer extends Reader implements 
ByteChunk.ByteInputChannel, A
     public int read(char[] cbuf, int off, int len) throws IOException {
         throwIfClosed();
 
+        if (len == 0) {
+            return 0;
+        }
+
         if (checkCharBufferEof()) {
             return -1;
         }
diff --git a/test/org/apache/catalina/connector/TestInputBuffer.java 
b/test/org/apache/catalina/connector/TestInputBuffer.java
index bb7ce5ce76..2880a68ace 100644
--- a/test/org/apache/catalina/connector/TestInputBuffer.java
+++ b/test/org/apache/catalina/connector/TestInputBuffer.java
@@ -18,6 +18,7 @@ package org.apache.catalina.connector;
 
 import java.io.BufferedReader;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.Reader;
 import java.io.Writer;
 import java.nio.charset.MalformedInputException;
@@ -135,6 +136,26 @@ public class TestInputBuffer extends TomcatBaseTest {
     }
 
 
+    @Test
+    public void testZeroLengthReadAtEof() throws Exception {
+        Tomcat tomcat = getTomcatInstance();
+        Context root = tomcat.addContext("", TEMP_DIR);
+        Tomcat.addServlet(root, "ZeroRead", new ZeroReadServlet());
+        root.addServletMapping("/test", "ZeroRead");
+
+        tomcat.start();
+
+        ByteChunk bc = new ByteChunk();
+        Map<String,List<String>> responseHeaders = new HashMap<>();
+        int rc = postUrl("abc".getBytes(StandardCharsets.US_ASCII),
+                "http://localhost:"; + getPort() + "/test", bc, 
responseHeaders);
+
+        Assert.assertEquals(HttpServletResponse.SC_OK, rc);
+        // Per the InputStream contract, a zero-length read returns 0, even at 
EOF
+        Assert.assertEquals("0", responseHeaders.get("X-Zero").get(0));
+    }
+
+
     private void doUtf8BodyTest(String description, int[] input, String 
expected) throws Exception {
 
         byte[] bytes = new byte[input.length];
@@ -192,6 +213,24 @@ public class TestInputBuffer extends TomcatBaseTest {
     }
 
 
+    private static class ZeroReadServlet extends HttpServlet {
+
+        private static final long serialVersionUID = 1L;
+
+        @Override
+        protected void doPost(HttpServletRequest req, HttpServletResponse 
resp) throws ServletException, IOException {
+            InputStream is = req.getInputStream();
+            while (is.read() >= 0) {
+                // Drain the body
+            }
+            int zero = is.read(new byte[1], 0, 0);
+
+            resp.setHeader("X-Zero", Integer.toString(zero));
+            resp.getWriter().write("ok");
+        }
+    }
+
+
     private static class SkipServlet extends HttpServlet {
 
         private static final long serialVersionUID = 1L;


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

Reply via email to