Skip to content

Commit c8ce61c

Browse files
tats-ulahodaj
authored andcommitted
8355371: NegativeArraySizeException in print methods in IO or System.console() in JShell
8354910: Output by java.io.IO or System.console() corrupted for some non-ASCII characters Reviewed-by: liach, jlahoda
1 parent 5b3ae92 commit c8ce61c

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

src/jdk.jshell/share/classes/jdk/jshell/execution/impl/ConsoleImpl.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,9 @@ public synchronized void write(int b) throws IOException {
356356
buffer = Arrays.copyOf(buffer, 2 * buffer.length);
357357
}
358358

359-
buffer[bp++] = b;
359+
// Can be negative because widening from byte in write(byte[], int, int).
360+
// java.io.OutputStream.write(int b) stipulates "The 24 high-order bits of b are ignored."
361+
buffer[bp++] = b & 0xff;
360362

361363
switch (Task.values()[buffer[0]]) {
362364
case WRITE_CHARS -> {
@@ -373,7 +375,7 @@ public synchronized void write(int b) throws IOException {
373375
}
374376
case READ_CHARS -> {
375377
if (bp >= 5) {
376-
int len = readInt(b);
378+
int len = readInt(1);
377379
int c = console.reader().read();
378380
//XXX: EOF handling!
379381
sendChars(sinkOutput, new char[] {(char) c}, 0, 1);

test/langtools/jdk/jshell/ConsoleTest.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,31 @@ public void close() throws IOException {}
149149
assertEquals(sb.toString(), expected);
150150
}
151151

152+
@Test
153+
public void testConsoleUnicodeWritingTest() {
154+
StringBuilder sb = new StringBuilder();
155+
console = new ThrowingJShellConsole() {
156+
@Override
157+
public PrintWriter writer() {
158+
return new PrintWriter(new Writer() {
159+
@Override
160+
public void write(char[] cbuf, int off, int len) throws IOException {
161+
sb.append(cbuf, off, len);
162+
}
163+
@Override
164+
public void flush() throws IOException {}
165+
@Override
166+
public void close() throws IOException {}
167+
});
168+
}
169+
};
170+
int count = 384; // 128-255, 384-511, 640-767, ... (JDK-8355371)
171+
String testStr = "\u30A2"; // Japanese katakana (A2 >= 80) (JDK-8354910)
172+
assertEval("System.console().writer().write(\"" + testStr + "\".repeat(" + count + "))");
173+
String expected = testStr.repeat(count);
174+
assertEquals(sb.toString(), expected);
175+
}
176+
152177
@Test
153178
public void testConsoleMultiThreading() {
154179
StringBuilder sb = new StringBuilder();

0 commit comments

Comments
 (0)