(tomcat) 03/03: Fix regression

[email protected]
Newsgroups gmane.comp.jakarta.tomcat.devel
Message-ID <[email protected]>
This is an automated email from the ASF dual-hosted git repository.

markt-asf pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit b86cd17d51a3b0805043e7438efcb23f8a5fdb3d
Author: Mark Thomas <[email protected]>
AuthorDate: Wed Jul 1 11:52:35 2026 +0100

    Fix regression
    
    Co-written with GPT-5.5
---
 java/org/apache/tomcat/util/buf/B2CConverter.java   | 12 +++++++++++-
 .../apache/tomcat/util/buf/TestB2CConverter.java    | 21 +++++++++++++++++++++
 webapps/docs/changelog.xml                          |  4 ++++
 3 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/java/org/apache/tomcat/util/buf/B2CConverter.java b/java/org/apache/tomcat/util/buf/B2CConverter.java
index d58c49033c..6a461f957e 100644
--- a/java/org/apache/tomcat/util/buf/B2CConverter.java
+++ b/java/org/apache/tomcat/util/buf/B2CConverter.java
@@ -287,10 +287,20 @@ public class B2CConverter {
         }
         // Do the decoding and get the results into the byte chunk and the char
         // chunk
+        int bbStart = bb.position();
         result = decoder.decode(bb, cb, endOfInput);
         if (result.isError()) {
             result.throwException();
-        } else if (result.isOverflow() || result.isUnderflow()) {
+        } else if (result.isOverflow()) {
+            // Propagate current positions to the byte chunk and char chunk
+            bc.position(bb.position());
+            cc.limit(cb.position());
+            if (bb.position() == bbStart && bc.remaining() > 0 && bc.remaining() <= leftovers.array().length) {
+                leftovers.limit(leftovers.array().length);
+                leftovers.position(bc.remaining());
+                bc.get(leftovers.array(), 0, bc.remaining());
+            }
+        } else if (result.isUnderflow()) {
             // Propagate current positions to the byte chunk and char chunk
             bc.position(bb.position());
             cc.limit(cb.position());
diff --git a/test/org/apache/tomcat/util/buf/TestB2CConverter.java b/test/org/apache/tomcat/util/buf/TestB2CConverter.java
index 89a4765244..7108b0cfb2 100644
--- a/test/org/apache/tomcat/util/buf/TestB2CConverter.java
+++ b/test/org/apache/tomcat/util/buf/TestB2CConverter.java
@@ -22,6 +22,7 @@ import java.nio.CharBuffer;
 import java.nio.charset.Charset;
 import java.nio.charset.MalformedInputException;
 import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
 import java.util.Locale;
 
 import org.junit.Assert;
@@ -224,6 +225,26 @@ public class TestB2CConverter {
     }
 
 
+    @Test
+    public void testOverflowWithLargeReadBuffer() throws Exception {
+        // Test range of input sizes from default (8kB) to 12kB.
+        for (int i = 0; i < 4096; i++) {
+            B2CConverter conv = new B2CConverter(StandardCharsets.UTF_8);
+            byte[] bytes = new byte[InputBuffer.DEFAULT_BUFFER_SIZE + i];
+            Arrays.fill(bytes, (byte) '0');
+            ByteBuffer bb = ByteBuffer.wrap(bytes);
+            CharBuffer cb = newCharBuffer(InputBuffer.DEFAULT_BUFFER_SIZE);
+            TesterInputBuffer ib = new TesterInputBuffer(bb);
+
+            conv.convert(bb, cb, ib, false);
+
+            Assert.assertEquals(InputBuffer.DEFAULT_BUFFER_SIZE, cb.remaining());
+            Assert.assertEquals(InputBuffer.DEFAULT_BUFFER_SIZE, bb.position());
+            Assert.assertEquals(bytes.length - InputBuffer.DEFAULT_BUFFER_SIZE, bb.remaining());
+        }
+    }
+
+
     @Test
     public void testLeftoverChunkWithTrailingBytes() throws Exception {
         B2CConverter conv = new B2CConverter(StandardCharsets.UTF_8);
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index a5383042c8..a3364a7457 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -161,6 +161,10 @@
         not available when the connector is explicitly configured to use Tomcat
         Native with OpenSSL for TLS. (markt)
       </fix>
+      <fix>
+        Correct a regression introduced in 9.0.119 that broke reading of some
+        request bodies via a Reader. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Jasper">
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.