-
Bug
-
Resolution: Fixed
-
P4
-
8, 11, 17, 18, 19
-
b25
-
generic
-
generic
-
Verified
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8339333 | 17.0.14 | Paul Hohensee | P4 | Resolved | Fixed | b01 |
ADDITIONAL SYSTEM INFORMATION :
Reproduced with 11.0.14, 17.0.3 and 19-ea+22 on Ubuntu 18.04.
A DESCRIPTION OF THE PROBLEM :
In some circumstances (see the reproducer) InputStreamReader::read(char[], int, int) can return zero while actually consuming a decoded character and writing it into the destination buffer. It happens because StreamDecoder.lockedRead() appears to assume that it's correct to always return "n + implRead(cbuf, off, off + len)" at [1], but it's not so if n == 1 and implRead() returns -1.
Note that the reproducer below is just one of the ways to trigger the bug. Another potential case is when implReady() returns true at [2], but the stream is actually at EOF (which typically doesn't happen, but is not forbidden by the contract of ready()).
[1] https://github.com/openjdk/jdk/blob/69ff86a32088d9664e5e0dae12edddc0643e3fd3/src/java.base/share/classes/sun/nio/cs/StreamDecoder.java#L218
[2] https://github.com/openjdk/jdk/blob/69ff86a32088d9664e5e0dae12edddc0643e3fd3/src/java.base/share/classes/sun/nio/cs/StreamDecoder.java#L204
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the following code.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
a
1
-1
ACTUAL -
a
0
-1
---------- BEGIN SOURCE ----------
import java.io.*;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.StandardCharsets;
class Test {
public static void main(String[] args) throws Exception {
var r = new InputStreamReader(
new ByteArrayInputStream(new byte[] {'a', 'b', (byte) 0xC2}),
StandardCharsets.UTF_8.newDecoder().onMalformedInput(CodingErrorAction.IGNORE));
System.out.println((char)r.read());
System.out.println(r.read(new char[3], 0, 3));
System.out.println(r.read());
}
}
---------- END SOURCE ----------
Reproduced with 11.0.14, 17.0.3 and 19-ea+22 on Ubuntu 18.04.
A DESCRIPTION OF THE PROBLEM :
In some circumstances (see the reproducer) InputStreamReader::read(char[], int, int) can return zero while actually consuming a decoded character and writing it into the destination buffer. It happens because StreamDecoder.lockedRead() appears to assume that it's correct to always return "n + implRead(cbuf, off, off + len)" at [1], but it's not so if n == 1 and implRead() returns -1.
Note that the reproducer below is just one of the ways to trigger the bug. Another potential case is when implReady() returns true at [2], but the stream is actually at EOF (which typically doesn't happen, but is not forbidden by the contract of ready()).
[1] https://github.com/openjdk/jdk/blob/69ff86a32088d9664e5e0dae12edddc0643e3fd3/src/java.base/share/classes/sun/nio/cs/StreamDecoder.java#L218
[2] https://github.com/openjdk/jdk/blob/69ff86a32088d9664e5e0dae12edddc0643e3fd3/src/java.base/share/classes/sun/nio/cs/StreamDecoder.java#L204
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the following code.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
a
1
-1
ACTUAL -
a
0
-1
---------- BEGIN SOURCE ----------
import java.io.*;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.StandardCharsets;
class Test {
public static void main(String[] args) throws Exception {
var r = new InputStreamReader(
new ByteArrayInputStream(new byte[] {'a', 'b', (byte) 0xC2}),
StandardCharsets.UTF_8.newDecoder().onMalformedInput(CodingErrorAction.IGNORE));
System.out.println((char)r.read());
System.out.println(r.read(new char[3], 0, 3));
System.out.println(r.read());
}
}
---------- END SOURCE ----------
- backported by
-
JDK-8339333 InputStreamReader::read() can return zero despite writing a char in the buffer
-
- Resolved
-
- links to
-
Commit openjdk/jdk/6520843f
-
Commit(master) openjdk/jdk17u-dev/42b5e12b
-
Review openjdk/jdk/8895
-
Review(master) openjdk/jdk17u-dev/2726