< prev index next >

src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptingFunctions.java

Print this page
rev 1277 : 8049300: jjs scripting: need way to quote $EXEC command arguments to protect spaces

*** 1,7 **** /* ! * Copyright (c) 2010, 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. Oracle designates this --- 1,7 ---- /* ! * Copyright (c) 2010, 2015, 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. Oracle designates this
*** 32,45 **** import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.util.Map; - import java.util.StringTokenizer; /** * Global functions supported only in scripting mode. */ public final class ScriptingFunctions { --- 32,48 ---- import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; + import java.io.StreamTokenizer; + import java.io.StringReader; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; + import java.util.ArrayList; + import java.util.List; import java.util.Map; /** * Global functions supported only in scripting mode. */ public final class ScriptingFunctions {
*** 131,149 **** */ public static Object exec(final Object self, final Object string, final Object input) throws IOException, InterruptedException { // Current global is need to fetch additional inputs and for additional results. final ScriptObject global = Context.getGlobal(); - // Break exec string into tokens. - final StringTokenizer tokenizer = new StringTokenizer(JSType.toString(string)); - final String[] cmdArray = new String[tokenizer.countTokens()]; - for (int i = 0; tokenizer.hasMoreTokens(); i++) { - cmdArray[i] = tokenizer.nextToken(); - } - // Set up initial process. ! final ProcessBuilder processBuilder = new ProcessBuilder(cmdArray); // Current ENV property state. final Object env = global.get(ENV_NAME); if (env instanceof ScriptObject) { final ScriptObject envProperties = (ScriptObject)env; --- 134,145 ---- */ public static Object exec(final Object self, final Object string, final Object input) throws IOException, InterruptedException { // Current global is need to fetch additional inputs and for additional results. final ScriptObject global = Context.getGlobal(); // Set up initial process. ! final ProcessBuilder processBuilder = new ProcessBuilder(tokenizeCommandLine(JSType.toString(string))); // Current ENV property state. final Object env = global.get(ENV_NAME); if (env instanceof ScriptObject) { final ScriptObject envProperties = (ScriptObject)env;
*** 237,242 **** --- 233,273 ---- } private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) { return MH.findStatic(MethodHandles.lookup(), ScriptingFunctions.class, name, MH.type(rtype, types)); } + + /** + * Break an exec string into tokens, honoring quoted arguments and escaped + * spaces. + * + * @param execString a String with the command line to execute. + * @return a {@link List} of {@link String}s representing the tokens that + * constitute the command line. + */ + private static List<String> tokenizeCommandLine(String execString) throws IOException { + StreamTokenizer tokenizer = new StreamTokenizer(new StringReader(execString)); + tokenizer.resetSyntax(); + tokenizer.wordChars(0, 255); + tokenizer.whitespaceChars(0, ' '); + tokenizer.commentChar('#'); + tokenizer.quoteChar('"'); + tokenizer.quoteChar('\''); + List<String> cmdList = new ArrayList<>(); + String toAppend = ""; + while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) { + String s = tokenizer.sval; + // The tokenizer understands about honoring quoted strings and recognizes + // them as one token that possibly contains multiple space-separated words. + // It does not recognize quoted spaces, though, and will split after the + // escaping \ character. This is handled here. + if (s.endsWith("\\")) { + // omit trailing \, append space instead + toAppend += s.substring(0, s.length() - 1) + " "; + } else { + cmdList.add(toAppend + s); + toAppend = ""; + } + } + return cmdList; + } }
< prev index next >