Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8355371

NegativeArraySizeException in print methods in IO or System.console() in JShell

XMLWordPrintable

    • b22
    • generic
    • generic

      ADDITIONAL SYSTEM INFORMATION :
      openjdk 25-ea 2025-09-16
      OpenJDK Runtime Environment (build 25-ea+19-2255)
      OpenJDK 64-Bit Server VM (build 25-ea+19-2255, mixed mode, sharing)

      Ubuntu 24.04 in WSL (Windows 11)

      However, Java 21 (Temurin) + Windows 11 can reproduce this bug too.

      openjdk 21.0.3 2024-04-16 LTS
      OpenJDK Runtime Environment Temurin-21.0.3+9 (build 21.0.3+9-LTS)
      OpenJDK 64-Bit Server VM Temurin-21.0.3+9 (build 21.0.3+9-LTS, mixed mode, sharing)

      A DESCRIPTION OF THE PROBLEM :
      Print functions in IO, System.console(), or System.console().writer() like IO.println throws an NegativeArraySizeException when a string with a specific length is passed only in JShell.

      The offending lengths are e.g. 128-255, 384-511, and 640-767, where ((length & 0x80) == 0x80). String arguments with other lengths are output without Exceptions (as are as long as they are not affected by JDK-8354910).

      The culprit is thought to be the same as that of JDK-8354910; https://github.com/openjdk/jdk/blob/a2dc9c71e47a1cdf70ab351c557a5f1835eb5f4a/src/jdk.jshell/share/classes/jdk/jshell/execution/impl/ConsoleImpl.java#L398 doesn't handle negative argument values derived from a (negative) byte-type value even though OutputStream.write(int) stipulates that "The byte to be written is the eight low-order bits of the argument b. The 24 high-order bits of b are ignored." in https://download.java.net/java/early_access/loom/docs/api/java.base/java/io/OutputStream.html#write(int).

      The `buffer` array doesn't assume that it stores negative values according to https://github.com/openjdk/jdk/blob/a2dc9c71e47a1cdf70ab351c557a5f1835eb5f4a/src/jdk.jshell/share/classes/jdk/jshell/execution/impl/ConsoleImpl.java#L470-L480, but actually it does due to https://github.com/openjdk/jdk/blob/a2dc9c71e47a1cdf70ab351c557a5f1835eb5f4a/src/jdk.jshell/share/classes/jdk/jshell/execution/impl/ConsoleImpl.java#L398.

      `& 0x80` must have been added at https://github.com/openjdk/jdk/blob/a2dc9c71e47a1cdf70ab351c557a5f1835eb5f4a/src/jdk.jshell/share/classes/jdk/jshell/execution/impl/ConsoleImpl.java#L398.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Run jshell --enable-preview (--enable-preview is unnecessary when you test only System.console().printf or methods of System.console().writer())
      2. Execute either of the following methods with an argument as a string with a length of e.g. 128-255, 384-511, or 640-767 there. You can utilize String.repeat to generate one easily, e.g. "a".repeat(128).

      Offending methods (the trailing * means that it requires --enable-preview):

      - IO.print *
      - IO.println *
      - System.console().print *
      - System.console().println *
      - System.console().printf
      - System.console().writer().write
      - System.console().writer().print
      - System.console().writer().println
      - System.console().writer().printf

      Note: works properly outside of JShell (e.g. java command with a .java source code) like JDK-8354910

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      jshell> IO.println("a".repeat(128))
      aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

      jshell> IO.print("a".repeat(128))
      aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
      jshell> System.console().print("a".repeat(128))
      aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$1 ==> java.io.ProxyingConsole@4459eb14

      jshell> System.console().println("a".repeat(128))
      aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
      $2 ==> java.io.ProxyingConsole@4459eb14

      jshell> System.console().printf("a".repeat(128))
      aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$3 ==> java.io.ProxyingConsole@4459eb14

      jshell> System.console().writer().print("a".repeat(128))
      aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
      jshell> System.console().writer().println("a".repeat(128))
      aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

      jshell> System.console().writer().printf("a".repeat(128))
      aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
      jshell> System.console().writer().write("a".repeat(128))
      aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
      jshell> IO.println("a".repeat(255))
      aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

      jshell> IO.println("a".repeat(384))
      aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

      jshell> IO.println("a".repeat(511))
      aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa


      ACTUAL -
      jshell> IO.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)
              at jdk.jshell/jdk.jshell.execution.impl.ConsoleImpl$ConsoleOutputStream.write(ConsoleImpl.java:402)
              at java.base/java.io.OutputStream.write(OutputStream.java:167)
              at java.base/java.io.OutputStream.write(OutputStream.java:124)
              at jdk.jshell/jdk.jshell.execution.DemultiplexInput.run(DemultiplexInput.java:74)
      | State engine terminated.
      | Restore definitions with: /reload -restore

      jshell> IO.print("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)
              at jdk.jshell/jdk.jshell.execution.impl.ConsoleImpl$ConsoleOutputStream.write(ConsoleImpl.java:402)
              at java.base/java.io.OutputStream.write(OutputStream.java:167)
              at java.base/java.io.OutputStream.write(OutputStream.java:124)
              at jdk.jshell/jdk.jshell.execution.DemultiplexInput.run(DemultiplexInput.java:74)
      | State engine terminated.
      | Restore definitions with: /reload -restore

      jshell> System.console().print("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)
              at jdk.jshell/jdk.jshell.execution.impl.ConsoleImpl$ConsoleOutputStream.write(ConsoleImpl.java:402)
              at java.base/java.io.OutputStream.write(OutputStream.java:167)
              at java.base/java.io.OutputStream.write(OutputStream.java:124)
              at jdk.jshell/jdk.jshell.execution.DemultiplexInput.run(DemultiplexInput.java:74)
      | State engine terminated.
      | Restore definitions with: /reload -restore
      $1 ==>

      jshell> System.console().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)
              at java.base/java.io.OutputStream.write(OutputStream.java:124)
      | Restore definitions with: /reload -restore
              at jdk.jshell/jdk.jshell.execution.DemultiplexInput.run(DemultiplexInput.java:74)
      $1 ==>

      jshell> System.console().printf("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)
              at jdk.jshell/jdk.jshell.execution.impl.ConsoleImpl$ConsoleOutputStream.write(ConsoleImpl.java:402)
              at java.base/java.io.OutputStream.write(OutputStream.java:167)
              at java.base/java.io.OutputStream.write(OutputStream.java:124)
      | State engine terminated. at jdk.jshell/jdk.jshell.execution.DemultiplexInput.run(DemultiplexInput.java:74)

      | Restore definitions with: /reload -restore
      $1 ==>

      jshell> System.console().writer().print("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)
      | Restore definitions with: /reload -restore
              at jdk.jshell/jdk.jshell.execution.impl.ConsoleImpl$ConsoleOutputStream.write(ConsoleImpl.java:402)
              at java.base/java.io.OutputStream.write(OutputStream.java:167)
              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("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)
              at jdk.jshell/jdk.jshell.execution.impl.ConsoleImpl$ConsoleOutputStream.write(ConsoleImpl.java:402)
      | State engine terminated. at java.base/java.io.OutputStream.write(OutputStream.java:167)

              at java.base/java.io.OutputStream.write(OutputStream.java:124)
      | Restore definitions with: /reload -restore at jdk.jshell/jdk.jshell.execution.DemultiplexInput.run(DemultiplexInput.java:74)


      jshell> System.console().writer().printf("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)

              at java.base/java.io.OutputStream.write(OutputStream.java:124)
      | Restore definitions with: /reload -restore at jdk.jshell/jdk.jshell.execution.DemultiplexInput.run(DemultiplexInput.java:74)

      $1 ==>

      jshell> System.console().writer().write("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)
              at java.base/java.io.OutputStream.write(OutputStream.java:124)
              at jdk.jshell/jdk.jshell.execution.DemultiplexInput.run(DemultiplexInput.java:74)
      | Restore definitions with: /reload -restore

      jshell> IO.println("a".repeat(255))
      Exception in thread "output reader" java.lang.NegativeArraySizeException: -1
              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)
              at java.base/java.io.OutputStream.write(OutputStream.java:124)
              at jdk.jshell/jdk.jshell.execution.DemultiplexInput.run(DemultiplexInput.java:74)
      | State engine terminated.
      | Restore definitions with: /reload -restore

      jshell> IO.println("a".repeat(384))
      Exception in thread "output reader" java.lang.NegativeArraySizeException: -128
              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)
      | State engine terminated. at java.base/java.io.OutputStream.write(OutputStream.java:167)

              at java.base/java.io.OutputStream.write(OutputStream.java:124)
              at jdk.jshell/jdk.jshell.execution.DemultiplexInput.run(DemultiplexInput.java:74)
      | Restore definitions with: /reload -restore

      jshell> IO.println("a".repeat(511))
      Exception in thread "output reader" java.lang.NegativeArraySizeException: -1
              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)
              at java.base/java.io.OutputStream.write(OutputStream.java:124)
              at jdk.jshell/jdk.jshell.execution.DemultiplexInput.run(DemultiplexInput.java:74)
      | State engine terminated.
      | Restore definitions with: /reload -restore

      ---------- BEGIN SOURCE ----------
      // See above
      ---------- END SOURCE ----------

            jlahoda Jan Lahoda
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: