undefect. CWE-407 — 63 sites patched across 27 ecosystems

Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com

Patches, unit tests, benchmarks, whitepaper, and outreach briefs.
Public domain — no copyright claimed. Use freely.
This commit is contained in:
russell@unturf.com 2026-03-26 17:11:57 -04:00
commit 0a580b313d
70422 changed files with 17213626 additions and 0 deletions

View file

@ -0,0 +1,123 @@
/*
* Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 8331681 8351435
* @summary Verify the java.base's console provider handles the prompt correctly.
* @library /test/lib
*/
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
import jtreg.SkippedException;
public class ConsolePromptTest {
private static final List<List<String>> VARIANTS = List.of(
List.of("--limit-modules", "java.base"),
List.of("-Djdk.console=java.base")
);
public static void main(String... args) throws Throwable {
for (Method m : ConsolePromptTest.class.getDeclaredMethods()) {
if (m.getName().startsWith("test")) {
for (List<String> variant : VARIANTS) {
try {
m.invoke(new ConsolePromptTest(variant));
} catch (InvocationTargetException e) {
if (e.getCause() instanceof SkippedException se) {
throw se;
} else {
throw e;
}
}
}
}
}
}
private final List<String> extraParams;
public ConsolePromptTest(List<String> extraParams) {
this.extraParams = extraParams;
}
void testCorrectOutputReadLine() throws Exception {
doRunConsoleTest("testCorrectOutputReadLine");
}
void testCorrectOutputReadPassword() throws Exception {
doRunConsoleTest("testCorrectOutputReadPassword");
}
void doRunConsoleTest(String testName) throws Exception {
// check "expect" command availability
var expect = Paths.get("/usr/bin/expect");
if (!Files.exists(expect) || !Files.isExecutable(expect)) {
throw new SkippedException("'expect' command not found. Test ignored.");
}
// invoking "expect" command
var testSrc = System.getProperty("test.src", ".");
var jdkDir = System.getProperty("test.jdk");
List<String> command = new ArrayList<>();
command.add("expect");
command.add("-n");
command.add(testSrc + "/consolePrompt.exp");
command.add("%s");
command.add(jdkDir + "/bin/java");
command.addAll(extraParams);
command.add("-cp");
command.add(System.getProperty("java.class.path"));
command.add(ConsoleTest.class.getName());
command.add(testName);
OutputAnalyzer output = ProcessTools.executeProcess(command.toArray(String[]::new));
output.reportDiagnosticSummary();
output.shouldHaveExitValue(0);
}
public static class ConsoleTest {
public static void main(String... args) {
switch (args[0]) {
case "testCorrectOutputReadLine" ->
System.console().readLine("%%s");
case "testCorrectOutputReadPassword" ->
System.console().readPassword("%%s");
default -> throw new UnsupportedOperationException(args[0]);
}
System.exit(0);
}
}
}

View file

@ -0,0 +1,86 @@
/*
* Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.nio.file.Files;
import java.nio.file.Paths;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import static jdk.test.lib.Utils.*;
/**
* @test
* @bug 8341975 8351435 8361613
* @summary Tests the default charset. It should honor `stdout.encoding`
* which should be the same as System.out.charset()
* @requires (os.family == "linux") | (os.family == "mac")
* @library /test/lib
* @build jdk.test.lib.Utils
* jdk.test.lib.JDKToolFinder
* jdk.test.lib.process.ProcessTools
* @run junit DefaultCharsetTest
*/
public class DefaultCharsetTest {
@BeforeAll
static void checkExpectAvailability() {
// check "expect" command availability
var expect = Paths.get("/usr/bin/expect");
Assumptions.assumeTrue(Files.exists(expect) && Files.isExecutable(expect),
"'" + expect + "' not found. Test ignored.");
}
@ParameterizedTest
@ValueSource(strings = {"UTF-8", "ISO-8859-1", "US-ASCII", "foo", ""})
void testDefaultCharset(String stdoutEncoding) throws Exception {
// invoking "expect" command
OutputAnalyzer oa = ProcessTools.executeProcess(
"expect",
"-n",
TEST_SRC + "/defaultCharset.exp",
TEST_CLASSES,
TEST_JDK + "/bin/java",
"-Dstdout.encoding=" + stdoutEncoding,
getClass().getName());
oa.reportDiagnosticSummary();
oa.shouldHaveExitValue(0);
}
public static void main(String... args) {
var stdoutEncoding = System.getProperty("stdout.encoding");
var sysoutCharset = System.out.charset();
var consoleCharset = System.console().charset();
System.out.printf("""
stdout.encoding = %s
System.out.charset() = %s
System.console().charset() = %s
""", stdoutEncoding, sysoutCharset.name(), consoleCharset.name());
if (!consoleCharset.equals(sysoutCharset)) {
System.err.printf("Charsets for System.out and Console differ for stdout.encoding: %s%n", stdoutEncoding);
System.exit(-1);
}
}
}

