8157310: jdk.dynalink.linker.support.Lookup should have more checks before adding module read link

Reviewed-by: hannesw, attila
This commit is contained in:
Athijegannathan Sundararajan 2016-05-20 13:20:10 +05:30
parent 9a8cbd6e1b
commit c81faa1b04
2 changed files with 62 additions and 62 deletions

View File

@ -88,9 +88,11 @@ import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Module;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
@ -98,6 +100,9 @@ import jdk.dynalink.CallSiteDescriptor;
import jdk.dynalink.SecureLookupSupplier;
import jdk.dynalink.internal.AccessControlContextFactory;
import jdk.dynalink.linker.support.Lookup;
import jdk.internal.module.Modules;
import jdk.internal.reflect.CallerSensitive;
/**
* A dynamic method bound to exactly one Java method or constructor that is caller sensitive. Since the target method is
@ -159,13 +164,13 @@ class CallerSensitiveDynamicMethod extends SingleDynamicMethod {
GET_LOOKUP_CONTEXT);
if(target instanceof Method) {
final MethodHandle mh = Lookup.unreflectCallerSensitive(lookup, (Method)target);
final MethodHandle mh = unreflect(lookup, (Method)target);
if(Modifier.isStatic(((Member)target).getModifiers())) {
return StaticClassIntrospector.editStaticMethodHandle(mh);
}
return mh;
}
return StaticClassIntrospector.editConstructorMethodHandle(Lookup.unreflectConstructorCallerSensitive(lookup,
return StaticClassIntrospector.editConstructorMethodHandle(unreflectConstructor(lookup,
(Constructor<?>)target));
}
@ -173,4 +178,59 @@ class CallerSensitiveDynamicMethod extends SingleDynamicMethod {
boolean isConstructor() {
return target instanceof Constructor;
}
private static MethodHandle unreflect(final MethodHandles.Lookup lookup, final Method m) {
try {
return Lookup.unreflect(lookup, m);
} catch (final IllegalAccessError iae) {
if (addModuleRead(lookup, m)) {
try {
return Lookup.unreflect(lookup, m);
} catch (final IllegalAccessError e2) {
// fall through and throw original error as cause
}
}
throw iae;
}
}
private static MethodHandle unreflectConstructor(final MethodHandles.Lookup lookup, final Constructor<?> c) {
try {
return Lookup.unreflectConstructor(lookup, c);
} catch (final IllegalAccessError iae) {
if (addModuleRead(lookup, c)) {
try {
return Lookup.unreflectConstructor(lookup, c);
} catch (final IllegalAccessError e2) {
// fall through and throw original error as cause
}
}
throw iae;
}
}
private static boolean addModuleRead(final MethodHandles.Lookup lookup, final Executable e) {
// Don't add module read link if this is not a CallerSensitive member
if (!e.isAnnotationPresent(CallerSensitive.class)) {
return false;
}
// If the lookup is public lookup, don't bother adding module read link!
// public lookup cannot unreflect caller sensitives anyway!
if (lookup == MethodHandles.publicLookup()) {
return false;
}
// try to add missing module read from using module to declararing module!
final Class<?> declClass = e.getDeclaringClass();
final Module useModule = lookup.lookupClass().getModule();
final Module declModule = declClass.getModule();
if (useModule != null && declModule != null && declModule.isExported(declClass.getPackageName())) {
Modules.addReads(useModule, declModule);
return true;
}
return false;
}
}

View File

@ -91,7 +91,6 @@ import java.lang.reflect.Executable;
import java.lang.reflect.Field;
import java.lang.reflect.Module;
import java.lang.reflect.Method;
import jdk.internal.module.Modules;
/**
* A wrapper around {@link java.lang.invoke.MethodHandles.Lookup} that masks
@ -130,42 +129,6 @@ public final class Lookup {
return unreflect(lookup, m);
}
private static boolean addModuleRead(final MethodHandles.Lookup lookup, final Executable e) {
// may be module read missing from a script class!
final Class<?> declClass = e.getDeclaringClass();
final Module from = lookup.lookupClass().getModule();
final Module to = declClass.getModule();
if (from != null && to != null) {
Modules.addReads(from, to);
return true;
}
return false;
}
/**
* Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflect(Method)}, of a caller sensitive method
* converting any encountered {@link IllegalAccessException} into an {@link IllegalAccessError}.
*
* @param lookup the lookup used to unreflect
* @param m the method to unreflect
* @return the unreflected method handle.
*/
public static MethodHandle unreflectCallerSensitive(final MethodHandles.Lookup lookup, final Method m) {
try {
return unreflect(lookup, m);
} catch (final IllegalAccessError iae) {
if (addModuleRead(lookup, m)) {
try {
return unreflect(lookup, m);
} catch (final IllegalAccessError e2) {
// fall through and throw original error as cause
}
}
throw iae;
}
}
/**
* Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflect(Method)},
* converting any encountered {@link IllegalAccessException} into an
@ -266,29 +229,6 @@ public final class Lookup {
return unreflectConstructor(lookup, c);
}
/**
* Performs a caller sensitive {@link java.lang.invoke.MethodHandles.Lookup#unreflectConstructor(Constructor)}, converting any
* encountered {@link IllegalAccessException} into an {@link IllegalAccessError}.
*
* @param lookup the lookup used to unreflect
* @param c the constructor to unreflect
* @return the unreflected constructor handle.
*/
public static MethodHandle unreflectConstructorCallerSensitive(final MethodHandles.Lookup lookup, final Constructor<?> c) {
try {
return unreflectConstructor(lookup, c);
} catch (final IllegalAccessError iae) {
if (addModuleRead(lookup, c)) {
try {
return unreflectConstructor(lookup, c);
} catch (final IllegalAccessError e2) {
// fall through and throw original error as cause
}
}
throw iae;
}
}
/**
* Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflectConstructor(Constructor)},
* converting any encountered {@link IllegalAccessException} into an