8174797: jshell tool: invalid module path crashes tool
8174796: jshell tool: regression: user home (tilde) not translated
Reviewed-by: jlahoda
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Mon Feb 13 11:57:56 2017 +0100
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Mon Feb 13 08:50:26 2017 -0800
@@ -349,9 +349,56 @@
}
}
+ // check that the supplied string represent valid class/module paths
+ // converting any ~/ to user home
+ private Collection<String> validPaths(Collection<String> vals, String context, boolean isModulePath) {
+ Stream<String> result = vals.stream()
+ .map(s -> Arrays.stream(s.split(File.pathSeparator))
+ .map(sp -> toPathResolvingUserHome(sp))
+ .filter(p -> checkValidPathEntry(p, context, isModulePath))
+ .map(p -> p.toString())
+ .collect(Collectors.joining(File.pathSeparator)));
+ if (failed) {
+ return Collections.emptyList();
+ } else {
+ return result.collect(toList());
+ }
+ }
+
+ // Adapted from compiler method Locations.checkValidModulePathEntry
+ private boolean checkValidPathEntry(Path p, String context, boolean isModulePath) {
+ if (!Files.exists(p)) {
+ msg("jshell.err.file.not.found", context, p);
+ failed = true;
+ return false;
+ }
+ if (Files.isDirectory(p)) {
+ // if module-path, either an exploded module or a directory of modules
+ return true;
+ }
+
+ String name = p.getFileName().toString();
+ int lastDot = name.lastIndexOf(".");
+ if (lastDot > 0) {
+ switch (name.substring(lastDot)) {
+ case ".jar":
+ return true;
+ case ".jmod":
+ if (isModulePath) {
+ return true;
+ }
+ }
+ }
+ msg("jshell.err.arg", context, p);
+ failed = true;
+ return false;
+ }
+
Options parse(OptionSet options) {
- addOptions(OptionKind.CLASS_PATH, options.valuesOf(argClassPath));
- addOptions(OptionKind.MODULE_PATH, options.valuesOf(argModulePath));
+ addOptions(OptionKind.CLASS_PATH,
+ validPaths(options.valuesOf(argClassPath), "--class-path", false));
+ addOptions(OptionKind.MODULE_PATH,
+ validPaths(options.valuesOf(argModulePath), "--module-path", true));
addOptions(OptionKind.ADD_MODULES, options.valuesOf(argAddModules));
addOptions(OptionKind.ADD_EXPORTS, options.valuesOf(argAddExports).stream()
.map(mp -> mp.contains("=") ? mp : mp + "=ALL-UNNAMED")
--- a/langtools/test/jdk/jshell/ToolBasicTest.java Mon Feb 13 11:57:56 2017 +0100
+++ b/langtools/test/jdk/jshell/ToolBasicTest.java Mon Feb 13 08:50:26 2017 -0800
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8143037 8142447 8144095 8140265 8144906 8146138 8147887 8147886 8148316 8148317 8143955 8157953 8080347 8154714 8166649 8167643 8170162 8172102 8165405
+ * @bug 8143037 8142447 8144095 8140265 8144906 8146138 8147887 8147886 8148316 8148317 8143955 8157953 8080347 8154714 8166649 8167643 8170162 8172102 8165405 8174796 8174797
* @summary Tests for Basic tests for REPL tool
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
@@ -35,6 +35,7 @@
* @run testng/timeout=600 ToolBasicTest
*/
+import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -272,23 +273,58 @@
);
}
- public void testClasspathJar() {
+ private String makeSimpleJar() {
Compiler compiler = new Compiler();
Path outDir = Paths.get("testClasspathJar");
compiler.compile(outDir, "package pkg; public class A { public String toString() { return \"A\"; } }");
String jarName = "test.jar";
compiler.jar(outDir, jarName, "pkg/A.class");
- Path jarPath = compiler.getPath(outDir).resolve(jarName);
+ return compiler.getPath(outDir).resolve(jarName).toString();
+ }
+
+ public void testClasspathJar() {
+ String jarPath = makeSimpleJar();
test(
(a) -> assertCommand(a, "/env --class-path " + jarPath,
"| Setting new options and restoring state."),
(a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "A")
);
- test(new String[] { "--class-path", jarPath.toString() },
+ test(new String[] { "--class-path", jarPath },
(a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "A")
);
}
+ public void testClasspathUserHomeExpansion() {
+ String jarPath = makeSimpleJar();
+ String tilde = "~" + File.separator;
+ test(
+ (a) -> assertCommand(a, "/env --class-path " + tilde + "forblato",
+ "| File '" + System.getProperty("user.home") + File.separator
+ + "forblato' for '--class-path' is not found."),
+ (a) -> assertCommand(a, "/env --class-path " + jarPath + File.pathSeparator
+ + tilde + "forblato",
+ "| File '" + System.getProperty("user.home") + File.separator
+ + "forblato' for '--class-path' is not found.")
+ );
+ }
+
+ public void testBadClasspath() {
+ String jarPath = makeSimpleJar();
+ Compiler compiler = new Compiler();
+ Path t1 = compiler.getPath("whatever/thing.zip");
+ compiler.writeToFile(t1, "");
+ Path t2 = compiler.getPath("whatever/thing.jmod");
+ compiler.writeToFile(t2, "");
+ test(
+ (a) -> assertCommand(a, "/env --class-path " + t1.toString(),
+ "| Invalid '--class-path' argument: " + t1.toString()),
+ (a) -> assertCommand(a, "/env --class-path " + jarPath + File.pathSeparator + t1.toString(),
+ "| Invalid '--class-path' argument: " + t1.toString()),
+ (a) -> assertCommand(a, "/env --class-path " + t2.toString(),
+ "| Invalid '--class-path' argument: " + t2.toString())
+ );
+ }
+
public void testModulePath() {
Compiler compiler = new Compiler();
Path modsDir = Paths.get("mods");
@@ -304,6 +340,25 @@
);
}
+ public void testModulePathUserHomeExpansion() {
+ String tilde = "~" + File.separatorChar;
+ test(
+ (a) -> assertCommand(a, "/env --module-path " + tilde + "snardugol",
+ "| File '" + System.getProperty("user.home")
+ + File.separatorChar + "snardugol' for '--module-path' is not found.")
+ );
+ }
+
+ public void testBadModulePath() {
+ Compiler compiler = new Compiler();
+ Path t1 = compiler.getPath("whatever/thing.zip");
+ compiler.writeToFile(t1, "");
+ test(
+ (a) -> assertCommand(a, "/env --module-path " + t1.toString(),
+ "| Invalid '--module-path' argument: " + t1.toString())
+ );
+ }
+
public void testStartupFileOption() {
Compiler compiler = new Compiler();
Path startup = compiler.getPath("StartupFileOption/startup.txt");
--- a/langtools/test/jdk/jshell/ToolSimpleTest.java Mon Feb 13 11:57:56 2017 +0100
+++ b/langtools/test/jdk/jshell/ToolSimpleTest.java Mon Feb 13 08:50:26 2017 -0800
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8153716 8143955 8151754 8150382 8153920 8156910 8131024 8160089 8153897 8167128 8154513 8170015 8170368 8172102 8172103 8165405 8173073 8173848 8174041 8173916 8174028 8174262
+ * @bug 8153716 8143955 8151754 8150382 8153920 8156910 8131024 8160089 8153897 8167128 8154513 8170015 8170368 8172102 8172103 8165405 8173073 8173848 8174041 8173916 8174028 8174262 8174797
* @summary Simple jshell tool tests
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
@@ -212,6 +212,14 @@
}
@Test
+ public void testInvalidClassPath() {
+ test(
+ a -> assertCommand(a, "/env --class-path snurge/fusal",
+ "| File 'snurge/fusal' for '--class-path' is not found.")
+ );
+ }
+
+ @Test
public void testNoArgument() {
test(
(a) -> assertCommand(a, "/save",