View file

@ -0,0 +1,125 @@
/*
* Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.function.Predicate;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.Test;
import static jdk.test.lib.Utils.*;
/**
* @test
* @bug 8330276 8351435 8361613
* @summary Tests Console methods that have Locale as an argument
* @requires (os.family == "linux") | (os.family == "mac")
* @library /test/lib
* @build jdk.test.lib.Utils
* jdk.test.lib.JDKToolFinder
* jdk.test.lib.process.ProcessTools
* @modules jdk.localedata
* @run junit LocaleTest
*/
public class LocaleTest {
private static final Calendar TODAY = new GregorianCalendar(2024, Calendar.APRIL, 22);
private static final String FORMAT = "%1$tY-%1$tB-%1$te %1$tA";
// We want to limit the expected strings within US-ASCII charset, as
// the native encoding is determined as such, which is used by
// the `Process` class under jtreg environment.
private static final List<String> EXPECTED = List.of(
String.format(Locale.UK, FORMAT, TODAY),
String.format(Locale.FRANCE, FORMAT, TODAY),
String.format(Locale.GERMANY, FORMAT, TODAY),
String.format(Locale.of("es"), FORMAT, TODAY),
String.format((Locale)null, FORMAT, TODAY),
String.format((Locale)null, FORMAT, TODAY),
String.format((Locale)null, FORMAT, TODAY),
String.format((Locale)null, FORMAT, TODAY)
);
@Test
void testLocale() throws Exception {
// check "expect" command availability
var expect = Paths.get("/usr/bin/expect");
Assumptions.assumeTrue(Files.exists(expect) && Files.isExecutable(expect),
"'" + expect + "' not found. Test ignored.");
// invoking "expect" command
OutputAnalyzer oa = ProcessTools.executeProcess(
"expect",
"-n",
TEST_SRC + "/locale.exp",
TEST_CLASSES,
TEST_JDK + "/bin/java",
getClass().getName());
var stdout =
oa.stdoutAsLines().stream().filter(Predicate.not(String::isEmpty)).toList();
var resultText =
"""
Actual output: %s
Expected output: %s
""".formatted(stdout, EXPECTED);
if (!stdout.equals(EXPECTED)) {
throw new RuntimeException("Standard out had unexpected strings:\n" + resultText);
} else {
oa.shouldHaveExitValue(0);
System.out.println("Formatting with explicit Locale succeeded.\n" + resultText);
}
}
public static void main(String... args) throws Throwable {
var con = System.console();
if (con != null) {
// tests these additional methods that take a Locale
con.format(Locale.UK, FORMAT, TODAY);
con.printf("\n");
con.printf(Locale.FRANCE, FORMAT, TODAY);
con.printf("\n");
con.readLine(Locale.GERMANY, FORMAT, TODAY);
con.printf("\n");
con.readPassword(Locale.of("es"), FORMAT, TODAY);
con.printf("\n");
// tests null locale
con.format((Locale)null, FORMAT, TODAY);
con.printf("\n");
con.printf((Locale)null, FORMAT, TODAY);
con.printf("\n");
con.readLine((Locale)null, FORMAT, TODAY);
con.printf("\n");
con.readPassword((Locale)null, FORMAT, TODAY);
} else {
// Exit with -1
System.exit(-1);
}
}
}

View file

