diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/util/Apps.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/util/Apps.java index 9235e7d..2d70948 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/util/Apps.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/util/Apps.java @@ -46,12 +46,10 @@ public static final String ID = "ID"; private static final Pattern VAR_SUBBER = Pattern.compile(Shell.getEnvironmentVariableRegex()); - private static final Pattern VARVAL_SPLITTER = Pattern.compile( - "(?<=^|,)" // preceded by ',' or line begin - + '(' + Shell.ENV_NAME_REGEX + ')' // var group - + '=' - + "([^,]*)" // val group - ); + private static final String ENV_SPLIT = + ",(?=(?:[^\"']*[\"'][^\"']*[\"'])*[^\"']*$)"; + private static final Pattern ENV_PAIR = + Pattern.compile("^(" + Shell.ENV_NAME_REGEX + ")=[\"']?([^\"']*)[\"']?$"); public static ApplicationId toAppID(String aid) { Iterator it = _split(aid).iterator(); @@ -81,26 +79,27 @@ public static void throwParseException(String name, String s) { public static void setEnvFromInputString(Map env, String envString, String classPathSeparator) { if (envString != null && envString.length() > 0) { - Matcher varValMatcher = VARVAL_SPLITTER.matcher(envString); - while (varValMatcher.find()) { - String envVar = varValMatcher.group(1); - Matcher m = VAR_SUBBER.matcher(varValMatcher.group(2)); - StringBuffer sb = new StringBuffer(); - while (m.find()) { - String var = m.group(1); - // replace $env with the child's env constructed by tt's - String replace = env.get(var); - // if this key is not configured by the tt for the child .. get it - // from the tt's env - if (replace == null) - replace = System.getenv(var); - // the env key is note present anywhere .. simply set it - if (replace == null) - replace = ""; - m.appendReplacement(sb, Matcher.quoteReplacement(replace)); + for (String pair : envString.split(ENV_SPLIT, -1)) { + Matcher envPairsMatcher = ENV_PAIR.matcher(pair); + while (envPairsMatcher.find()) { + String key = envPairsMatcher.group(1); + String value = envPairsMatcher.group(2); + Matcher m = VAR_SUBBER.matcher(value); + StringBuffer sb = new StringBuffer(); + while (m.find()) { + String var = m.group(1); + String replace = env.get(var); + if (replace == null) { + replace = System.getenv(var); + } + if (replace == null) { + replace = ""; + } + m.appendReplacement(sb, Matcher.quoteReplacement(replace)); + } + m.appendTail(sb); + addToEnvironment(env, key, sb.toString(), classPathSeparator); } - m.appendTail(sb); - addToEnvironment(env, envVar, sb.toString(), classPathSeparator); } } } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/util/TestApps.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/util/TestApps.java index 66d2d23..e7aded2 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/util/TestApps.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/test/java/org/apache/hadoop/yarn/util/TestApps.java @@ -32,13 +32,15 @@ public void testSetEnvFromInputString() { Map environment = new HashMap(); environment.put("JAVA_HOME", "/path/jdk"); String goodEnv = "a1=1,b_2=2,_c=3,d=4,e=,f_win=%JAVA_HOME%" - + ",g_nix=$JAVA_HOME"; + + ",g_nix=$JAVA_HOME,h='6,7',i=\"8,9\""; Apps.setEnvFromInputString(environment, goodEnv, File.pathSeparator); assertEquals("1", environment.get("a1")); assertEquals("2", environment.get("b_2")); assertEquals("3", environment.get("_c")); assertEquals("4", environment.get("d")); assertEquals("", environment.get("e")); + assertEquals("6,7", environment.get("h")); + assertEquals("8,9", environment.get("i")); if (Shell.WINDOWS) { assertEquals("$JAVA_HOME", environment.get("g_nix")); assertEquals("/path/jdk", environment.get("f_win")); @@ -49,7 +51,7 @@ public void testSetEnvFromInputString() { String badEnv = "1,,2=a=b,3=a=,4==,5==a,==,c-3=3,="; environment.clear(); Apps.setEnvFromInputString(environment, badEnv, File.pathSeparator); - assertEquals(environment.size(), 0); + assertEquals(0, environment.size()); // Test "=" in the value part environment.clear(); @@ -57,5 +59,10 @@ public void testSetEnvFromInputString() { File.pathSeparator); assertEquals("=", environment.get("e1")); assertEquals("a1=a2", environment.get("e2")); + + // Test empty string + environment.clear(); + Apps.setEnvFromInputString(environment, "", File.pathSeparator); + assertEquals(0, environment.size()); } }