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 dd0febe2f98b2cf53813d8152780eb8f5c93ac00
Author: opencode <[email protected]>
AuthorDate: Wed Sep 30 10:44:48 2026 +0200

    Fix InputBuffer.skip() consuming and returning more characters than 
requested by comparing and advancing by the remaining count (n - nRead) rather 
than the original count, and add a regression test
---
 .../org/apache/catalina/connector/InputBuffer.java |  4 +-
 .../apache/catalina/connector/TestInputBuffer.java | 61 ++++++++++++++++++++++
 2 files changed, 63 insertions(+), 2 deletions(-)

diff --git a/java/org/apache/catalina/connector/InputBuffer.java 
b/java/org/apache/catalina/connector/InputBuffer.java
index 10fe74c300..5fc9285b5e 100644
--- a/java/org/apache/catalina/connector/InputBuffer.java
+++ b/java/org/apache/catalina/connector/InputBuffer.java
@@ -520,8 +520,8 @@ public class InputBuffer extends Reader implements 
ByteChunk.ByteInputChannel, A
 
         long nRead = 0;
         while (nRead < n) {
-            if (cb.remaining() >= n) {
-                cb.position(cb.position() + (int) n);
+            if (cb.remaining() >= (n - nRead)) {
+                cb.position(cb.position() + (int) (n - nRead));
                 nRead = n;
             } else {
                 nRead += cb.remaining();
diff --git a/test/org/apache/catalina/connector/TestInputBuffer.java 
b/test/org/apache/catalina/connector/TestInputBuffer.java
index 55d3ad142f..bb7ce5ce76 100644
--- a/test/org/apache/catalina/connector/TestInputBuffer.java
+++ b/test/org/apache/catalina/connector/TestInputBuffer.java
@@ -23,6 +23,9 @@ import java.io.Writer;
 import java.nio.charset.MalformedInputException;
 import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 import jakarta.servlet.ServletException;
 import jakarta.servlet.http.HttpServlet;
@@ -102,6 +105,36 @@ public class TestInputBuffer extends TomcatBaseTest {
     }
 
 
+    @Test
+    public void testSkip() throws Exception {
+        Tomcat tomcat = getTomcatInstance();
+        Context root = tomcat.addContext("", TEMP_DIR);
+        Tomcat.addServlet(root, "Skip", new SkipServlet());
+        root.addServletMapping("/test", "Skip");
+
+        // Limit socket reads to 10 bytes so skip() has to refill repeatedly
+        
Assert.assertTrue(tomcat.getConnector().setProperty("socket.appReadBufSize", 
"10"));
+
+        tomcat.start();
+
+        StringBuilder body = new StringBuilder();
+        for (int i = 0; i < 210; i++) {
+            body.append((char) ('a' + i % 26));
+        }
+
+        ByteChunk bc = new ByteChunk();
+        Map<String,List<String>> responseHeaders = new HashMap<>();
+        int rc = postUrl(body.toString().getBytes(StandardCharsets.US_ASCII),
+                "http://localhost:"; + getPort() + "/test", bc, 
responseHeaders);
+        bc.setCharset(StandardCharsets.US_ASCII);
+
+        Assert.assertEquals(HttpServletResponse.SC_OK, rc);
+        // One character read, then 20 skipped before the remainder was echoed
+        Assert.assertEquals("20", responseHeaders.get("X-Skip").get(0));
+        Assert.assertEquals(body.substring(21), bc.toString());
+    }
+
+
     private void doUtf8BodyTest(String description, int[] input, String 
expected) throws Exception {
 
         byte[] bytes = new byte[input.length];
@@ -159,6 +192,34 @@ public class TestInputBuffer extends TomcatBaseTest {
     }
 
 
+    private static class SkipServlet extends HttpServlet {
+
+        private static final long serialVersionUID = 1L;
+
+        @Override
+        protected void doPost(HttpServletRequest req, HttpServletResponse 
resp) throws ServletException, IOException {
+            Reader r = req.getReader();
+            StringBuilder result = new StringBuilder();
+
+            // Consume one character so the skip below starts with 9 buffered 
chars
+            r.read();
+            long skipped = r.skip(20);
+
+            char[] cbuf = new char[80];
+            int n = r.read(cbuf);
+            while (n > 0) {
+                result.append(cbuf, 0, n);
+                n = r.read(cbuf);
+            }
+
+            resp.setHeader("X-Skip", Long.toString(skipped));
+            resp.setContentType("text/plain");
+            resp.setCharacterEncoding("US-ASCII");
+            resp.getWriter().write(result.toString());
+        }
+    }
+
+
     private static class Bug60400Servlet 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