@ -0,0 +1,118 @@
/*
* Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8295803 8299689 8351435 8361613 8366261
* @summary Tests System.console() returns correct Console (or null) from the expected
* module.
* @library /test/lib
* @build jdk.test.lib.Utils
* jdk.test.lib.process.ProcessTools
* @run junit ModuleSelectionTest
*/
import java.io.Console;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import static jdk.test.lib.Utils.*;
public class ModuleSelectionTest {
private static Stream<Arguments> options() {
return Stream.of(
Arguments.of("-Djdk.console=foo", "java.base"),
Arguments.of("-Djdk.console=java.base", "java.base"),
Arguments.of("-Djdk.console=jdk.internal.le", "jdk.internal.le"),
Arguments.of("--limit-modules java.base", "java.base")
);
}
@ParameterizedTest
@MethodSource("options")
void testNonTTY(String opts) throws Exception {
opts = opts +
" --add-opens java.base/java.io=ALL-UNNAMED ModuleSelectionTest null";
OutputAnalyzer output = ProcessTools.executeTestJava(opts.split(" "));
output.reportDiagnosticSummary();
output.shouldHaveExitValue(0);
}
@ParameterizedTest
@MethodSource("options")
void testTTY(String opts, String expected) throws Exception {
// check "expect" command availability
var expect = Paths.get("/usr/bin/expect");
Assumptions.assumeTrue(Files.exists(expect) && Files.isExecutable(expect),
"'" + expect + "' not found. Test ignored.");
opts = "expect -n " + TEST_SRC + "/moduleSelection.exp " +
TEST_CLASSES + " " +
expected + " " +
TEST_JDK + "/bin/java" +
" --add-opens java.base/java.io=ALL-UNNAMED "
+ opts;
// invoking "expect" command
OutputAnalyzer output = ProcessTools.executeProcess(opts.split(" "));
output.reportDiagnosticSummary();
output.shouldHaveExitValue(0);
}
public static void main(String... args) throws Throwable {
var con = System.console();
var pc = Class.forName("java.io.ProxyingConsole");
var jdkc = Class.forName("jdk.internal.io.JdkConsole");
var lookup = MethodHandles.privateLookupIn(Console.class, MethodHandles.lookup());
var istty = (boolean)lookup.findStatic(Console.class, "isStdinTty", MethodType.methodType(boolean.class))
.invoke() &&
(boolean)lookup.findStatic(Console.class, "isStdoutTty", MethodType.methodType(boolean.class))
.invoke();
var impl = con != null ? MethodHandles.privateLookupIn(pc, MethodHandles.lookup())
.findGetter(pc, "delegate", jdkc)
.invoke(con) : null;
var expected = args[0];
var actual = con == null ? "null" : impl.getClass().getModule().getName();
if (!actual.equals(expected)) {
throw new RuntimeException("""
Console implementation is not the expected one.
Expected: %s
Actual: %s
""".formatted(expected, actual));
} else {
System.out.printf("%s is the expected implementation. (tty: %s)\n", actual, istty);
}
}
}

View file

@ -0,0 +1,86 @@
/*
* Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 8340830
* @summary Check if writing to Console is not blocked by other thread's read.
* This test relies on sleep(1000) to ensure that readLine() is
* invoked before printf(), which may not always occur.
* @library /test/lib
* @requires (os.family == "linux" | os.family == "mac")
* @run junit ReadWriteBlockingTest
*/
import java.nio.file.Files;
import java.nio.file.Path;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
public class ReadWriteBlockingTest {
@ParameterizedTest
@ValueSource(strings = {"java.base", "jdk.internal.le"})
@EnabledOnOs({OS.LINUX, OS.MAC})
public void testReadWriteBlocking(String consoleModule) throws Exception {
// check "expect" command availability
var expect = Path.of("/usr/bin/expect");
if (!Files.exists(expect) || !Files.isExecutable(expect)) {
Assumptions.abort("'" + expect + "' not found");
}
// invoking "expect" command
var testSrc = System.getProperty("test.src", ".");
var testClasses = System.getProperty("test.classes", ".");
var jdkDir = System.getProperty("test.jdk");
OutputAnalyzer output = ProcessTools.executeProcess(
"/usr/bin/expect",
"-n",
testSrc + "/readWriteBlocking.exp",
jdkDir + "/bin/java",
"-classpath", testClasses,
"-Djdk.console=" + consoleModule,
"ReadWriteBlockingTest");
output.reportDiagnosticSummary();
output.shouldHaveExitValue(0);
}
public static void main(String... args) {
var con = System.console();
Thread.ofVirtual().start(() -> {
try {
// give some time for main thread to invoke readLine()
Thread.sleep(1000);
} catch (InterruptedException _) {}
con.printf("printf() invoked");
});
con.readLine("");
}
}

