Skip to content

Commit 5f22162

Browse files
author
Gary Gregory
committed
[IO-716] ReaderInputStream enter infinite loop for too small buffer
sizes.
1 parent ff6fd46 commit 5f22162

3 files changed

Lines changed: 29 additions & 6 deletions

File tree

src/changes/changes.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ The <action> type attribute can be add,update,fix,remove.
9595
<action issue="IO-717" dev="ggregory" type="fix" due-to="Marcono1234, Gary Gregory">
9696
Infinite loop in ReaderInputStream instead of throwing exception for CodingErrorAction.REPORT.
9797
</action>
98+
<action issue="IO-716" dev="ggregory" type="fix" due-to="Marcono1234, Gary Gregory">
99+
ReaderInputStream enter infinite loop for too small buffer sizes.
100+
</action>
98101
<!-- ADD -->
99102
<action dev="ggregory" type="add" due-to="Gary Gregory">
100103
Add BrokenReader.INSTANCE.

src/main/java/org/apache/commons/io/input/ReaderInputStream.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,14 @@
8686
public class ReaderInputStream extends InputStream {
8787
private static final int DEFAULT_BUFFER_SIZE = 1024;
8888

89+
private static int checkBufferSize(int bufferSize) {
90+
if (bufferSize < 2) {
91+
throw new IllegalArgumentException("Buffer size < 2");
92+
}
93+
return bufferSize;
94+
}
8995
private final Reader reader;
96+
9097
private final CharsetEncoder encoder;
9198

9299
/**
@@ -101,8 +108,8 @@ public class ReaderInputStream extends InputStream {
101108
* buffer provided by the caller.
102109
*/
103110
private final ByteBuffer encoderOut;
104-
105111
private CoderResult lastCoderResult;
112+
106113
private boolean endOfInput;
107114

108115
/**
@@ -131,17 +138,17 @@ public ReaderInputStream(final Reader reader, final Charset charset) {
131138
/**
132139
* Constructs a new {@link ReaderInputStream}.
133140
*
134-
* @param reader the target {@link Reader}
135-
* @param charset the charset encoding
136-
* @param bufferSize the size of the input buffer in number of characters
141+
* @param reader the target {@link Reader}.
142+
* @param charset the charset encoding.
143+
* @param bufferSize the size of the input buffer in number of characters.
137144
*/
138145
public ReaderInputStream(final Reader reader, final Charset charset, final int bufferSize) {
139146
// @formatter:off
140147
this(reader,
141148
charset.newEncoder()
142149
.onMalformedInput(CodingErrorAction.REPLACE)
143150
.onUnmappableCharacter(CodingErrorAction.REPLACE),
144-
bufferSize);
151+
checkBufferSize(bufferSize));
145152
// @formatter:on
146153
}
147154

src/test/java/org/apache/commons/io/input/ReaderInputStreamTest.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
package org.apache.commons.io.input;
1818

1919
import static org.junit.jupiter.api.Assertions.assertEquals;
20-
import static org.junit.jupiter.api.Assertions.assertTrue;
2120
import static org.junit.jupiter.api.Assertions.assertThrows;
21+
import static org.junit.jupiter.api.Assertions.assertTrue;
2222

2323
import java.io.CharArrayReader;
2424
import java.io.IOException;
@@ -50,6 +50,19 @@ public class ReaderInputStreamTest {
5050

5151
private final Random random = new Random();
5252

53+
@Test
54+
public void testBufferTooSmall() throws IOException {
55+
assertThrows(IllegalArgumentException.class, () -> new ReaderInputStream(new StringReader("\uD800"), StandardCharsets.UTF_8, 1));
56+
}
57+
58+
@Test
59+
@Timeout(value = 500, unit = TimeUnit.MILLISECONDS)
60+
public void testBufferSmallest() throws IOException {
61+
try (InputStream in = new ReaderInputStream(new StringReader("\uD800"), StandardCharsets.UTF_8, 2)) {
62+
in.read();
63+
}
64+
}
65+
5366
/*
5467
* Tests https://issues.apache.org/jira/browse/IO-277
5568
*/

0 commit comments

Comments
 (0)