101 // Apply the special rules for refc here. 102 if (!isRelatedClass(refc, lookupClass)) 103 return isSamePackage(defc, lookupClass); 104 // If refc == defc, the call to isPublicSuperClass will do 105 // the whole job, since in that case refc (as defc) will be 106 // a superclass of the lookup class. 107 } 108 } 109 if (defc == lookupClass && 110 (allowedModes & PRIVATE) != 0) 111 return true; // easy check; all self-access is OK 112 switch (mods & ALL_ACCESS_MODES) { 113 case PUBLIC: 114 if (refc != defc) return true; // already checked above 115 return isClassAccessible(refc, lookupClass, allowedModes); 116 case PROTECTED: 117 if ((allowedModes & PROTECTED_OR_PACKAGE_ALLOWED) != 0 && 118 isSamePackage(defc, lookupClass)) 119 return true; 120 if ((allowedModes & PROTECTED) != 0 && 121 isPublicSuperClass(defc, lookupClass)) 122 return true; 123 return false; 124 case PACKAGE_ONLY: // That is, zero. Unmarked member is package-only access. 125 return ((allowedModes & PACKAGE_ALLOWED) != 0 && 126 isSamePackage(defc, lookupClass)); 127 case PRIVATE: 128 // Loosened rules for privates follows access rules for inner classes. 129 return (ALLOW_NESTMATE_ACCESS && 130 (allowedModes & PRIVATE) != 0 && 131 isSamePackageMember(defc, lookupClass)); 132 default: 133 throw new IllegalArgumentException("bad modifiers: "+Modifier.toString(mods)); 134 } 135 } 136 137 static boolean isRelatedClass(Class<?> refc, Class<?> lookupClass) { 138 return (refc == lookupClass || 139 refc.isAssignableFrom(lookupClass) || 140 lookupClass.isAssignableFrom(refc)); 141 } 142 143 static boolean isPublicSuperClass(Class<?> defc, Class<?> lookupClass) { 144 return isPublic(getClassModifiers(defc)) && defc.isAssignableFrom(lookupClass); 145 } 146 147 static int getClassModifiers(Class<?> c) { 148 // This would return the mask stored by javac for the source-level modifiers. 149 // return c.getModifiers(); 150 // But what we need for JVM access checks are the actual bits from the class header. 151 // ...But arrays and primitives are synthesized with their own odd flags: 152 if (c.isArray() || c.isPrimitive()) 153 return c.getModifiers(); 154 return Reflection.getClassAccessFlags(c); 155 } 156 157 /** 158 * Evaluate the JVM linkage rules for access to the given class on behalf of caller. 159 * <h3>JVM Specification, 5.4.4 "Access Control"</h3> 160 * A class or interface C is accessible to a class or interface D 161 * if and only if either of the following conditions are true:<ul> 162 * <li>C is public. 163 * <li>C and D are members of the same runtime package. 164 * </ul> | 101 // Apply the special rules for refc here. 102 if (!isRelatedClass(refc, lookupClass)) 103 return isSamePackage(defc, lookupClass); 104 // If refc == defc, the call to isPublicSuperClass will do 105 // the whole job, since in that case refc (as defc) will be 106 // a superclass of the lookup class. 107 } 108 } 109 if (defc == lookupClass && 110 (allowedModes & PRIVATE) != 0) 111 return true; // easy check; all self-access is OK 112 switch (mods & ALL_ACCESS_MODES) { 113 case PUBLIC: 114 if (refc != defc) return true; // already checked above 115 return isClassAccessible(refc, lookupClass, allowedModes); 116 case PROTECTED: 117 if ((allowedModes & PROTECTED_OR_PACKAGE_ALLOWED) != 0 && 118 isSamePackage(defc, lookupClass)) 119 return true; 120 if ((allowedModes & PROTECTED) != 0 && 121 isSuperClass(defc, lookupClass)) 122 return true; 123 return false; 124 case PACKAGE_ONLY: // That is, zero. Unmarked member is package-only access. 125 return ((allowedModes & PACKAGE_ALLOWED) != 0 && 126 isSamePackage(defc, lookupClass)); 127 case PRIVATE: 128 // Loosened rules for privates follows access rules for inner classes. 129 return (ALLOW_NESTMATE_ACCESS && 130 (allowedModes & PRIVATE) != 0 && 131 isSamePackageMember(defc, lookupClass)); 132 default: 133 throw new IllegalArgumentException("bad modifiers: "+Modifier.toString(mods)); 134 } 135 } 136 137 static boolean isRelatedClass(Class<?> refc, Class<?> lookupClass) { 138 return (refc == lookupClass || 139 refc.isAssignableFrom(lookupClass) || 140 lookupClass.isAssignableFrom(refc)); 141 } 142 143 static boolean isSuperClass(Class<?> defc, Class<?> lookupClass) { 144 return defc.isAssignableFrom(lookupClass); 145 } 146 147 static int getClassModifiers(Class<?> c) { 148 // This would return the mask stored by javac for the source-level modifiers. 149 // return c.getModifiers(); 150 // But what we need for JVM access checks are the actual bits from the class header. 151 // ...But arrays and primitives are synthesized with their own odd flags: 152 if (c.isArray() || c.isPrimitive()) 153 return c.getModifiers(); 154 return Reflection.getClassAccessFlags(c); 155 } 156 157 /** 158 * Evaluate the JVM linkage rules for access to the given class on behalf of caller. 159 * <h3>JVM Specification, 5.4.4 "Access Control"</h3> 160 * A class or interface C is accessible to a class or interface D 161 * if and only if either of the following conditions are true:<ul> 162 * <li>C is public. 163 * <li>C and D are members of the same runtime package. 164 * </ul> |