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 e7766dc99d0e534407e584a314afe9ce27ece1ce
Author: Mark Thomas <[email protected]>
AuthorDate: Wed Jun 3 09:09:05 2026 +0100

    UTF-8 decoder in 9.0.x behaves slightly differently.
    
    If the output CharBuffer is full, it returns overflow even if there are
    insufficient bytes on input to generate more output.
---
 java/org/apache/tomcat/util/buf/B2CConverter.java     |  7 +------
 test/org/apache/tomcat/util/buf/TestB2CConverter.java | 13 ++++++++-----
 2 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/java/org/apache/tomcat/util/buf/B2CConverter.java 
b/java/org/apache/tomcat/util/buf/B2CConverter.java
index 1a81b6870a..45b0af53e5 100644
--- a/java/org/apache/tomcat/util/buf/B2CConverter.java
+++ b/java/org/apache/tomcat/util/buf/B2CConverter.java
@@ -290,12 +290,7 @@ public class B2CConverter {
         result = decoder.decode(bb, cb, endOfInput);
         if (result.isError()) {
             result.throwException();
-        } else if (result.isOverflow()) {
-            // Propagate current positions to the byte chunk and char chunk, if
-            // this continues the char buffer will get resized
-            bc.position(bb.position());
-            cc.limit(cb.position());
-        } else if (result.isUnderflow()) {
+        } else if (result.isOverflow() || 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 bf7b5bb3e1..89a4765244 100644
--- a/test/org/apache/tomcat/util/buf/TestB2CConverter.java
+++ b/test/org/apache/tomcat/util/buf/TestB2CConverter.java
@@ -180,6 +180,7 @@ public class TestB2CConverter {
     @Test
     public void testLeftoverBuffer() throws Exception {
         // E2 8C A8 is the "keyboard" character
+        // Note: UTF-8 decoder behaviour in 9.0.x is different to 10.1.x 
onwards
         B2CConverter conv = new B2CConverter(StandardCharsets.UTF_8);
         ByteBuffer bb = ByteBuffer.allocate(8);
         CharBuffer cb = newCharBuffer(1);
@@ -191,24 +192,26 @@ public class TestB2CConverter {
         conv.convert(bb, cb, ib, false);
         assertCharBufferEquals("A", cb);
 
-        // Will trigger overflow if there is a complete character
+        // Triggers overflow since cb is full
         bb.clear();
         bb.put((byte) 0xE2);
         bb.flip();
         conv.convert(bb, cb, ib, false);
         assertCharBufferEquals("A", cb);
 
-        // NO-OP (underflow)
+        // NO-OP (still overflow)
         conv.convert(bb, cb, ib, false);
         assertCharBufferEquals("A", cb);
 
-        // Adds second byte of an incomplete 3 byte character to leftovers
+        // Further decodes will be NO-OPs until cb is expanded.
+
+        // Provide 2nd byte of 3 byte character. Not read as decoder still 
returns overflow.
         ib.setNextRealBytes(new byte[] { (byte) 0x8C });
         conv.convert(bb, cb, ib, false);
         assertCharBufferEquals("A", cb);
 
-        // Adds final byte of 3 byte character to leftovers. Not converted as 
output will overflow
-        ib.setNextRealBytes(new byte[] { (byte) 0xA8 });
+        // Provide final byte of 3 byte character. Still not read as decoder 
still returns overflow.
+        ib.setNextRealBytes(new byte[] { (byte) 0x8C, (byte) 0xA8 });
         conv.convert(bb, cb, ib, false);
         assertCharBufferEquals("A", cb);
 


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

Reply via email to