< prev index next >

src/java.base/share/classes/sun/invoke/util/VerifyAccess.java

Print this page

        

@@ -131,11 +131,11 @@
             return ((allowedModes & PACKAGE_ALLOWED) != 0 &&
                     isSamePackage(defc, lookupClass));
         case PRIVATE:
             // Rules for privates follows access rules for nestmates.
             return ((allowedModes & PRIVATE) != 0 &&
-                    Reflection.areNestMates(defc, lookupClass));
+                    areNestMates(defc, lookupClass));
         default:
             throw new IllegalArgumentException("bad modifiers: "+Modifier.toString(mods));
         }
     }
 

@@ -334,10 +334,37 @@
         if (class1.getClassLoader() != class2.getClassLoader())
             return false;
         return Objects.equals(class1.getPackageName(), class2.getPackageName());
     }
 
+    /**
+     * Test if two classes are defined as part of the same package member (top-level class).
+     * If this is true, they can share private access with each other.
+     * @param class1 a class
+     * @param class2 another class
+     * @return whether they are identical or nested together
+     */
+    public static boolean areNestMates(Class<?> class1, Class<?> class2) {
+        if (class1 == class2)
+            return true;
+        if (!isSamePackage(class1, class2))
+            return false;
+        if (Reflection.areNestMates(class1, class2))
+            return true;
+        // Could be pre-nestmate nested types
+        if (getOutermostEnclosingClass(class1) != getOutermostEnclosingClass(class2))
+            return false;
+        return true;
+    }
+
+    private static Class<?> getOutermostEnclosingClass(Class<?> c) {
+        Class<?> pkgmem = c;
+        for (Class<?> enc = c; (enc = enc.getEnclosingClass()) != null; )
+            pkgmem = enc;
+        return pkgmem;
+    }
+
     private static boolean loadersAreRelated(ClassLoader loader1, ClassLoader loader2,
                                              boolean loader1MustBeParent) {
         if (loader1 == loader2 || loader1 == null
                 || (loader2 == null && !loader1MustBeParent)) {
             return true;
< prev index next >