116 return true;
117 if ((allowedModes & PROTECTED) == 0)
118 return false;
119 // Protected members are accessible by subclasses, which does not include interfaces.
120 // Interfaces are types, not classes. They should not have access to
121 // protected members in j.l.Object, even though it is their superclass.
122 if ((mods & STATIC) != 0 &&
123 !isRelatedClass(refc, lookupClass))
124 return false;
125 if ((allowedModes & PROTECTED) != 0 &&
126 isSubClass(lookupClass, defc))
127 return true;
128 return false;
129 case PACKAGE_ONLY: // That is, zero. Unmarked member is package-only access.
130 assert !defc.isInterface(); // package-private members aren't allowed in interfaces
131 return ((allowedModes & PACKAGE_ALLOWED) != 0 &&
132 isSamePackage(defc, lookupClass));
133 case PRIVATE:
134 // Rules for privates follows access rules for nestmates.
135 return ((allowedModes & PRIVATE) != 0 &&
136 Reflection.areNestMates(defc, lookupClass));
137 default:
138 throw new IllegalArgumentException("bad modifiers: "+Modifier.toString(mods));
139 }
140 }
141
142 static boolean isRelatedClass(Class<?> refc, Class<?> lookupClass) {
143 return (refc == lookupClass ||
144 isSubClass(refc, lookupClass) ||
145 isSubClass(lookupClass, refc));
146 }
147
148 static boolean isSubClass(Class<?> lookupClass, Class<?> defc) {
149 return defc.isAssignableFrom(lookupClass) &&
150 !lookupClass.isInterface(); // interfaces are types, not classes.
151 }
152
153 static int getClassModifiers(Class<?> c) {
154 // This would return the mask stored by javac for the source-level modifiers.
155 // return c.getModifiers();
156 // But what we need for JVM access checks are the actual bits from the class header.
317 * @param class2 another class
318 * @return whether they are in the same module
319 */
320 public static boolean isSameModule(Class<?> class1, Class<?> class2) {
321 return class1.getModule() == class2.getModule();
322 }
323
324 /**
325 * Test if two classes have the same class loader and package qualifier.
326 * @param class1 a class
327 * @param class2 another class
328 * @return whether they are in the same package
329 */
330 public static boolean isSamePackage(Class<?> class1, Class<?> class2) {
331 assert(!class1.isArray() && !class2.isArray());
332 if (class1 == class2)
333 return true;
334 if (class1.getClassLoader() != class2.getClassLoader())
335 return false;
336 return Objects.equals(class1.getPackageName(), class2.getPackageName());
337 }
338
339 private static boolean loadersAreRelated(ClassLoader loader1, ClassLoader loader2,
340 boolean loader1MustBeParent) {
341 if (loader1 == loader2 || loader1 == null
342 || (loader2 == null && !loader1MustBeParent)) {
343 return true;
344 }
345 for (ClassLoader scan2 = loader2;
346 scan2 != null; scan2 = scan2.getParent()) {
347 if (scan2 == loader1) return true;
348 }
349 if (loader1MustBeParent) return false;
350 // see if loader2 is a parent of loader1:
351 for (ClassLoader scan1 = loader1;
352 scan1 != null; scan1 = scan1.getParent()) {
353 if (scan1 == loader2) return true;
354 }
355 return false;
356 }
|
116 return true;
117 if ((allowedModes & PROTECTED) == 0)
118 return false;
119 // Protected members are accessible by subclasses, which does not include interfaces.
120 // Interfaces are types, not classes. They should not have access to
121 // protected members in j.l.Object, even though it is their superclass.
122 if ((mods & STATIC) != 0 &&
123 !isRelatedClass(refc, lookupClass))
124 return false;
125 if ((allowedModes & PROTECTED) != 0 &&
126 isSubClass(lookupClass, defc))
127 return true;
128 return false;
129 case PACKAGE_ONLY: // That is, zero. Unmarked member is package-only access.
130 assert !defc.isInterface(); // package-private members aren't allowed in interfaces
131 return ((allowedModes & PACKAGE_ALLOWED) != 0 &&
132 isSamePackage(defc, lookupClass));
133 case PRIVATE:
134 // Rules for privates follows access rules for nestmates.
135 return ((allowedModes & PRIVATE) != 0 &&
136 areNestMates(defc, lookupClass));
137 default:
138 throw new IllegalArgumentException("bad modifiers: "+Modifier.toString(mods));
139 }
140 }
141
142 static boolean isRelatedClass(Class<?> refc, Class<?> lookupClass) {
143 return (refc == lookupClass ||
144 isSubClass(refc, lookupClass) ||
145 isSubClass(lookupClass, refc));
146 }
147
148 static boolean isSubClass(Class<?> lookupClass, Class<?> defc) {
149 return defc.isAssignableFrom(lookupClass) &&
150 !lookupClass.isInterface(); // interfaces are types, not classes.
151 }
152
153 static int getClassModifiers(Class<?> c) {
154 // This would return the mask stored by javac for the source-level modifiers.
155 // return c.getModifiers();
156 // But what we need for JVM access checks are the actual bits from the class header.
317 * @param class2 another class
318 * @return whether they are in the same module
319 */
320 public static boolean isSameModule(Class<?> class1, Class<?> class2) {
321 return class1.getModule() == class2.getModule();
322 }
323
324 /**
325 * Test if two classes have the same class loader and package qualifier.
326 * @param class1 a class
327 * @param class2 another class
328 * @return whether they are in the same package
329 */
330 public static boolean isSamePackage(Class<?> class1, Class<?> class2) {
331 assert(!class1.isArray() && !class2.isArray());
332 if (class1 == class2)
333 return true;
334 if (class1.getClassLoader() != class2.getClassLoader())
335 return false;
336 return Objects.equals(class1.getPackageName(), class2.getPackageName());
337 }
338
339 /**
340 * Test if two classes are defined as part of the same package member (top-level class).
341 * If this is true, they can share private access with each other.
342 * @param class1 a class
343 * @param class2 another class
344 * @return whether they are identical or nested together
345 */
346 public static boolean areNestMates(Class<?> class1, Class<?> class2) {
347 if (class1 == class2)
348 return true;
349 if (!isSamePackage(class1, class2))
350 return false;
351 if (Reflection.areNestMates(class1, class2))
352 return true;
353 // Could be pre-nestmate nested types
354 if (getOutermostEnclosingClass(class1) != getOutermostEnclosingClass(class2))
355 return false;
356 return true;
357 }
358
359 private static Class<?> getOutermostEnclosingClass(Class<?> c) {
360 Class<?> pkgmem = c;
361 for (Class<?> enc = c; (enc = enc.getEnclosingClass()) != null; )
362 pkgmem = enc;
363 return pkgmem;
364 }
365
366 private static boolean loadersAreRelated(ClassLoader loader1, ClassLoader loader2,
367 boolean loader1MustBeParent) {
368 if (loader1 == loader2 || loader1 == null
369 || (loader2 == null && !loader1MustBeParent)) {
370 return true;
371 }
372 for (ClassLoader scan2 = loader2;
373 scan2 != null; scan2 = scan2.getParent()) {
374 if (scan2 == loader1) return true;
375 }
376 if (loader1MustBeParent) return false;
377 // see if loader2 is a parent of loader1:
378 for (ClassLoader scan1 = loader1;
379 scan1 != null; scan1 = scan1.getParent()) {
380 if (scan1 == loader2) return true;
381 }
382 return false;
383 }
|