< 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 >