diff options
Diffstat (limited to 'java/openjdk6/files/icedtea/openjdk/8012453-runtime.exec.patch')
-rw-r--r-- | java/openjdk6/files/icedtea/openjdk/8012453-runtime.exec.patch | 383 |
1 files changed, 0 insertions, 383 deletions
diff --git a/java/openjdk6/files/icedtea/openjdk/8012453-runtime.exec.patch b/java/openjdk6/files/icedtea/openjdk/8012453-runtime.exec.patch deleted file mode 100644 index 143a0c1f286d..000000000000 --- a/java/openjdk6/files/icedtea/openjdk/8012453-runtime.exec.patch +++ /dev/null @@ -1,383 +0,0 @@ -# HG changeset patch -# User uta -# Date 1383008821 0 -# Tue Oct 29 01:07:01 2013 +0000 -# Node ID 20c88fd14959c6a4df2e0f36bd759b56efa6f2cb -# Parent 3e758b40337ef9da5ad030d0ac60ab4407357277 -8012453: (process) Runtime.exec(String) fails if command contains spaces [win] -Reviewed-by: alanb - -diff -r 3e758b40337e -r 20c88fd14959 src/share/classes/java/lang/ProcessBuilder.java ---- jdk/src/share/classes/java/lang/ProcessBuilder.java Tue Jul 30 17:20:22 2013 -0400 -+++ jdk/src/share/classes/java/lang/ProcessBuilder.java Tue Oct 29 01:07:01 2013 +0000 -@@ -490,6 +490,15 @@ - + (dir == null ? "" : " (in directory \"" + dir + "\")") - + exceptionInfo, - cause); -+ } catch (IllegalArgumentException e) { -+ String exceptionInfo = ": " + e.getMessage(); -+ // It's much easier for us to create a high-quality error -+ // message than the low-level C code which found the problem. -+ throw new IOException( -+ "Cannot run program \"" + prog + "\"" -+ + (dir == null ? "" : " (in directory \"" + dir + "\")") -+ + exceptionInfo, -+ e); - } - } - } -diff -r 3e758b40337e -r 20c88fd14959 src/windows/classes/java/lang/ProcessImpl.java ---- jdk/src/windows/classes/java/lang/ProcessImpl.java Tue Jul 30 17:20:22 2013 -0400 -+++ jdk/src/windows/classes/java/lang/ProcessImpl.java Tue Oct 29 01:07:01 2013 +0000 -@@ -26,6 +26,9 @@ - package java.lang; - - import java.io.*; -+import java.util.ArrayList; -+import java.util.regex.Matcher; -+import java.util.regex.Pattern; - - /* This class is for the exclusive use of ProcessBuilder.start() to - * create new processes. -@@ -47,6 +50,66 @@ - return new ProcessImpl(cmdarray, envblock, dir, redirectErrorStream); - } - -+ private static class LazyPattern { -+ // Escape-support version: -+ // "(\")((?:\\\\\\1|.)+?)\\1|([^\\s\"]+)"; -+ private static final Pattern PATTERN = -+ Pattern.compile("[^\\s\"]+|\"[^\"]*\""); -+ }; -+ -+ /* Parses the command string parameter into the executable name and -+ * program arguments. -+ * -+ * The command string is broken into tokens. The token separator is a space -+ * or quota character. The space inside quotation is not a token separator. -+ * There are no escape sequences. -+ */ -+ private static String[] getTokensFromCommand(String command) { -+ ArrayList<String> matchList = new ArrayList<String>(8); -+ Matcher regexMatcher = LazyPattern.PATTERN.matcher(command); -+ while (regexMatcher.find()) -+ matchList.add(regexMatcher.group()); -+ return matchList.toArray(new String[matchList.size()]); -+ } -+ -+ private static String createCommandLine(boolean isCmdFile, -+ final String executablePath, -+ final String cmd[]) -+ { -+ StringBuilder cmdbuf = new StringBuilder(80); -+ -+ cmdbuf.append(executablePath); -+ -+ for (int i = 1; i < cmd.length; ++i) { -+ cmdbuf.append(' '); -+ String s = cmd[i]; -+ if (needsEscaping(isCmdFile, s)) { -+ cmdbuf.append('"'); -+ cmdbuf.append(s); -+ -+ // The code protects the [java.exe] and console command line -+ // parser, that interprets the [\"] combination as an escape -+ // sequence for the ["] char. -+ // http://msdn.microsoft.com/en-us/library/17w5ykft.aspx -+ // -+ // If the argument is an FS path, doubling of the tail [\] -+ // char is not a problem for non-console applications. -+ // -+ // The [\"] sequence is not an escape sequence for the [cmd.exe] -+ // command line parser. The case of the [""] tail escape -+ // sequence could not be realized due to the argument validation -+ // procedure. -+ if (!isCmdFile && s.endsWith("\\")) { -+ cmdbuf.append('\\'); -+ } -+ cmdbuf.append('"'); -+ } else { -+ cmdbuf.append(s); -+ } -+ } -+ return cmdbuf.toString(); -+ } -+ - // We guarantee the only command file execution for implicit [cmd.exe] run. - // http://technet.microsoft.com/en-us/library/bb490954.aspx - private static final char CMD_BAT_ESCAPE[] = {' ', '\t', '<', '>', '&', '|', '^'}; -@@ -128,6 +191,16 @@ - return fileToRun.getPath(); - } - -+ private boolean isShellFile(String executablePath) { -+ String upPath = executablePath.toUpperCase(); -+ return (upPath.endsWith(".CMD") || upPath.endsWith(".BAT")); -+ } -+ -+ private String quoteString(String arg) { -+ StringBuilder argbuf = new StringBuilder(arg.length() + 2); -+ return argbuf.append('"').append(arg).append('"').toString(); -+ } -+ - - private long handle = 0; - private FileDescriptor stdin_fd; -@@ -143,36 +216,66 @@ - boolean redirectErrorStream) - throws IOException - { -- // The [executablePath] is not quoted for any case. -- String executablePath = getExecutablePath(cmd[0]); -+ String cmdstr; -+ SecurityManager security = System.getSecurityManager(); -+ boolean allowAmbigousCommands = false; -+ if (security == null) { -+ String value = System.getProperty("jdk.lang.Process.allowAmbigousCommands"); -+ if (value != null) -+ allowAmbigousCommands = !"false".equalsIgnoreCase(value); -+ } -+ if (allowAmbigousCommands) { -+ // Legacy mode. - -- // We need to extend the argument verification procedure -- // to guarantee the only command file execution for implicit [cmd.exe] -- // run. -- String upPath = executablePath.toUpperCase(); -- boolean isCmdFile = (upPath.endsWith(".CMD") || upPath.endsWith(".BAT")); -+ // Normalize path if possible. -+ String executablePath = new File(cmd[0]).getPath(); - -- StringBuilder cmdbuf = new StringBuilder(80); -+ // No worry about internal and unpaired ["] . -+ if (needsEscaping(false, executablePath) ) -+ executablePath = quoteString(executablePath); - -- // Quotation protects from interpretation of the [path] argument as -- // start of longer path with spaces. Quotation has no influence to -- // [.exe] extension heuristic. -- cmdbuf.append('"'); -- cmdbuf.append(executablePath); -- cmdbuf.append('"'); -+ cmdstr = createCommandLine( -+ false, //legacy mode doesn't worry about extended verification -+ executablePath, -+ cmd); -+ } else { -+ String executablePath; -+ try { -+ executablePath = getExecutablePath(cmd[0]); -+ } catch (IllegalArgumentException e) { -+ // Workaround for the calls like -+ // Runtime.getRuntime().exec("\"C:\\Program Files\\foo\" bar") - -- for (int i = 1; i < cmd.length; i++) { -- cmdbuf.append(' '); -- String s = cmd[i]; -- if (needsEscaping(isCmdFile, s)) { -- cmdbuf.append('"'); -- cmdbuf.append(s); -- cmdbuf.append('"'); -- } else { -- cmdbuf.append(s); -+ // No chance to avoid CMD/BAT injection, except to do the work -+ // right from the beginning. Otherwise we have too many corner -+ // cases from -+ // Runtime.getRuntime().exec(String[] cmd [, ...]) -+ // calls with internal ["] and escape sequences. -+ -+ // Restore original command line. -+ StringBuilder join = new StringBuilder(); -+ // terminal space in command line is ok -+ for (String s : cmd) -+ join.append(s).append(' '); -+ -+ // Parse the command line again. -+ cmd = getTokensFromCommand(join.toString()); -+ executablePath = getExecutablePath(cmd[0]); -+ -+ // Check new executable name once more -+ if (security != null) -+ security.checkExec(executablePath); - } -+ -+ // Quotation protects from interpretation of the [path] argument as -+ // start of longer path with spaces. Quotation has no influence to -+ // [.exe] extension heuristic. -+ cmdstr = createCommandLine( -+ // We need the extended verification procedure for CMD files. -+ isShellFile(executablePath), -+ quoteString(executablePath), -+ cmd); - } -- String cmdstr = cmdbuf.toString(); - - stdin_fd = new FileDescriptor(); - stdout_fd = new FileDescriptor(); -diff -r 3e758b40337e -r 20c88fd14959 test/java/lang/Runtime/exec/ExecCommand.java ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ jdk/test/java/lang/Runtime/exec/ExecCommand.java Tue Oct 29 01:07:01 2013 +0000 -@@ -0,0 +1,163 @@ -+/* -+ * Copyright (c) 2013, 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 8012453 -+ * @run main/othervm ExecCommand -+ * @summary workaround for legacy applications with Runtime.getRuntime().exec(String command) -+ */ -+ -+import java.io.BufferedWriter; -+import java.io.File; -+import java.io.FileWriter; -+import java.io.IOException; -+import java.security.AccessControlException; -+ -+public class ExecCommand { -+ static class SecurityMan extends SecurityManager { -+ public static String unquote(String str) -+ { -+ int length = (str == null) -+ ? 0 -+ : str.length(); -+ -+ if (length > 1 -+ && str.charAt(0) == '\"' -+ && str.charAt(length - 1) == '\"') -+ { -+ return str.substring(1, length - 1); -+ } -+ return str; -+ } -+ -+ @Override public void checkExec(String cmd) { -+ String ncmd = (new File(unquote(cmd))).getPath(); -+ if ( ncmd.equals(".\\Program") -+ || ncmd.equals("\".\\Program") -+ || ncmd.equals(".\\Program Files\\do.cmd") -+ || ncmd.equals(".\\Program.cmd")) -+ { -+ return; -+ } -+ super.checkExec(cmd); -+ } -+ } -+ -+ // Parameters for the Runtime.exec calls -+ private static final String TEST_RTE_ARG[] = { -+ ".\\Program Files\\do.cmd", -+ "\".\\Program Files\\doNot.cmd\" arg", -+ "\".\\Program Files\\do.cmd\" arg", -+ // compatibility -+ "\".\\Program.cmd\" arg", -+ ".\\Program.cmd arg", -+ }; -+ -+ private static final String doCmdCopy[] = { -+ ".\\Program.cmd", -+ ".\\Program Files\\doNot.cmd", -+ ".\\Program Files\\do.cmd", -+ }; -+ -+ // Golden image for results -+ private static final String TEST_RTE_GI[][] = { -+ //Pure system | Legacy mode | Legacy mode & SM -+ // [.\Program File\do.cmd] -+ new String[]{"IOException", // [.\Program] not found -+ "Success", -+ "IOException"}, //SM - no legacy mode [.\Program] - OK -+ -+ // [".\Program File\doNot.cmd" arg] -+ new String[]{"Success", -+ "Success", -+ "AccessControlException"}, //SM - [".\Program] - OK, -+ // [.\\Program Files\\doNot.cmd] - Fail -+ -+ // [".\Program File\do.cmd" arg] -+ // AccessControlException -+ new String[]{"Success", -+ "Success", -+ "Success"}, //SM - [".\Program] - OK, -+ // [.\\Program Files\\do.cmd] - OK -+ -+ // compatibility -+ new String[]{"Success", "Success", "Success"}, //[".\Program.cmd"] -+ new String[]{"Success", "Success", "Success"} //[.\Program.cmd] -+ }; -+ -+ public static void main(String[] _args) throws Exception { -+ if (!System.getProperty("os.name").startsWith("Windows")) { -+ return; -+ } -+ -+ // tear up -+ try { -+ new File(".\\Program Files").mkdirs(); -+ for (int i = 0; i < doCmdCopy.length; ++i) { -+ try (BufferedWriter outCmd = new BufferedWriter( -+ new FileWriter(doCmdCopy[i]))) { -+ outCmd.write("@echo %1"); -+ } -+ } -+ } catch (IOException e) { -+ throw new Error(e.getMessage()); -+ } -+ -+ // action -+ for (int k = 0; k < 3; ++k) { -+ switch (k) { -+ case 1: -+ System.setProperty("jdk.lang.Process.allowAmbigousCommands", ""); -+ break; -+ case 2: -+ System.setSecurityManager( new SecurityMan() ); -+ break; -+ } -+ for (int i = 0; i < TEST_RTE_ARG.length; ++i) { -+ String outRes; -+ try { -+ Process exec = Runtime.getRuntime().exec(TEST_RTE_ARG[i]); -+ exec.waitFor(); -+ outRes = "Success"; -+ } catch (IOException ioe) { -+ outRes = "IOException: " + ioe.getMessage(); -+ } catch (IllegalArgumentException iae) { -+ outRes = "IllegalArgumentException: " + iae.getMessage(); -+ } catch (AccessControlException se) { -+ outRes = "AccessControlException: " + se.getMessage(); -+ } -+ -+ if (!outRes.startsWith(TEST_RTE_GI[i][k])) { -+ throw new Error("Unexpected output! Step" + k + "" + i -+ + " \nArgument: " + TEST_RTE_ARG[i] -+ + "\nExpected: " + TEST_RTE_GI[i][k] -+ + "\n Output: " + outRes); -+ } else { -+ System.out.println("RTE OK:" + TEST_RTE_ARG[i]); -+ } -+ } -+ } -+ } -+} |