aboutsummaryrefslogtreecommitdiff
path: root/src/share/classes/java/lang
diff options
context:
space:
mode:
authorpoonam <none@none>2016-03-21 13:37:11 -0700
committerpoonam <none@none>2016-03-21 13:37:11 -0700
commit0fda41e1f243318cd4e5e85671fb24da84ceb702 (patch)
tree776f24d5d9917ebead4141e0bfbcd8c4793cecdd /src/share/classes/java/lang
parent5f5b2a92bdfe2b93aa3458b700479b3ca5cc26df (diff)
downloadjdk8u_jdk-0fda41e1f243318cd4e5e85671fb24da84ceb702.tar.gz
8152335: Improve MethodHandle consistency
Reviewed-by: vlivanov, acorn, jrose
Diffstat (limited to 'src/share/classes/java/lang')
-rw-r--r--src/share/classes/java/lang/ClassLoader.java3
-rw-r--r--src/share/classes/java/lang/invoke/MemberName.java29
-rw-r--r--src/share/classes/java/lang/invoke/MethodHandleNatives.java2
3 files changed, 26 insertions, 8 deletions
diff --git a/src/share/classes/java/lang/ClassLoader.java b/src/share/classes/java/lang/ClassLoader.java
index 9bf5736c0c..842af56143 100644
--- a/src/share/classes/java/lang/ClassLoader.java
+++ b/src/share/classes/java/lang/ClassLoader.java
@@ -653,6 +653,9 @@ public abstract class ClassLoader {
if (!checkName(name))
throw new NoClassDefFoundError("IllegalName: " + name);
+ // Note: Checking logic in java.lang.invoke.MemberName.checkForTypeAlias
+ // relies on the fact that spoofing is impossible if a class has a name
+ // of the form "java.*"
if ((name != null) && name.startsWith("java.")) {
throw new SecurityException
("Prohibited package name: " +
diff --git a/src/share/classes/java/lang/invoke/MemberName.java b/src/share/classes/java/lang/invoke/MemberName.java
index d0c6e42413..bcc08e71d9 100644
--- a/src/share/classes/java/lang/invoke/MemberName.java
+++ b/src/share/classes/java/lang/invoke/MemberName.java
@@ -783,7 +783,7 @@ import java.util.Objects;
assert(isResolved() == isResolved);
}
- void checkForTypeAlias() {
+ void checkForTypeAlias(Class<?> refc) {
if (isInvocable()) {
MethodType type;
if (this.type instanceof MethodType)
@@ -791,16 +791,16 @@ import java.util.Objects;
else
this.type = type = getMethodType();
if (type.erase() == type) return;
- if (VerifyAccess.isTypeVisible(type, clazz)) return;
- throw new LinkageError("bad method type alias: "+type+" not visible from "+clazz);
+ if (VerifyAccess.isTypeVisible(type, refc)) return;
+ throw new LinkageError("bad method type alias: "+type+" not visible from "+refc);
} else {
Class<?> type;
if (this.type instanceof Class<?>)
type = (Class<?>) this.type;
else
this.type = type = getFieldType();
- if (VerifyAccess.isTypeVisible(type, clazz)) return;
- throw new LinkageError("bad field type alias: "+type+" not visible from "+clazz);
+ if (VerifyAccess.isTypeVisible(type, refc)) return;
+ throw new LinkageError("bad field type alias: "+type+" not visible from "+refc);
}
}
@@ -959,10 +959,25 @@ import java.util.Objects;
MemberName m = ref.clone(); // JVM will side-effect the ref
assert(refKind == m.getReferenceKind());
try {
+ // There are 4 entities in play here:
+ // * LC: lookupClass
+ // * REFC: symbolic reference class (MN.clazz before resolution);
+ // * DEFC: resolved method holder (MN.clazz after resolution);
+ // * PTYPES: parameter types (MN.type)
+ //
+ // What we care about when resolving a MemberName is consistency between DEFC and PTYPES.
+ // We do type alias (TA) checks on DEFC to ensure that. DEFC is not known until the JVM
+ // finishes the resolution, so do TA checks right after MHN.resolve() is over.
+ //
+ // All parameters passed by a caller are checked against MH type (PTYPES) on every invocation,
+ // so it is safe to call a MH from any context.
+ //
+ // REFC view on PTYPES doesn't matter, since it is used only as a starting point for resolution and doesn't
+ // participate in method selection.
m = MethodHandleNatives.resolve(m, lookupClass);
- m.checkForTypeAlias();
+ m.checkForTypeAlias(m.getDeclaringClass());
m.resolution = null;
- } catch (LinkageError ex) {
+ } catch (ClassNotFoundException | LinkageError ex) {
// JVM reports that the "bytecode behavior" would get an error
assert(!m.isResolved());
m.resolution = ex;
diff --git a/src/share/classes/java/lang/invoke/MethodHandleNatives.java b/src/share/classes/java/lang/invoke/MethodHandleNatives.java
index 0f5169e95e..ecc1460785 100644
--- a/src/share/classes/java/lang/invoke/MethodHandleNatives.java
+++ b/src/share/classes/java/lang/invoke/MethodHandleNatives.java
@@ -45,7 +45,7 @@ class MethodHandleNatives {
static native void init(MemberName self, Object ref);
static native void expand(MemberName self);
- static native MemberName resolve(MemberName self, Class<?> caller) throws LinkageError;
+ static native MemberName resolve(MemberName self, Class<?> caller) throws LinkageError, ClassNotFoundException;
static native int getMembers(Class<?> defc, String matchName, String matchSig,
int matchFlags, Class<?> caller, int skip, MemberName[] results);