RFR: 8355371: NegativeArraySizeException in print methods in IO or System.console() in JShell
Chen Liang
liach at openjdk.org
Tue Apr 29 20:56:16 UTC 2025
On Sat, 26 Apr 2025 15:54:40 GMT, Tatsunori Uchino <duke at openjdk.org> wrote:
> This PR will fix not only JDK-8355371 but also JDK-8354910. I chose the more serious one.
>
> Note: according to JEP-512 (JDK-8344699), java.io.IO is going to stop using System.console().
> I confirmed it by checking out and building https://github.com/openjdk/jdk/pull/24438. (in that PR, the bug does not occur in `IO.print(ln)`)
>
> Before (Temurin 24):
>
>
> jshell> IO.println("a".repeat(128))
> Exception in thread "output reader" java.lang.NegativeArraySizeException: -128
> | State engine terminated. at jdk.jshell/jdk.jshell.execution.impl.ConsoleImpl$ConsoleOutputStream.readCharsOrNull(ConsoleImpl.java:486)
>
> at jdk.jshell/jdk.jshell.execution.impl.ConsoleImpl$ConsoleOutputStream.write(ConsoleImpl.java:402)
> at java.base/java.io.OutputStream.write(OutputStream.java:167)
> | Restore definitions with: /reload -restore
> at java.base/java.io.OutputStream.write(OutputStream.java:124)
> at jdk.jshell/jdk.jshell.execution.DemultiplexInput.run(DemultiplexInput.java:74)
>
> jshell> IO.println("ドラえもん")
> ←えツモ
>
> jshell> System.console().writer().println("a".repeat(128))
> Exception in thread "output reader" java.lang.NegativeArraySizeException: -128
> at jdk.jshell/jdk.jshell.execution.impl.ConsoleImpl$ConsoleOutputStream.readCharsOrNull(ConsoleImpl.java:486)
> | State engine terminated.
> at jdk.jshell/jdk.jshell.execution.impl.ConsoleImpl$ConsoleOutputStream.write(ConsoleImpl.java:402)
> at java.base/java.io.OutputStream.write(OutputStream.java:167)
> | Restore definitions with: /reload -restore at java.base/java.io.OutputStream.write(OutputStream.java:124)
>
> at jdk.jshell/jdk.jshell.execution.DemultiplexInput.run(DemultiplexInput.java:74)
>
> jshell> System.console().writer().println("ドラえもん")
> ←えツモ
>
>
> After (master & without https://github.com/openjdk/jdk/pull/24438):
>
>
> jshell> IO.println("a".repeat(128))
> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
>
> jshell> IO.println("ドラえもん")
> ドラえもん
>
> jshell> System.console().writer().println("a".repeat(128))
> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
>
> jshell> System.console().writer().println("ドラえもん")
> ドラえもん
>
>
> I don't know how to prepare the template other PRs use or whether outsiders like me may create a PR.
Newcomer notes:
1. Please check this part of the guide https://openjdk.org/guide/#sign-the-oca or the [bot comment](https://github.com/openjdk/jdk/pull/24897#issuecomment-2832348458) for signing the contributor agreement. The robot will automatically update the oca status once you have signed and typed `/signed` command in a github comment.
2. Please check our guide https://openjdk.org/guide for more details (though they are too long and many don't apply to newcomers); for example, these files need license header updates. See https://openjdk.org/guide/#making-a-change.
3. Our bot has a lot of commands. See https://wiki.openjdk.org/display/SKARA/Pull+Request+Commands for details. For example, we have [`/issue`](https://wiki.openjdk.org/display/SKARA/Pull+Request+Commands#PullRequestCommands-/issue) to add other issues fixed by the same PR; you can use that to include the other issue you want.
src/jdk.jshell/share/classes/jdk/jshell/execution/impl/ConsoleImpl.java line 400:
> 398: // Can be negative because directly casted from byte.
> 399: // java.io.OutputStream.write(int b) stipulates "The 24 high-order bits of b are ignored."
> 400: buffer[bp++] = b & 0xff;
I think the cause is that `OutputStream.write(byte[], int, int)` provides negative bytes. I recommend you to update the "can be negative" comment above to be like:
// Can be negative because widening from byte in write(byte[], int, int).
Also note, there is another usage of `b` below in `case READ_CHARS ->` but I think it is also a bug; it should be `readInt(1)`.
-------------
PR Comment: https://git.openjdk.org/jdk/pull/24897#issuecomment-2832518400
PR Review Comment: https://git.openjdk.org/jdk/pull/24897#discussion_r2061536194
More information about the kulla-dev
mailing list