< prev index next >
test/java/lang/invoke/AccessControlTest.java
Print this page
*** 1,7 ****
/*
! * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
--- 1,7 ----
/*
! * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*** 116,125 ****
--- 116,127 ----
String suffix = "";
if (lookupModes == 0)
suffix = "/noaccess";
else if (lookupModes == PUBLIC)
suffix = "/public";
+ else if (lookupModes == (PUBLIC|UNCONDITIONAL))
+ suffix = "/publicLookup";
else if (lookupModes == (PUBLIC|MODULE))
suffix = "/module";
else if (lookupModes == (PUBLIC|MODULE|PACKAGE))
suffix = "/package";
else if (lookupModes == (PUBLIC|MODULE|PACKAGE|PRIVATE))
*** 138,164 ****
* class as its own {@link #lookupClass lookupClass}.
* <p>
* [A2] However, the resulting {@code Lookup} object is guaranteed
* to have no more access capabilities than the original.
* In particular, access capabilities can be lost as follows:<ul>
! * <li>[A3] If the new lookup class differs from the old one,
! * protected members will not be accessible by virtue of inheritance.
* (Protected members may continue to be accessible because of package sharing.)
! * <li>[A4] If the new lookup class is in a different package
! * than the old one, protected and default (package) members will not be accessible.
! * <li>[A5] If the new lookup class is not within the same package member
* as the old one, private members will not be accessible.
! * <li>[A6] If the new lookup class is not accessible to the old lookup class,
! * using the original access modes,
* then no members, not even public members, will be accessible.
! * <li>[A7] If the new lookup class for this {@code Lookup} is in the unnamed module,
! * and the new lookup class is in a named module {@code M}, then no members in
! * {@code M}'s non-exported packages will be accessible.
! * <li>[A8] If the lookup for this {@code Lookup} is in a named module, and the
! * new lookup class is in a different module, then no members, not even
! * public members in {@code M}'s exported packages, will be accessible.
! * [A8] (In all other cases, public members will continue to be accessible.)
* </ul>
* Other than the above cases, the new lookup will have the same
* access capabilities as the original. [A10]
* <hr>
*/
--- 140,167 ----
* class as its own {@link #lookupClass lookupClass}.
* <p>
* [A2] However, the resulting {@code Lookup} object is guaranteed
* to have no more access capabilities than the original.
* In particular, access capabilities can be lost as follows:<ul>
! * <li> [A3] If the old lookup class is in a named module, and the new
! * lookup class is in a different module {@code M}, then no members, not
! * even public members in {@code M}'s exported packages, will be accessible.
! * The exception to this is when this lookup is publicLookup, in which case
! * public access is not lost.
! * <li> [A4] If the old lookup class is in an unnamed module, and the new
! * lookup class is a different module then module access is lost.
! * <li> [A5] If the new lookup class differs from the old one then UNCONDITIONAL
! * is lost. If the new lookup class is not within the same package member as the
! * old one, protected members will not be accessible by virtue of inheritance.
* (Protected members may continue to be accessible because of package sharing.)
! * <li> [A6] If the new lookup class is in a different package than the old one,
! * protected and default (package) members will not be accessible.
! * <li> [A7] If the new lookup class is not within the same package member
* as the old one, private members will not be accessible.
! * <li> [A8] If the new lookup class is not accessible to the old lookup class,
* then no members, not even public members, will be accessible.
! * <li> [A9] (In all other cases, public members will continue to be accessible.)
* </ul>
* Other than the above cases, the new lookup will have the same
* access capabilities as the original. [A10]
* <hr>
*/
*** 169,208 ****
// for the purposes of access control then treat classes in different unnamed
// modules as being in the same module.
boolean sameModule = (c1.getModule() == c2.getModule()) ||
(!c1.getModule().isNamed() && !c2.getModule().isNamed());
boolean samePackage = (c1.getClassLoader() == c2.getClassLoader() &&
! packagePrefix(c1).equals(packagePrefix(c2)));
boolean sameTopLevel = (topLevelClass(c1) == topLevelClass(c2));
boolean sameClass = (c1 == c2);
assert(samePackage || !sameTopLevel);
assert(sameTopLevel || !sameClass);
! boolean accessible = sameClass; // [A6]
if ((m1 & PACKAGE) != 0) accessible |= samePackage;
if ((m1 & PUBLIC ) != 0) accessible |= (c2.getModifiers() & PUBLIC) != 0;
if (!sameModule) {
! if (c1.getModule().isNamed()) {
! accessible = false; // [A8]
} else {
! // Different module; loose MODULE and lower access.
! changed |= (MODULE|PACKAGE|PRIVATE|PROTECTED); // [A7]
}
}
if (!accessible) {
// Different package and no access to c2; lose all access.
! changed |= (PUBLIC|MODULE|PACKAGE|PRIVATE|PROTECTED); // [A6]
}
if (!samePackage) {
// Different package; loose PACKAGE and lower access.
! changed |= (PACKAGE|PRIVATE|PROTECTED); // [A4]
}
if (!sameTopLevel) {
! // Different top-level class. Lose PRIVATE and lower access.
! changed |= (PRIVATE|PROTECTED); // [A5]
}
if (!sameClass) {
! changed |= (PROTECTED); // [A3]
} else {
assert(changed == 0); // [A10] (no deprivation if same class)
}
if (accessible) assert((changed & PUBLIC) == 0); // [A9]
int m2 = m1 & ~changed;
--- 172,210 ----
// for the purposes of access control then treat classes in different unnamed
// modules as being in the same module.
boolean sameModule = (c1.getModule() == c2.getModule()) ||
(!c1.getModule().isNamed() && !c2.getModule().isNamed());
boolean samePackage = (c1.getClassLoader() == c2.getClassLoader() &&
! c1.getPackageName().equals(c2.getPackageName()));
boolean sameTopLevel = (topLevelClass(c1) == topLevelClass(c2));
boolean sameClass = (c1 == c2);
assert(samePackage || !sameTopLevel);
assert(sameTopLevel || !sameClass);
! boolean accessible = sameClass;
if ((m1 & PACKAGE) != 0) accessible |= samePackage;
if ((m1 & PUBLIC ) != 0) accessible |= (c2.getModifiers() & PUBLIC) != 0;
if (!sameModule) {
! if (c1.getModule().isNamed() && (m1 & UNCONDITIONAL) == 0) {
! accessible = false; // [A3]
} else {
! changed |= (MODULE|PACKAGE|PRIVATE|PROTECTED); // [A3] [A4]
}
}
if (!accessible) {
// Different package and no access to c2; lose all access.
! changed |= (PUBLIC|MODULE|PACKAGE|PRIVATE|PROTECTED); // [A8]
}
if (!samePackage) {
// Different package; loose PACKAGE and lower access.
! changed |= (PACKAGE|PRIVATE|PROTECTED); // [A6]
}
if (!sameTopLevel) {
! // Different top-level class. Lose PRIVATE and PROTECTED access.
! changed |= (PRIVATE|PROTECTED); // [A5] [A7]
}
if (!sameClass) {
! changed |= (UNCONDITIONAL); // [A5]
} else {
assert(changed == 0); // [A10] (no deprivation if same class)
}
if (accessible) assert((changed & PUBLIC) == 0); // [A9]
int m2 = m1 & ~changed;
*** 226,240 ****
/** Predict the success or failure of accessing this method. */
public boolean willAccess(Method m) {
Class<?> c1 = lookupClass();
Class<?> c2 = m.getDeclaringClass();
! // if the lookup class is in a loose module with PUBLIC access then
! // public members of public types in all unnamed modules can be accessed
! if (isLooseModule(c1.getModule())
&& (lookupModes & PUBLIC) != 0
! && (!c2.getModule().isNamed())
&& Modifier.isPublic(c2.getModifiers())
&& Modifier.isPublic(m.getModifiers()))
return true;
LookupCase lc = this.in(c2);
--- 228,241 ----
/** Predict the success or failure of accessing this method. */
public boolean willAccess(Method m) {
Class<?> c1 = lookupClass();
Class<?> c2 = m.getDeclaringClass();
! // publicLookup has access to all public types/members of types in unnamed modules
! if ((lookupModes & UNCONDITIONAL) != 0
&& (lookupModes & PUBLIC) != 0
! && !c2.getModule().isNamed()
&& Modifier.isPublic(c2.getModifiers())
&& Modifier.isPublic(m.getModifiers()))
return true;
LookupCase lc = this.in(c2);
*** 261,279 ****
if (load && c2.getClassLoader() != null) {
if (c1.getClassLoader() == null) {
// not visible
return false;
}
- if (c1 == publicLookup().lookupClass()) {
- // not visible as lookup class is defined by child of the boot loader
- return false;
- }
}
! // if the lookup class is in a loose module with PUBLIC access then
! // public types in all unnamed modules can be accessed
! if (isLooseModule(c1.getModule())
&& (lookupModes & PUBLIC) != 0
&& (!c2.getModule().isNamed())
&& Modifier.isPublic(c2.getModifiers()))
return true;
--- 262,275 ----
if (load && c2.getClassLoader() != null) {
if (c1.getClassLoader() == null) {
// not visible
return false;
}
}
! // publicLookup has access to all public types/members of types in unnamed modules
! if ((lookupModes & UNCONDITIONAL) != 0
&& (lookupModes & PUBLIC) != 0
&& (!c2.getModule().isNamed())
&& Modifier.isPublic(c2.getModifiers()))
return true;
*** 293,307 ****
if (verbosity >= 2) {
System.out.println(this+" willAccessClass "+lc+" c1="+c1+" c2="+c2+" => "+r);
}
return r;
}
-
- private boolean isLooseModule(Module m) {
- ClassLoader cl = new ClassLoader() { };
- return m.canRead(cl.getUnnamedModule());
- }
}
private static Class<?> topLevelClass(Class<?> cls) {
Class<?> c = cls;
for (Class<?> ec; (ec = c.getEnclosingClass()) != null; )
--- 289,298 ----
*** 309,326 ****
assert(c.getEnclosingClass() == null);
assert(c == cls || cls.getEnclosingClass() != null);
return c;
}
- private static String packagePrefix(Class<?> c) {
- while (c.isArray()) c = c.getComponentType();
- String s = c.getName();
- assert(s.indexOf('/') < 0);
- return s.substring(0, s.lastIndexOf('.')+1);
- }
-
-
private final TreeSet<LookupCase> CASES = new TreeSet<>();
private final TreeMap<LookupCase,TreeSet<LookupCase>> CASE_EDGES = new TreeMap<>();
private final ArrayList<ClassLoader> LOADERS = new ArrayList<>();
private final ClassLoader THIS_LOADER = this.getClass().getClassLoader();
{ if (THIS_LOADER != null) LOADERS.add(THIS_LOADER); } // #1
--- 300,309 ----
< prev index next >