73 * </ul>
74 * This discussion of access control omits a related restriction
75 * on the target of a protected field access or method invocation
76 * (the target must be of class D or a subtype of D). That
77 * requirement is checked as part of the verification process
78 * (5.4.1); it is not part of link-time access control.
79 * @param refc the class used in the symbolic reference to the proposed member
80 * @param defc the class in which the proposed member is actually defined
81 * @param mods modifier flags for the proposed member
82 * @param lookupClass the class for which the access check is being made
83 * @return true iff the the accessing class can access such a member
84 */
85 public static boolean isMemberAccessible(Class<?> refc, // symbolic ref class
86 Class<?> defc, // actual def class
87 int mods, // actual member mods
88 Class<?> lookupClass,
89 int allowedModes) {
90 if (allowedModes == 0) return false;
91 assert((allowedModes & PUBLIC) != 0 &&
92 (allowedModes & ~(ALL_ACCESS_MODES|PACKAGE_ALLOWED)) == 0);
93 // Usually refc and defc are the same, but if they differ, verify them both.
94 if (refc != defc) {
95 if (!isClassAccessible(refc, lookupClass, allowedModes)) {
96 // Note that defc is verified in the switch below.
97 return false;
98 }
99 if ((mods & (ALL_ACCESS_MODES|STATIC)) == (PROTECTED|STATIC) &&
100 (allowedModes & PROTECTED_OR_PACKAGE_ALLOWED) != 0) {
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) ||
|
73 * </ul>
74 * This discussion of access control omits a related restriction
75 * on the target of a protected field access or method invocation
76 * (the target must be of class D or a subtype of D). That
77 * requirement is checked as part of the verification process
78 * (5.4.1); it is not part of link-time access control.
79 * @param refc the class used in the symbolic reference to the proposed member
80 * @param defc the class in which the proposed member is actually defined
81 * @param mods modifier flags for the proposed member
82 * @param lookupClass the class for which the access check is being made
83 * @return true iff the the accessing class can access such a member
84 */
85 public static boolean isMemberAccessible(Class<?> refc, // symbolic ref class
86 Class<?> defc, // actual def class
87 int mods, // actual member mods
88 Class<?> lookupClass,
89 int allowedModes) {
90 if (allowedModes == 0) return false;
91 assert((allowedModes & PUBLIC) != 0 &&
92 (allowedModes & ~(ALL_ACCESS_MODES|PACKAGE_ALLOWED)) == 0);
93 // The symbolic reference class (refc) must always be fully verified.
94 if (!isClassAccessible(refc, lookupClass, allowedModes)) {
95 return false;
96 }
97 // Usually refc and defc are the same, but verify defc also in case they differ.
98 if (defc == lookupClass &&
99 (allowedModes & PRIVATE) != 0)
100 return true; // easy check; all self-access is OK
101 switch (mods & ALL_ACCESS_MODES) {
102 case PUBLIC:
103 return true; // already checked above
104 case PROTECTED:
105 if ((allowedModes & PROTECTED_OR_PACKAGE_ALLOWED) != 0 &&
106 isSamePackage(defc, lookupClass))
107 return true;
108 if ((allowedModes & PROTECTED) == 0)
109 return false;
110 if ((mods & STATIC) != 0 &&
111 !isRelatedClass(refc, lookupClass))
112 return false;
113 if ((allowedModes & PROTECTED) != 0 &&
114 isSuperClass(defc, lookupClass))
115 return true;
116 return false;
117 case PACKAGE_ONLY: // That is, zero. Unmarked member is package-only access.
118 return ((allowedModes & PACKAGE_ALLOWED) != 0 &&
119 isSamePackage(defc, lookupClass));
120 case PRIVATE:
121 // Loosened rules for privates follows access rules for inner classes.
122 return (ALLOW_NESTMATE_ACCESS &&
123 (allowedModes & PRIVATE) != 0 &&
124 isSamePackageMember(defc, lookupClass));
125 default:
126 throw new IllegalArgumentException("bad modifiers: "+Modifier.toString(mods));
127 }
128 }
129
130 static boolean isRelatedClass(Class<?> refc, Class<?> lookupClass) {
131 return (refc == lookupClass ||
132 refc.isAssignableFrom(lookupClass) ||
|