summaryrefslogtreecommitdiff
path: root/external/ikvm/openjdk/java/lang/Class.java
diff options
context:
space:
mode:
Diffstat (limited to 'external/ikvm/openjdk/java/lang/Class.java')
-rw-r--r--external/ikvm/openjdk/java/lang/Class.java181
1 files changed, 121 insertions, 60 deletions
diff --git a/external/ikvm/openjdk/java/lang/Class.java b/external/ikvm/openjdk/java/lang/Class.java
index 20f35534c3..bbc1d241f6 100644
--- a/external/ikvm/openjdk/java/lang/Class.java
+++ b/external/ikvm/openjdk/java/lang/Class.java
@@ -53,6 +53,7 @@ import java.util.Set;
import java.util.Map;
import java.util.HashMap;
import sun.misc.Unsafe;
+import sun.reflect.CallerSensitive;
import sun.reflect.ConstantPool;
import sun.reflect.Reflection;
import sun.reflect.ReflectionFactory;
@@ -65,7 +66,9 @@ import sun.reflect.generics.repository.ConstructorRepository;
import sun.reflect.generics.scope.ClassScope;
import sun.security.util.SecurityConstants;
import java.lang.annotation.Annotation;
-import sun.reflect.annotation.AnnotationType;
+import java.lang.reflect.Proxy;
+import sun.reflect.annotation.*;
+import sun.reflect.misc.ReflectUtil;
import cli.System.Runtime.Serialization.IObjectReference;
import cli.System.Runtime.Serialization.SerializationException;
import cli.System.Runtime.Serialization.SerializationInfo;
@@ -281,10 +284,11 @@ public final
* by this method fails
* @exception ClassNotFoundException if the class cannot be located
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public static Class<?> forName(String className)
throws ClassNotFoundException {
- return forName0(className, true, ClassLoader.getCallerClassLoader());
+ return forName0(className, true,
+ ClassLoader.getClassLoader(Reflection.getCallerClass()));
}
@@ -348,7 +352,7 @@ public final
* @see java.lang.ClassLoader
* @since 1.2
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public static Class<?> forName(String name, boolean initialize,
ClassLoader loader)
throws ClassNotFoundException
@@ -356,7 +360,7 @@ public final
if (loader == null) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- ClassLoader ccl = ClassLoader.getCallerClassLoader();
+ ClassLoader ccl = ClassLoader.getClassLoader(Reflection.getCallerClass());
if (ccl != null) {
sm.checkPermission(
SecurityConstants.GET_CLASSLOADER_PERMISSION);
@@ -418,19 +422,14 @@ public final
* </ul>
*
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public T newInstance()
throws InstantiationException, IllegalAccessException
{
if (System.getSecurityManager() != null) {
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
}
- return newInstance0(ikvm.internal.CallerID.getCallerID());
- }
- private T newInstance0(ikvm.internal.CallerID callerID)
- throws InstantiationException, IllegalAccessException
- {
// NOTE: the following code may not be strictly correct under
// the current Java memory model.
@@ -464,7 +463,7 @@ public final
// Security check (same as in java.lang.reflect.Constructor)
int modifiers = tmpConstructor.getModifiers();
if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
- Class<?> caller = callerID.getCallerClass();
+ Class<?> caller = Reflection.getCallerClass();
if (newInstanceCallerCache != caller) {
Reflection.ensureMemberAccess(caller, this, null, modifiers);
newInstanceCallerCache = caller;
@@ -705,17 +704,14 @@ public final
* @see SecurityManager#checkPermission
* @see java.lang.RuntimePermission
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public ClassLoader getClassLoader() {
ClassLoader cl = getClassLoader0();
if (cl == null)
return null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- ClassLoader ccl = ClassLoader.getCallerClassLoader();
- if (ccl != null && ccl != cl && !cl.isAncestor(ccl)) {
- sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
- }
+ ClassLoader.checkClassLoaderPermission(cl, Reflection.getCallerClass());
}
return cl;
}
@@ -996,6 +992,7 @@ public final
* that class is a local or anonymous class; otherwise {@code null}.
* @since 1.5
*/
+ @CallerSensitive
public Method getEnclosingMethod() {
EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
@@ -1017,13 +1014,22 @@ public final
for(int i = 0; i < parameterClasses.length; i++)
parameterClasses[i] = toClass(parameterTypes[i]);
+ // Perform access check
+ Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();
+ // be very careful not to change the stack depth of this
+ // checkMemberAccess call for security reasons
+ // see java.lang.SecurityManager.checkMemberAccess
+ //
+ // Note that we need to do this on the enclosing class
+ enclosingCandidate.checkMemberAccess(Member.DECLARED,
+ Reflection.getCallerClass(), true);
/*
* Loop over all declared methods; match method name,
* number of and type of parameters, *and* return
* type. Matching return type is also necessary
* because of covariant returns, etc.
*/
- for(Method m: enclosingInfo.getEnclosingClass().getDeclaredMethods()) {
+ for(Method m: enclosingCandidate.getDeclaredMethods()) {
if (m.getName().equals(enclosingInfo.getName()) ) {
Class<?>[] candidateParamClasses = m.getParameterTypes();
if (candidateParamClasses.length == parameterClasses.length) {
@@ -1124,6 +1130,7 @@ public final
* that class is a local or anonymous class; otherwise {@code null}.
* @since 1.5
*/
+ @CallerSensitive
public Constructor<?> getEnclosingConstructor() {
EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
@@ -1144,11 +1151,20 @@ public final
for(int i = 0; i < parameterClasses.length; i++)
parameterClasses[i] = toClass(parameterTypes[i]);
+ // Perform access check
+ Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();
+ // be very careful not to change the stack depth of this
+ // checkMemberAccess call for security reasons
+ // see java.lang.SecurityManager.checkMemberAccess
+ //
+ // Note that we need to do this on the enclosing class
+ enclosingCandidate.checkMemberAccess(Member.DECLARED,
+ Reflection.getCallerClass(), true);
/*
* Loop over all declared constructors; match number
* of and type of parameters.
*/
- for(Constructor<?> c: enclosingInfo.getEnclosingClass().getDeclaredConstructors()) {
+ for(Constructor<?> c: enclosingCandidate.getDeclaredConstructors()) {
Class<?>[] candidateParamClasses = c.getParameterTypes();
if (candidateParamClasses.length == parameterClasses.length) {
boolean matches = true;
@@ -1190,6 +1206,7 @@ public final
* @return the immediately enclosing class of the underlying class
* @since 1.5
*/
+ @CallerSensitive
public Class<?> getEnclosingClass() {
// There are five kinds of classes (or interfaces):
// a) Top level classes
@@ -1203,18 +1220,24 @@ public final
// attribute if and only if it is a local class or an
// anonymous class.
EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
+ Class<?> enclosingCandidate;
if (enclosingInfo == null) {
// This is a top level or a nested class or an inner class (a, b, or c)
- return getDeclaringClass();
+ enclosingCandidate = getDeclaringClass();
} else {
Class<?> enclosingClass = enclosingInfo.getEnclosingClass();
// This is a local class or an anonymous class (d or e)
if (enclosingClass == this || enclosingClass == null)
throw new InternalError("Malformed enclosing method information");
else
- return enclosingClass;
+ enclosingCandidate = enclosingClass;
}
+
+ if (enclosingCandidate != null)
+ enclosingCandidate.checkPackageAccess(
+ ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
+ return enclosingCandidate;
}
/**
@@ -1397,12 +1420,12 @@ public final
*
* @since JDK1.1
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Class<?>[] getClasses() {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
// Privileged so this implementation can look at DECLARED classes,
// something the caller might not have privilege to do. The code here
@@ -1473,12 +1496,12 @@ public final
*
* @since JDK1.1
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Field[] getFields() throws SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
return copyFields(privateGetPublicFields(null));
}
@@ -1525,12 +1548,12 @@ public final
*
* @since JDK1.1
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Method[] getMethods() throws SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
return copyMethods(privateGetPublicMethods());
}
@@ -1575,12 +1598,12 @@ public final
*
* @since JDK1.1
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Constructor<?>[] getConstructors() throws SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
return copyConstructors(privateGetDeclaredConstructors(true));
}
@@ -1634,13 +1657,13 @@ public final
*
* @since JDK1.1
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Field getField(String name)
throws NoSuchFieldException, SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
Field field = getField0(name);
if (field == null) {
throw new NoSuchFieldException(name);
@@ -1720,13 +1743,13 @@ public final
*
* @since JDK1.1
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Method getMethod(String name, Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
Method method = getMethod0(name, parameterTypes);
if (method == null) {
throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
@@ -1775,13 +1798,13 @@ public final
*
* @since JDK1.1
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Constructor<T> getConstructor(Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
return getConstructor0(parameterTypes, Member.PUBLIC);
}
@@ -1819,12 +1842,12 @@ public final
*
* @since JDK1.1
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Class<?>[] getDeclaredClasses() throws SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), false);
return getDeclaredClasses0();
}
@@ -1864,12 +1887,12 @@ public final
*
* @since JDK1.1
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Field[] getDeclaredFields() throws SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
return copyFields(privateGetDeclaredFields(false));
}
@@ -1913,12 +1936,12 @@ public final
*
* @since JDK1.1
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Method[] getDeclaredMethods() throws SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
return copyMethods(privateGetDeclaredMethods(false));
}
@@ -1959,12 +1982,12 @@ public final
*
* @since JDK1.1
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Constructor<?>[] getDeclaredConstructors() throws SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
return copyConstructors(privateGetDeclaredConstructors(false));
}
@@ -2003,13 +2026,13 @@ public final
*
* @since JDK1.1
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Field getDeclaredField(String name)
throws NoSuchFieldException, SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
Field field = searchFields(privateGetDeclaredFields(false), name);
if (field == null) {
throw new NoSuchFieldException(name);
@@ -2059,13 +2082,13 @@ public final
*
* @since JDK1.1
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
if (method == null) {
throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
@@ -2110,13 +2133,13 @@ public final
*
* @since JDK1.1
*/
- @ikvm.internal.HasCallerID
+ @CallerSensitive
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+ checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
return getConstructor0(parameterTypes, Member.DECLARED);
}
@@ -2274,31 +2297,69 @@ public final
*/
static native Class getPrimitiveClass(String name);
+ private static boolean isCheckMemberAccessOverridden(SecurityManager smgr) {
+ if (smgr.getClass() == SecurityManager.class) return false;
+
+ Class<?>[] paramTypes = new Class<?>[] {Class.class, int.class};
+ return smgr.getClass().getMethod0("checkMemberAccess", paramTypes).
+ getDeclaringClass() != SecurityManager.class;
+ }
+
/*
* Check if client is allowed to access members. If access is denied,
* throw a SecurityException.
*
- * Be very careful not to change the stack depth of this checkMemberAccess
- * call for security reasons.
- * See java.lang.SecurityManager.checkMemberAccess.
+ * This method also enforces package access.
*
* <p> Default policy: allow all clients access with normal Java access
* control.
*/
- private void checkMemberAccess(int which, ClassLoader ccl) {
- SecurityManager s = System.getSecurityManager();
+ private void checkMemberAccess(int which, Class<?> caller, boolean checkProxyInterfaces) {
+ final SecurityManager s = System.getSecurityManager();
if (s != null) {
- s.checkMemberAccess(this, which);
- ClassLoader cl = getClassLoader0();
- if ((ccl != null) && (ccl != cl) &&
- ((cl == null) || !cl.isAncestor(ccl))) {
+ final ClassLoader ccl = ClassLoader.getClassLoader(caller);
+ final ClassLoader cl = getClassLoader0();
+ if (!isCheckMemberAccessOverridden(s)) {
+ // Inlined SecurityManager.checkMemberAccess
+ if (which != Member.PUBLIC) {
+ if (ccl != cl) {
+ s.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
+ }
+ }
+ } else {
+ // Don't refactor; otherwise break the stack depth for
+ // checkMemberAccess of subclasses of SecurityManager as specified.
+ s.checkMemberAccess(this, which);
+ }
+ this.checkPackageAccess(ccl, checkProxyInterfaces);
+ }
+ }
+
+ /*
+ * Checks if a client loaded in ClassLoader ccl is allowed to access this
+ * class under the current package access policy. If access is denied,
+ * throw a SecurityException.
+ */
+ private void checkPackageAccess(final ClassLoader ccl, boolean checkProxyInterfaces) {
+ final SecurityManager s = System.getSecurityManager();
+ if (s != null) {
+ final ClassLoader cl = getClassLoader0();
+ if (ReflectUtil.needsPackageAccessCheck(ccl, cl)) {
String name = this.getName();
int i = name.lastIndexOf('.');
if (i != -1) {
- s.checkPackageAccess(name.substring(0, i));
+ // skip the package access check on a proxy class in default proxy package
+ String pkg = name.substring(0, i);
+ if (!Proxy.isProxyClass(this) || ReflectUtil.isNonPublicProxyClass(this)) {
+ s.checkPackageAccess(pkg);
+ }
}
}
+ // check package access on the proxy interfaces
+ if (checkProxyInterfaces && Proxy.isProxyClass(this)) {
+ ReflectUtil.checkProxyPackageAccess(ccl, this.getInterfaces());
+ }
}
}