< 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 >