diff options
author | Stuart McCulloch <mcculls@gmail.com> | 2014-11-07 09:43:43 -0800 |
---|---|---|
committer | Sam Berlin <sameb@google.com> | 2014-11-07 13:22:20 -0500 |
commit | 0c3a880d89bda0fe769f9fb422eb212b72934e66 (patch) | |
tree | 29ad953b5c581fc73b1e4123f1c5ff8921258ab6 /core/src/com/google/inject | |
parent | 4f6c5672a1a685228d2970fc2dea89484430279f (diff) | |
download | guice-0c3a880d89bda0fe769f9fb422eb212b72934e66.tar.gz |
Robustness: wrap any calls to System.getProperty in case security is enabled.
Since calling System.getProperty may throw an exception on locked-down systems.
Note: this patch has the side-effect of making the 'guice_include_stack_traces'
setting static, rather than querying the system property each time a module is
installed. Making the setting static improves performance as System.getProperty
can be a bottleneck, at the cost of being able to change the setting
on-the-fly.
(This is a slightly modified version of the pull request from #872.)
-------------
Created by MOE: http://code.google.com/p/moe-java
MOE_MIGRATED_REVID=79427020
Diffstat (limited to 'core/src/com/google/inject')
-rw-r--r-- | core/src/com/google/inject/internal/BytecodeGen.java | 13 | ||||
-rw-r--r-- | core/src/com/google/inject/internal/InternalFlags.java | 84 |
2 files changed, 81 insertions, 16 deletions
diff --git a/core/src/com/google/inject/internal/BytecodeGen.java b/core/src/com/google/inject/internal/BytecodeGen.java index ad7764b7..ed01cd10 100644 --- a/core/src/com/google/inject/internal/BytecodeGen.java +++ b/core/src/com/google/inject/internal/BytecodeGen.java @@ -16,9 +16,12 @@ package com.google.inject.internal; +import static com.google.inject.internal.InternalFlags.getCustomClassLoadingOption; + import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; +import com.google.inject.internal.InternalFlags.CustomClassLoadingOption; import java.lang.reflect.Constructor; import java.lang.reflect.Member; @@ -116,10 +119,6 @@ public final class BytecodeGen { private static final String CGLIB_PACKAGE = " "; // any string that's illegal in a package name end[NO_AOP]*/ - /** Use "-Dguice.custom.loader=false" to disable custom classloading. */ - private static final boolean CUSTOM_LOADER_ENABLED - = Boolean.parseBoolean(System.getProperty("guice.custom.loader", "true")); - /** * Weak cache of bridge class loaders that make the Guice implementation * classes visible to various code-generated proxies of client classes. @@ -128,12 +127,12 @@ public final class BytecodeGen { static { CacheBuilder<Object, Object> builder = CacheBuilder.newBuilder().weakKeys().weakValues(); - if (!CUSTOM_LOADER_ENABLED) { + if (getCustomClassLoadingOption() == CustomClassLoadingOption.OFF) { builder.maximumSize(0); } CLASS_LOADER_CACHE = builder.build( new CacheLoader<ClassLoader, ClassLoader>() { - public ClassLoader load(final ClassLoader typeClassLoader) { + @Override public ClassLoader load(final ClassLoader typeClassLoader) { logger.fine("Creating a bridge ClassLoader for " + typeClassLoader); return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { public ClassLoader run() { @@ -162,7 +161,7 @@ public final class BytecodeGen { private static ClassLoader getClassLoader(Class<?> type, ClassLoader delegate) { // simple case: do nothing! - if (!CUSTOM_LOADER_ENABLED) { + if (getCustomClassLoadingOption() == CustomClassLoadingOption.OFF) { return delegate; } diff --git a/core/src/com/google/inject/internal/InternalFlags.java b/core/src/com/google/inject/internal/InternalFlags.java index 2b3c3a61..74e0db23 100644 --- a/core/src/com/google/inject/internal/InternalFlags.java +++ b/core/src/com/google/inject/internal/InternalFlags.java @@ -16,13 +16,24 @@ package com.google.inject.internal; + +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.Arrays; import java.util.logging.Logger; /** * Contains flags for Guice. */ public class InternalFlags { - private final static Logger logger = Logger.getLogger(InternalFlags.class.getName()); + private static final Logger logger = Logger.getLogger(InternalFlags.class.getName()); + + private static final IncludeStackTraceOption INCLUDE_STACK_TRACES + = parseIncludeStackTraceOption(); + + private static final CustomClassLoadingOption CUSTOM_CLASS_LOADING + = parseCustomClassLoadingOption(); + + /** * The options for Guice stack trace collection. */ @@ -35,18 +46,73 @@ public class InternalFlags { COMPLETE } + /** + * The options for Guice custom class loading. + */ + public enum CustomClassLoadingOption { + /** No custom class loading */ + OFF, + /** Automatically bridge between class loaders (Default) */ + BRIDGE + } public static IncludeStackTraceOption getIncludeStackTraceOption() { - String flag = System.getProperty("guice_include_stack_traces"); + return INCLUDE_STACK_TRACES; + } + + public static CustomClassLoadingOption getCustomClassLoadingOption() { + return CUSTOM_CLASS_LOADING; + } + + private static IncludeStackTraceOption parseIncludeStackTraceOption() { + return getSystemOption("guice_include_stack_traces", + IncludeStackTraceOption.ONLY_FOR_DECLARING_SOURCE); + } + + private static CustomClassLoadingOption parseCustomClassLoadingOption() { + return getSystemOption("guice_custom_class_loading", + CustomClassLoadingOption.BRIDGE, CustomClassLoadingOption.OFF); + } + + /** + * Gets the system option indicated by the specified key; runs as a privileged action. + * + * @param name of the system option + * @param defaultValue if the option is not set + * + * @return value of the option, defaultValue if not set + */ + private static <T extends Enum<T>> T getSystemOption(final String name, T defaultValue) { + return getSystemOption(name, defaultValue, defaultValue); + } + + /** + * Gets the system option indicated by the specified key; runs as a privileged action. + * + * @param name of the system option + * @param defaultValue if the option is not set + * @param secureValue if the security manager disallows access to the option + * + * @return value of the option, defaultValue if not set, secureValue if no access + */ + private static <T extends Enum<T>> T getSystemOption(final String name, T defaultValue, + T secureValue) { + @SuppressWarnings("unchecked") + Class<T> enumType = defaultValue.getDeclaringClass(); + String value = null; try { - return (flag == null || flag.length() == 0) - ? IncludeStackTraceOption.ONLY_FOR_DECLARING_SOURCE - : IncludeStackTraceOption.valueOf(flag); + value = AccessController.doPrivileged(new PrivilegedAction<String>() { + public String run() { + return System.getProperty(name); + } + }); + return (value != null && value.length() > 0) ? Enum.valueOf(enumType, value) : defaultValue; + } catch (SecurityException e) { + return secureValue; } catch (IllegalArgumentException e) { - logger.warning(flag - + " is not a valid flag value for guice_include_stack_traces. " - + " Values must be one of " + Arrays.asList(IncludeStackTraceOption.values())); - return IncludeStackTraceOption.ONLY_FOR_DECLARING_SOURCE; + logger.warning(value + " is not a valid flag value for " + name + ". " + + " Values must be one of " + Arrays.asList(enumType.getEnumConstants())); + return defaultValue; } } } |