View file

@ -0,0 +1,78 @@
/*
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.File;
import java.nio.file.Files;
import jdk.test.lib.process.ProcessTools;
/**
* @test
* @bug 8295803 8299689
* @summary Tests System.console() works with standard input redirection.
* @library /test/lib
* @run main RedirectTest
* @run main/othervm -Djdk.console=jdk.internal.le RedirectTest
*/
public class RedirectTest {
private static final String SYSPROP = "jdk.console";
public static void main(String... args) throws Throwable {
if (args.length == 0) {
// no arg will launch the child process that actually perform tests
var pb = ProcessTools.createTestJavaProcessBuilder(
"-D" + SYSPROP + "=" + System.getProperty(SYSPROP, ""),
"RedirectTest", "dummy");
var input = new File(System.getProperty("test.src", "."), "input.txt");
pb.redirectInput(input);
var oa = ProcessTools.executeProcess(pb);
if (oa.getExitValue() == 1) {
System.out.println("System.console() returns null. Ignoring the test.");
} else {
var output = oa.asLines();
var expected = Files.readAllLines(input.toPath());
if (!output.equals(expected)) {
throw new RuntimeException("""
Standard out had unexpected strings:
Actual output: %s
Expected output: %s
""".formatted(output, expected));
} else {
oa.shouldHaveExitValue(0);
System.out.println("Redirect succeeded.");
}
}
} else {
var con = System.console();
if (con != null) {
String line;
while ((line = con.readLine()) != null) {
System.out.println(line);
}
} else {
// Exit with 1
System.exit(1);
}
}
}
}

View file

@ -0,0 +1,95 @@
/*
* Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.Console;
import java.nio.file.Files;
import java.nio.file.Paths;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
/**
* @test
* @bug 8332161
* @summary Tests JdkConsoleImpl restores the echo state after readPassword() call
* @library /test/lib
* @run junit RestoreEchoTest
*/
public class RestoreEchoTest {
@Test
@EnabledOnOs({OS.LINUX, OS.MAC})
public void testRestoreEcho() throws Throwable {
// check "expect" command availability
var expect = Paths.get("/usr/bin/expect");
if (!Files.exists(expect) || !Files.isExecutable(expect)) {
Assumptions.abort("'" + expect + "' not found");
}
expectRunner("-echo");
expectRunner("echo");
}
private static void expectRunner(String initialEcho) throws Throwable {
// invoking "expect" command
var testSrc = System.getProperty("test.src", ".");
var testClasses = System.getProperty("test.classes", ".");
var jdkDir = System.getProperty("test.jdk");
OutputAnalyzer output = ProcessTools.executeProcess(
"expect",
"-n",
testSrc + "/restoreEcho.exp",
initialEcho,
jdkDir + "/bin/java",
"-Djdk.console=java.base",
"-classpath", testClasses,
"RestoreEchoTest");
output.reportDiagnosticSummary();
output.shouldHaveExitValue(0);
}
public static void main(String... args) throws Throwable {
if (!"java.base".equals(System.getProperty("jdk.console"))) {
throw new RuntimeException("Test failed. jdk.console is not java.base");
}
Console con = System.console();
if (con == null) {
throw new RuntimeException("Test failed. System.console() returned null");
}
// testing readLine()
String input = con.readLine("prompt: ");
con.printf("input is %s%n", input);
// testing readPassword()
input = String.valueOf(con.readPassword("password prompt: "));
con.printf("password is %s%n", input);
}
}

View file

