Skip to content

Commit

Permalink
Showing 2 changed files with 57 additions and 61 deletions.
31 changes: 12 additions & 19 deletions core/src/main/java/org/jruby/RubyGlobal.java
Original file line number Diff line number Diff line change
@@ -295,21 +295,13 @@ public static void createGlobals(ThreadContext context, Ruby runtime) {
globals.alias("$LAST_PAREN_MATCH", "$+");
}

@SuppressWarnings("unchecked")
private static void defineGlobalEnvConstants(Ruby runtime) {
Map environmentVariableMap;
final OSEnvironment environment = new OSEnvironment();
environmentVariableMap = environment.getEnvironmentVariableMap(runtime);

if (environmentVariableMap == null) {
// if the environment variables can't be obtained, define an empty ENV
environmentVariableMap = Collections.EMPTY_MAP;
}

CaseInsensitiveStringOnlyRubyHash env = new CaseInsensitiveStringOnlyRubyHash(runtime,
environmentVariableMap,
runtime.getNil(),
runtime.getInstanceConfig().isNativeEnabled() &&
runtime.getInstanceConfig().isUpdateNativeENVEnabled() );
Map<RubyString, RubyString> environmentVariableMap = OSEnvironment.environmentVariableMap(runtime);
RubyHash env = new CaseInsensitiveStringOnlyRubyHash(
runtime, environmentVariableMap, runtime.getNil(),
runtime.getInstanceConfig().isNativeEnabled() && runtime.getInstanceConfig().isUpdateNativeENVEnabled()
);
env.getSingletonClass().defineAnnotatedMethods(CaseInsensitiveStringOnlyRubyHash.class);
if ( ! runtime.is2_0() ) { // MRI 1.9.3 does not have ENV#to_h
env.getSingletonClass().undefineMethod("to_h");
@@ -318,11 +310,12 @@ private static void defineGlobalEnvConstants(Ruby runtime) {
runtime.setENV(env);

// Define System.getProperties() in ENV_JAVA
Map systemProps = environment.getSystemPropertiesMap(runtime);
RubyHash systemPropsHash = new ReadOnlySystemPropertiesHash(
runtime, systemProps, runtime.getNil());
systemPropsHash.setFrozen(true);
runtime.defineGlobalConstant("ENV_JAVA", systemPropsHash);
Map<RubyString, RubyString> systemPropertiesMap = OSEnvironment.systemPropertiesMap(runtime);
RubyHash envJava = new ReadOnlySystemPropertiesHash(
runtime, systemPropertiesMap, runtime.getNil()
);
envJava.setFrozen(true);
runtime.defineGlobalConstant("ENV_JAVA", envJava);
}

/**
87 changes: 45 additions & 42 deletions core/src/main/java/org/jruby/util/OSEnvironment.java
Original file line number Diff line number Diff line change
@@ -28,94 +28,97 @@

package org.jruby.util;

import org.jcodings.Encoding;
import org.jruby.Ruby;
import jnr.posix.util.Platform;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import jnr.posix.util.Platform;
import org.jcodings.Encoding;
import org.jruby.Ruby;
import org.jruby.RubyString;

public class OSEnvironment {

/**
* Returns the environment as a hash of Ruby strings.
*
* @param runtime
*/
public Map getEnvironmentVariableMap(Ruby runtime) {
Map envs = null;

if (runtime.getInstanceConfig().getEnvironment() != null) {
return getAsMapOfRubyStrings(runtime, runtime.getInstanceConfig().getEnvironment().entrySet());
}
public static Map<RubyString, RubyString> environmentVariableMap(Ruby runtime) {
@SuppressWarnings("unchecked")
Map<String, String> env = runtime.getInstanceConfig().getEnvironment();
if ( env != null ) return asMapOfRubyStrings(runtime, env);

// fall back on empty env when security disallows environment var access (like in an applet)
if (Ruby.isSecurityRestricted()) {
envs = new HashMap();
} else {
Map variables = System.getenv();
envs = getAsMapOfRubyStrings(runtime, variables.entrySet());
}
if ( Ruby.isSecurityRestricted() ) return Collections.emptyMap();

return envs;
return asMapOfRubyStrings(runtime, System.getenv());
}

public Map getEnvironmentVariableMap(Ruby runtime) {
Map envMap = OSEnvironment.environmentVariableMap(runtime);
return envMap == Collections.EMPTY_MAP ? new HashMap(4) : envMap;
}

/**
* Returns java system properties as a Map<RubyString,RubyString>.
* @param runtime
* @return the java system properties as a Map<RubyString,RubyString>.
*/
public static Map<RubyString, RubyString> systemPropertiesMap(Ruby runtime) {
if ( Ruby.isSecurityRestricted() ) return Collections.emptyMap();
return asMapOfRubyStrings(runtime, (Properties) System.getProperties().clone());
}

public Map getSystemPropertiesMap(Ruby runtime) {
if (Ruby.isSecurityRestricted()) {
return new HashMap();
} else {
return getAsMapOfRubyStrings(runtime, ((Properties)System.getProperties().clone()).entrySet());
}
Map sysMap = OSEnvironment.systemPropertiesMap(runtime);
return sysMap == Collections.EMPTY_MAP ? new HashMap(4) : sysMap;
}

private static Map getAsMapOfRubyStrings(Ruby runtime, Set<Map.Entry<Object, Object>> entrySet) {
Map envs = new HashMap();
private static Map<RubyString, RubyString> asMapOfRubyStrings(final Ruby runtime, final Map<?, ?> map) {
@SuppressWarnings("unchecked")
final Map<RubyString, RubyString> rubyMap = new HashMap(map.size() + 2);
Encoding encoding = runtime.getEncodingService().getLocaleEncoding();

// On Windows, entrySet doesn't have corresponding keys for these
if (Platform.IS_WINDOWS) {
// these may be null when in a restricted environment (JRUBY-6514)
String home = SafePropertyAccessor.getProperty("user.home");
String user = SafePropertyAccessor.getProperty("user.name");
addRubyKeyValuePair(runtime, envs, "HOME", home == null ? "/" : home, encoding);
addRubyKeyValuePair(runtime, envs, "USER", user == null ? "" : user, encoding);
putRubyKeyValuePair(runtime, rubyMap, "HOME", home == null ? "/" : home, encoding);
putRubyKeyValuePair(runtime, rubyMap, "USER", user == null ? "" : user, encoding);
}

for (Map.Entry<Object, Object> entry : entrySet) {
Object tmp = entry.getKey();
if (!(tmp instanceof String)) continue; // Java devs can stuff non-string objects into env
String key = (String) tmp;
for (Map.Entry<?, ?> entry : map.entrySet()) {
Object val = entry.getKey();

if ( ! (val instanceof String) ) continue; // Java devs can stuff non-string objects into env
final String key = (String) val;

if (Platform.IS_WINDOWS && key.startsWith("=")) continue;

tmp = entry.getValue();
if (!(tmp instanceof String)) continue; // Java devs can stuff non-string objects into env

addRubyKeyValuePair(runtime, envs, key, (String) tmp, encoding);
val = entry.getValue();
if ( ! (val instanceof String) ) continue; // Java devs can stuff non-string objects into env

putRubyKeyValuePair(runtime, rubyMap, key, (String) val, encoding);
}

return envs;
return rubyMap;
}

private static void addRubyKeyValuePair(Ruby runtime, Map map, String key, String value, Encoding encoding) {

private static void putRubyKeyValuePair(Ruby runtime,
final Map<RubyString, RubyString> map,
String key, String value, Encoding encoding) {
ByteList keyBytes = new ByteList(key.getBytes(), encoding);
ByteList valueBytes = new ByteList(value.getBytes(), encoding);

RubyString keyString = runtime.newString(keyBytes);
RubyString valueString = runtime.newString(valueBytes);

keyString.setFrozen(true);
valueString.setFrozen(true);

map.put(keyString, valueString);
}

}

0 comments on commit d6d1151

Please sign in to comment.