Skip to content

Commit af5f764

Browse files
author
Gary Gregory
committed
Fix infinite loops in ObservableInputStream read(*) when an exception is
caught but not re-thrown.
1 parent 29e4f85 commit af5f764

3 files changed

Lines changed: 33 additions & 6 deletions

File tree

src/changes/changes.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ The <action> type attribute can be add,update,fix,remove.
108108
<action issue="IO-705" dev="ggregory" type="fix" due-to="Hao Zhong, Gary Gregory">
109109
LockableFileWriter.close() should fail when the lock file cannot be deleted.
110110
</action>
111+
<action issue="IO-705" dev="ggregory" type="fix" due-to="Hao Zhong, Gary Gregory">
112+
Fix infinite loops in ObservableInputStream read(*) when an exception is caught but not re-thrown.
113+
</action>
111114
<!-- ADD -->
112115
<action dev="ggregory" type="add" due-to="Gary Gregory">
113116
Add FileSystemProviders class.

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ protected void noteFinished() throws IOException {
244244
private void notify(final byte[] buffer, final int offset, int result, IOException ioe) throws IOException {
245245
if (ioe != null) {
246246
noteError(ioe);
247+
throw ioe;
247248
} else if (result == EOF) {
248249
noteFinished();
249250
} else if (result > 0) {
@@ -257,11 +258,12 @@ public int read() throws IOException {
257258
IOException ioe = null;
258259
try {
259260
result = super.read();
260-
} catch (final IOException pException) {
261-
ioe = pException;
261+
} catch (final IOException ex) {
262+
ioe = ex;
262263
}
263264
if (ioe != null) {
264265
noteError(ioe);
266+
throw ioe;
265267
} else if (result == EOF) {
266268
noteFinished();
267269
} else {
@@ -276,8 +278,8 @@ public int read(final byte[] buffer) throws IOException {
276278
IOException ioe = null;
277279
try {
278280
result = super.read(buffer);
279-
} catch (final IOException pException) {
280-
ioe = pException;
281+
} catch (final IOException ex) {
282+
ioe = ex;
281283
}
282284
notify(buffer, 0, result, ioe);
283285
return result;
@@ -289,8 +291,8 @@ public int read(final byte[] buffer, final int offset, final int length) throws
289291
IOException ioe = null;
290292
try {
291293
result = super.read(buffer, offset, length);
292-
} catch (final IOException pException) {
293-
ioe = pException;
294+
} catch (final IOException ex) {
295+
ioe = ex;
294296
}
295297
notify(buffer, offset, result, ioe);
296298
return result;

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static org.junit.jupiter.api.Assertions.assertEquals;
2020
import static org.junit.jupiter.api.Assertions.assertNotEquals;
2121
import static org.junit.jupiter.api.Assertions.assertTrue;
22+
import static org.junit.jupiter.api.Assertions.assertThrows;
2223

2324
import java.io.ByteArrayInputStream;
2425
import java.io.IOException;
@@ -125,6 +126,27 @@ public long getFinishedCount() {
125126

126127
}
127128

129+
@Test
130+
public void testBrokenInputStreamRead() throws IOException {
131+
try (final ObservableInputStream ois = new ObservableInputStream(new BrokenInputStream())) {
132+
assertThrows(IOException.class, () -> ois.read());
133+
}
134+
}
135+
136+
@Test
137+
public void testBrokenInputStreamReadBuffer() throws IOException {
138+
try (final ObservableInputStream ois = new ObservableInputStream(new BrokenInputStream())) {
139+
assertThrows(IOException.class, () -> ois.read(new byte[1]));
140+
}
141+
}
142+
143+
@Test
144+
public void testBrokenInputStreamReadSubBuffer() throws IOException {
145+
try (final ObservableInputStream ois = new ObservableInputStream(new BrokenInputStream())) {
146+
assertThrows(IOException.class, () -> ois.read(new byte[2], 0, 1));
147+
}
148+
}
149+
128150
/**
129151
* Tests that {@link Observer#data(int)} is called.
130152
*/

0 commit comments

Comments
 (0)