@ -0,0 +1,90 @@
/*
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.BufferedReader;
import java.nio.file.Files;
import java.nio.file.Paths;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
import static jdk.test.lib.Utils.*;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.Test;
/**
* @test
* @bug 8356985
* @summary Tests if "stdin.encoding" is reflected for reading
* the console. "expect" command in Windows/Cygwin does
* not work as expected. Ignoring tests on Windows.
* @requires (os.family == "linux" | os.family == "mac")
* @library /test/lib
* @build csp/*
* @run junit StdinEncodingTest
*/
public class StdinEncodingTest {
@Test
public void testStdinEncoding() throws Throwable {
// check "expect" command availability
var expect = Paths.get("/usr/bin/expect");
Assumptions.assumeTrue(Files.exists(expect) && Files.isExecutable(expect),
"'" + expect + "' not found");
// invoking "expect" command
OutputAnalyzer output = ProcessTools.executeProcess(
"expect",
"-n",
TEST_SRC + "/stdinEncoding.exp",
TEST_JDK + "/bin/java",
"--module-path",
TEST_CLASSES + "/modules",
"-Dstdin.encoding=Uppercasing", // <- gist of this test
"StdinEncodingTest");
output.reportDiagnosticSummary();
output.shouldHaveExitValue(0);
}
public static void main(String... args) throws Throwable {
// check stdin.encoding
if (!"Uppercasing".equals(System.getProperty("stdin.encoding"))) {
throw new RuntimeException("Uppercasing charset was not set in stdin.encoding");
}
var con = System.console();
// Console.readLine()
System.out.print(con.readLine());
// Console.readPassword()
System.out.print(String.valueOf(con.readPassword()));
// Console.reader()
try (var br = new BufferedReader(con.reader())) {
System.out.print(br.readLine());
}
// Wait till the test receives the result
con.readLine();
}
}

View file

@ -0,0 +1,75 @@
/*
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.nio.file.Files;
import java.nio.file.Paths;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
import static jdk.test.lib.Utils.*;
import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
/**
* @test
* @bug 8264208 8265918 8356985 8358158
* @summary Tests if "stdout.encoding" property is reflected in
* Console.charset() method. "expect" command in Windows/Cygwin
* does not work as expected. Ignoring tests on Windows.
* @requires (os.family == "linux") | (os.family == "mac")
* @library /test/lib
* @run junit StdoutEncodingTest
*/
public class StdoutEncodingTest {
@ParameterizedTest
@CsvSource({
"en_US.ISO8859-1, ISO-8859-1",
"en_US.US-ASCII, US-ASCII",
"en_US.UTF-8, UTF-8"
})
void testCharset(String locale, String expectedCharset) throws Exception {
// check "expect" command availability
var expect = Paths.get("/usr/bin/expect");
Assumptions.assumeTrue(Files.exists(expect) && Files.isExecutable(expect),
"'" + expect + "' not found. Test ignored.");
// invoking "expect" command
OutputAnalyzer output = ProcessTools.executeProcess(
"expect",
"-n",
TEST_SRC + "/stdoutEncoding.exp",
TEST_JDK + "/bin/java",
locale,
expectedCharset,
TEST_CLASSES);
output.reportDiagnosticSummary();
output.shouldHaveExitValue(0);
}
public static void main(String... args) {
System.out.println(System.console().charset());
}
}

View file

@ -0,0 +1,30 @@
#
# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
set java [lrange $argv 1 end]
set expected [lindex $argv 0]
eval spawn $java
expect -- "$expected"
send -- "\n"
expect eof

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
module csp {
provides java.nio.charset.spi.CharsetProvider with provider.UppercasingCharsetProvider;
}

View file

