From c5768e07bca2ba1e6671a90951230ce178bbcb0c Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Thu, 26 Oct 2023 11:50:27 +0200 Subject: [PATCH] classlib: fix issue in InputStreamReader --- .../classlib/java/io/TInputStreamReader.java | 5 ++++- .../java/io/InputStreamReaderTest.java | 20 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/classlib/src/main/java/org/teavm/classlib/java/io/TInputStreamReader.java b/classlib/src/main/java/org/teavm/classlib/java/io/TInputStreamReader.java index 73f6d527a..fae9e251b 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/io/TInputStreamReader.java +++ b/classlib/src/main/java/org/teavm/classlib/java/io/TInputStreamReader.java @@ -110,8 +110,11 @@ public class TInputStreamReader extends TReader { if (!inBuffer.hasRemaining() && !fillReadBuffer()) { break; } - if (decoder.decode(inBuffer, outBuffer, streamEof).isOverflow()) { + var result = decoder.decode(inBuffer, outBuffer, streamEof); + if (result.isOverflow()) { break; + } else if (result.isUnderflow()) { + fillReadBuffer(); } } if (!inBuffer.hasRemaining() && streamEof && decoder.flush(outBuffer).isUnderflow()) { diff --git a/tests/src/test/java/org/teavm/classlib/java/io/InputStreamReaderTest.java b/tests/src/test/java/org/teavm/classlib/java/io/InputStreamReaderTest.java index dabe966c0..e901609ba 100644 --- a/tests/src/test/java/org/teavm/classlib/java/io/InputStreamReaderTest.java +++ b/tests/src/test/java/org/teavm/classlib/java/io/InputStreamReaderTest.java @@ -17,8 +17,10 @@ package org.teavm.classlib.java.io; import static org.junit.Assert.assertEquals; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; import org.junit.Test; import org.junit.runner.RunWith; import org.teavm.junit.TeaVMTestRunner; @@ -78,4 +80,22 @@ public class InputStreamReaderTest { assertEquals(str.charAt(i), chars[i]); } } + + @Test + public void underflowWhileFillingBuffer() throws IOException { + var bos = new ByteArrayOutputStream(); + bos.write(0x24); + for (var i = 0; i < 20000; ++i) { + bos.write(0xC2); + bos.write(0xA2); + } + + var bis = new ByteArrayInputStream(bos.toByteArray()); + var reader = new InputStreamReader(bis, StandardCharsets.UTF_8); + assertEquals(0x24, reader.read()); + for (var i = 0; i < 20000; ++i) { + assertEquals(0xA2, reader.read()); + } + assertEquals(-1, reader.read()); + } }