You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2026/09/30 09:39:50 UTC
(tomcat) 01/07: 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
This is an automated email from the ASF dual-hosted git repository.
rmaucher pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit e9bc42994118108d4a5791bad8bb2da0829623e5
Author: opencode <re...@apache.org>
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 30497ed192..17128b4bec 100644
--- a/java/org/apache/catalina/connector/InputBuffer.java
+++ b/java/org/apache/catalina/connector/InputBuffer.java
@@ -533,8 +533,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: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org