@ -0,0 +1,87 @@
/*
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package provider;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;
import java.nio.charset.spi.CharsetProvider;
import java.util.Collections;
import java.util.Iterator;
// A test charset provider that decodes every input byte into its uppercase
public class UppercasingCharsetProvider extends CharsetProvider {
@Override
public Iterator charsets() {
return Collections.singleton(new UppercasingCharsetProvider.UppercasingCharset()).iterator();
}
@Override
public Charset charsetForName(String charsetName) {
if (charsetName.equals("Uppercasing")) {
return new UppercasingCharsetProvider.UppercasingCharset();
} else {
return null;
}
}
public static class UppercasingCharset extends Charset {
public UppercasingCharset() {
super("Uppercasing", null);
}
@Override
public boolean contains(Charset cs) {
return false;
}
@Override
public CharsetDecoder newDecoder() {
return new UppercasingCharsetDecoder(this, 1, 1);
}
@Override
public CharsetEncoder newEncoder() {
return null;
}
}
private static class UppercasingCharsetDecoder extends CharsetDecoder {
public UppercasingCharsetDecoder(Charset cs, float averageCharsPerByte, float maxCharsPerByte) {
super(cs, averageCharsPerByte, maxCharsPerByte);
}
@Override
protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
while (in.remaining() > 0) {
out.put(Character.toUpperCase((char)in.get()));
}
return CoderResult.UNDERFLOW;
}
}
}

View file

@ -0,0 +1,32 @@
#
# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
# simply invoking java under expect command
set classpath [lrange $argv 0 0]
set java [lrange $argv 1 1]
set stdoutProp [lrange $argv 2 2]
set clsname [lrange $argv 3 3]
eval spawn $java -classpath $classpath $stdoutProp $clsname
expect eof
set result [wait]
exit [lindex $result 3]

View file

@ -0,0 +1,3 @@
This is line 1
This is line 2
This is the last line

View file

@ -0,0 +1,37 @@
#
# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
# simply invoking java under expect command
set classpath [lrange $argv 0 0]
set java [lrange $argv 1 1]
set clsname [lrange $argv 2 2]
eval spawn -noecho $java -classpath $classpath $clsname
# sends CR 4 times (readLine x 2, readPassword x 2)
send "\r"
send "\r"
send "\r"
send "\r"
expect eof
set result [wait]
exit [lindex $result 3]

View file

@ -0,0 +1,30 @@
#
# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
# simply invoking java under expect command
set classpath [lrange $argv 0 0]
set expected [lrange $argv 1 1]
set java [lrange $argv 2 2]
set opts [lrange $argv 3 end]
eval spawn $java $opts -classpath $classpath ModuleSelectionTest $expected
expect eof

View file

@ -0,0 +1,41 @@
#
# Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
set timeout 10
eval spawn $argv
expect {
"printf() invoked" {
send -- "\n"
}
timeout {
puts stderr "ERROR: Timed out waiting for the expected text"
exit 1
}
eof {
puts stderr "ERROR: Process exited before printing the expected text"
exit 1
}
}
expect eof

View file

@ -0,0 +1,58 @@
#
# Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
set initialEcho [lindex $argv 0]
set java [lrange $argv 1 end]
set rlprompt "prompt: "
set rpprompt "password prompt: "
set rlinput "InPuT"
set rpinput "PaSsWoRd"
set rlexpected "input is $rlinput"
set rpexpected "password is $rpinput"
set stty_init $initialEcho
set timeout 10
proc test {prompt input echoStat expected} {
expect "$prompt"
send -- "$input\n"
if {$echoStat == "echo"} {
expect "$input"
}
expect "$expected"
if {$expect_out(0,string) != $expected} {
send_error "Expected: $expected\n"
send_error "Received: $expect_out(0,string)"
exit 1
}
}
spawn sh -c "[list {*}$java] && stty -a"
# readLine() - input is displayed depending on initialEcho value
test "$rlprompt" "$rlinput" "$initialEcho" "$rlexpected"
# readPassword() - input is not displayed
test "$rpprompt" "$rpinput" "-echo" "$rpexpected"
# See if the initialEcho is restored with `stty -a`
expect -- " $initialEcho "
expect eof

View file

@ -0,0 +1,63 @@
#
# Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
set java [lrange $argv 0 end]
eval spawn $java
# Console::readLine()
send "abc\r"
expect {
"ABC" { send_error "Console::readLine() received\n" }
timeout {
send_error "Error: Console::readLine() not received\n"
exit 1
}
}
# Console::readPassword()
send "def\r"
expect {
"DEF" { send_error "Console::readPassword() received\n" }
timeout {
send_error "Error: Console::readPassword() not received\n"
exit 1
}
}
# Console::reader()
send "ghi\r"
expect {
"GHI" { send_error "Console::reader() received\n" }
timeout {
send_error "Error: Console::reader() not received\n"
exit 1
}
}
# should receive eof
send "\r"
expect eof
# success
exit 0

View file

@ -0,0 +1,34 @@
#
# Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
# `expect` script for StdoutEncodingTest
set java [lrange $argv 0 0]
set locale [lrange $argv 1 1]
set expected [lrange $argv 2 2]
set classpath [lrange $argv 3 end]
regexp {([a-zA-Z_]*).([a-zA-Z0-9\-]*)} $locale dummy lang_region encoding
eval spawn $java -Dstdout.encoding=$encoding -classpath $classpath StdoutEncodingTest
expect $expected
expect eof