< prev index next >
src/java.base/share/classes/sun/invoke/util/VerifyAccess.java
Print this page
*** 86,116 ****
*
* @param refc the class used in the symbolic reference to the proposed member
* @param defc the class in which the proposed member is actually defined
* @param mods modifier flags for the proposed member
* @param lookupClass the class for which the access check is being made
* @return true iff the accessing class can access such a member
*/
public static boolean isMemberAccessible(Class<?> refc, // symbolic ref class
Class<?> defc, // actual def class
int mods, // actual member mods
Class<?> lookupClass,
int allowedModes) {
if (allowedModes == 0) return false;
! assert((allowedModes & PUBLIC) != 0 &&
! (allowedModes & ~(ALL_ACCESS_MODES|PACKAGE_ALLOWED|MODULE_ALLOWED|UNCONDITIONAL_ALLOWED)) == 0);
// The symbolic reference class (refc) must always be fully verified.
! if (!isClassAccessible(refc, lookupClass, allowedModes)) {
return false;
}
// Usually refc and defc are the same, but verify defc also in case they differ.
if (defc == lookupClass &&
(allowedModes & PRIVATE) != 0)
return true; // easy check; all self-access is OK with a private lookup
switch (mods & ALL_ACCESS_MODES) {
case PUBLIC:
return true; // already checked above
case PROTECTED:
assert !defc.isInterface(); // protected members aren't allowed in interfaces
if ((allowedModes & PROTECTED_OR_PACKAGE_ALLOWED) != 0 &&
isSamePackage(defc, lookupClass))
--- 86,119 ----
*
* @param refc the class used in the symbolic reference to the proposed member
* @param defc the class in which the proposed member is actually defined
* @param mods modifier flags for the proposed member
* @param lookupClass the class for which the access check is being made
+ * @param prevLookupClass the class for which the access check is being made
+ * @param allowedModes allowed modes
* @return true iff the accessing class can access such a member
*/
public static boolean isMemberAccessible(Class<?> refc, // symbolic ref class
Class<?> defc, // actual def class
int mods, // actual member mods
Class<?> lookupClass,
+ Class<?> prevLookupClass,
int allowedModes) {
if (allowedModes == 0) return false;
! assert((allowedModes & ~(ALL_ACCESS_MODES|PACKAGE_ALLOWED|MODULE_ALLOWED|UNCONDITIONAL_ALLOWED)) == 0);
// The symbolic reference class (refc) must always be fully verified.
! if (!isClassAccessible(refc, lookupClass, prevLookupClass, allowedModes)) {
return false;
}
// Usually refc and defc are the same, but verify defc also in case they differ.
if (defc == lookupClass &&
(allowedModes & PRIVATE) != 0)
return true; // easy check; all self-access is OK with a private lookup
switch (mods & ALL_ACCESS_MODES) {
case PUBLIC:
+ assert (allowedModes & PUBLIC) != 0 || (allowedModes & UNCONDITIONAL_ALLOWED) != 0;
return true; // already checked above
case PROTECTED:
assert !defc.isInterface(); // protected members aren't allowed in interfaces
if ((allowedModes & PROTECTED_OR_PACKAGE_ALLOWED) != 0 &&
isSamePackage(defc, lookupClass))
*** 173,190 ****
* <li>C is public and in the same module as D.
* <li>D is in a module that reads the module containing C, C is public and in a
* package that is exported to the module that contains D.
* <li>C and D are members of the same runtime package.
* </ul>
* @param refc the symbolic reference class to which access is being checked (C)
* @param lookupClass the class performing the lookup (D)
*/
! public static boolean isClassAccessible(Class<?> refc, Class<?> lookupClass,
int allowedModes) {
if (allowedModes == 0) return false;
! assert((allowedModes & PUBLIC) != 0 &&
! (allowedModes & ~(ALL_ACCESS_MODES|PACKAGE_ALLOWED|MODULE_ALLOWED|UNCONDITIONAL_ALLOWED)) == 0);
int mods = getClassModifiers(refc);
if (isPublic(mods)) {
Module lookupModule = lookupClass.getModule();
Module refModule = refc.getModule();
--- 176,202 ----
* <li>C is public and in the same module as D.
* <li>D is in a module that reads the module containing C, C is public and in a
* package that is exported to the module that contains D.
* <li>C and D are members of the same runtime package.
* </ul>
+ *
* @param refc the symbolic reference class to which access is being checked (C)
* @param lookupClass the class performing the lookup (D)
+ * @param prevLookupClass the class from which the lookup was teleported or null
+ * @param allowedModes allowed modes
*/
! public static boolean isClassAccessible(Class<?> refc,
! Class<?> lookupClass,
! Class<?> prevLookupClass,
int allowedModes) {
if (allowedModes == 0) return false;
! assert((allowedModes & ~(ALL_ACCESS_MODES|PACKAGE_ALLOWED|MODULE_ALLOWED|UNCONDITIONAL_ALLOWED)) == 0);
!
! if ((allowedModes & PACKAGE_ALLOWED) != 0 &&
! isSamePackage(lookupClass, refc))
! return true;
!
int mods = getClassModifiers(refc);
if (isPublic(mods)) {
Module lookupModule = lookupClass.getModule();
Module refModule = refc.getModule();
*** 193,233 ****
if (lookupModule == null) {
assert refModule == null;
return true;
}
! // trivially allow
! if ((allowedModes & MODULE_ALLOWED) != 0 &&
! (lookupModule == refModule))
! return true;
!
! // check readability when UNCONDITIONAL not allowed
! if (((allowedModes & UNCONDITIONAL_ALLOWED) != 0)
! || lookupModule.canRead(refModule)) {
!
! // check that refc is in an exported package
! if ((allowedModes & MODULE_ALLOWED) != 0) {
! if (refModule.isExported(refc.getPackageName(), lookupModule))
! return true;
! } else {
! // exported unconditionally
! if (refModule.isExported(refc.getPackageName()))
return true;
}
// not exported but allow access during VM initialization
// because java.base does not have its exports setup
if (!jdk.internal.misc.VM.isModuleSystemInited())
return true;
- }
// public class not accessible to lookupClass
return false;
}
! if ((allowedModes & PACKAGE_ALLOWED) != 0 &&
! isSamePackage(lookupClass, refc))
return true;
return false;
}
/**
* Decide if the given method type, attributed to a member or symbolic
--- 205,267 ----
if (lookupModule == null) {
assert refModule == null;
return true;
}
! // allow access to public types in all unconditionally exported packages
! if ((allowedModes & UNCONDITIONAL_ALLOWED) != 0) {
! return refModule.isExported(refc.getPackageName());
! }
!
! if (lookupModule == refModule && prevLookupClass == null) {
! // allow access to all public types in lookupModule
! if ((allowedModes & MODULE_ALLOWED) != 0)
return true;
+
+ assert (allowedModes & PUBLIC) != 0;
+ return refModule.isExported(refc.getPackageName());
}
+ // cross-module access
+ // 1. refc is in different module from lookupModule, or
+ // 2. refc is in lookupModule and a different module from prevLookupModule
+ Module prevLookupModule = prevLookupClass != null ? prevLookupClass.getModule()
+ : lookupModule;
+ assert refModule != lookupModule || refModule != prevLookupModule;
+ if (isModuleAccessible(refc, lookupModule, prevLookupModule))
+ return true;
+
// not exported but allow access during VM initialization
// because java.base does not have its exports setup
if (!jdk.internal.misc.VM.isModuleSystemInited())
return true;
// public class not accessible to lookupClass
return false;
}
!
! return false;
! }
!
! /*
! * A class or interface C in m is accessible to m1 and m2 if and only if
! * both m1 and m2 read m and m exports the package of C at least to
! * both m1 and m2.
! */
! public static boolean isModuleAccessible(Class<?> refc, Module m1, Module m2) {
! Module refModule = refc.getModule();
! assert refModule != m1 || refModule != m2;
! int mods = getClassModifiers(refc);
! if (isPublic(mods)) {
! if (m1.canRead(refModule) && m2.canRead(refModule)) {
! String pn = refc.getPackageName();
!
! // refc is exported package to at least both m1 and m2
! if (refModule.isExported(pn, m1) && refModule.isExported(pn, m2))
return true;
+ }
+ }
return false;
}
/**
* Decide if the given method type, attributed to a member or symbolic
< prev index next >