Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/sun/reflect/misc/ReflectUtil.java
41159 views
1
/*
2
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
27
package sun.reflect.misc;
28
29
import java.lang.reflect.Member;
30
import java.lang.reflect.Method;
31
import java.lang.reflect.Modifier;
32
import java.lang.reflect.Proxy;
33
import jdk.internal.reflect.Reflection;
34
import sun.security.util.SecurityConstants;
35
36
public final class ReflectUtil {
37
38
private ReflectUtil() {
39
}
40
41
public static Class<?> forName(String name)
42
throws ClassNotFoundException {
43
checkPackageAccess(name);
44
return Class.forName(name);
45
}
46
47
/**
48
* Ensures that access to a method or field is granted and throws
49
* IllegalAccessException if not. This method is not suitable for checking
50
* access to constructors.
51
*
52
* @param currentClass the class performing the access
53
* @param memberClass the declaring class of the member being accessed
54
* @param target the target object if accessing instance field or method;
55
* or null if accessing static field or method or if target
56
* object access rights will be checked later
57
* @param modifiers the member's access modifiers
58
* @throws IllegalAccessException if access to member is denied
59
* @implNote Delegates directly to
60
* {@link Reflection#ensureMemberAccess(Class, Class, Class, int)}
61
* which should be used instead.
62
*/
63
public static void ensureMemberAccess(Class<?> currentClass,
64
Class<?> memberClass,
65
Object target,
66
int modifiers)
67
throws IllegalAccessException
68
{
69
Reflection.ensureMemberAccess(currentClass,
70
memberClass,
71
target == null ? null : target.getClass(),
72
modifiers);
73
}
74
75
/**
76
* Does a conservative approximation of member access check. Use this if
77
* you don't have an actual 'userland' caller Class/ClassLoader available.
78
* This might be more restrictive than a precise member access check where
79
* you have a caller, but should never allow a member access that is
80
* forbidden.
81
*
82
* @param m the {@code Member} about to be accessed
83
*/
84
public static void conservativeCheckMemberAccess(Member m) throws SecurityException{
85
@SuppressWarnings("removal")
86
final SecurityManager sm = System.getSecurityManager();
87
if (sm == null)
88
return;
89
90
// Check for package access on the declaring class.
91
//
92
// In addition, unless the member and the declaring class are both
93
// public check for access declared member permissions.
94
//
95
// This is done regardless of ClassLoader relations between the {@code
96
// Member m} and any potential caller.
97
98
final Class<?> declaringClass = m.getDeclaringClass();
99
100
privateCheckPackageAccess(sm, declaringClass);
101
102
if (Modifier.isPublic(m.getModifiers()) &&
103
Modifier.isPublic(declaringClass.getModifiers()))
104
return;
105
106
// Check for declared member access.
107
sm.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
108
}
109
110
/**
111
* Checks package access on the given class.
112
*
113
* If it is a {@link Proxy#isProxyClass(java.lang.Class)} that implements
114
* a non-public interface (i.e. may be in a non-restricted package),
115
* also check the package access on the proxy interfaces.
116
*/
117
public static void checkPackageAccess(Class<?> clazz) {
118
@SuppressWarnings("removal")
119
SecurityManager s = System.getSecurityManager();
120
if (s != null) {
121
privateCheckPackageAccess(s, clazz);
122
}
123
}
124
125
/**
126
* NOTE: should only be called if a SecurityManager is installed
127
*/
128
private static void privateCheckPackageAccess(@SuppressWarnings("removal") SecurityManager s, Class<?> clazz) {
129
String pkg = clazz.getPackageName();
130
if (!pkg.isEmpty()) {
131
s.checkPackageAccess(pkg);
132
}
133
134
if (isNonPublicProxyClass(clazz)) {
135
privateCheckProxyPackageAccess(s, clazz);
136
}
137
}
138
139
/**
140
* Checks package access on the given classname.
141
* This method is typically called when the Class instance is not
142
* available and the caller attempts to load a class on behalf
143
* the true caller (application).
144
*/
145
public static void checkPackageAccess(String name) {
146
@SuppressWarnings("removal")
147
SecurityManager s = System.getSecurityManager();
148
if (s != null) {
149
String cname = name.replace('/', '.');
150
if (cname.startsWith("[")) {
151
int b = cname.lastIndexOf('[') + 2;
152
if (b > 1 && b < cname.length()) {
153
cname = cname.substring(b);
154
}
155
}
156
int i = cname.lastIndexOf('.');
157
if (i != -1) {
158
s.checkPackageAccess(cname.substring(0, i));
159
}
160
}
161
}
162
163
public static boolean isPackageAccessible(Class<?> clazz) {
164
try {
165
checkPackageAccess(clazz);
166
} catch (SecurityException e) {
167
return false;
168
}
169
return true;
170
}
171
172
// Returns true if p is an ancestor of cl i.e. class loader 'p' can
173
// be found in the cl's delegation chain
174
private static boolean isAncestor(ClassLoader p, ClassLoader cl) {
175
ClassLoader acl = cl;
176
do {
177
acl = acl.getParent();
178
if (p == acl) {
179
return true;
180
}
181
} while (acl != null);
182
return false;
183
}
184
185
/**
186
* Returns true if package access check is needed for reflective
187
* access from a class loader 'from' to classes or members in
188
* a class defined by class loader 'to'. This method returns true
189
* if 'from' is not the same as or an ancestor of 'to'. All code
190
* in a system domain are granted with all permission and so this
191
* method returns false if 'from' class loader is a class loader
192
* loading system classes. On the other hand, if a class loader
193
* attempts to access system domain classes, it requires package
194
* access check and this method will return true.
195
*/
196
public static boolean needsPackageAccessCheck(ClassLoader from, ClassLoader to) {
197
if (from == null || from == to)
198
return false;
199
200
if (to == null)
201
return true;
202
203
return !isAncestor(from, to);
204
}
205
206
/**
207
* Check package access on the proxy interfaces that the given proxy class
208
* implements.
209
*
210
* @param clazz Proxy class object
211
*/
212
public static void checkProxyPackageAccess(Class<?> clazz) {
213
@SuppressWarnings("removal")
214
SecurityManager s = System.getSecurityManager();
215
if (s != null) {
216
privateCheckProxyPackageAccess(s, clazz);
217
}
218
}
219
220
/**
221
* NOTE: should only be called if a SecurityManager is installed
222
*/
223
private static void privateCheckProxyPackageAccess(@SuppressWarnings("removal") SecurityManager s, Class<?> clazz) {
224
// check proxy interfaces if the given class is a proxy class
225
if (Proxy.isProxyClass(clazz)) {
226
for (Class<?> intf : clazz.getInterfaces()) {
227
privateCheckPackageAccess(s, intf);
228
}
229
}
230
}
231
/**
232
* Access check on the interfaces that a proxy class implements and throw
233
* {@code SecurityException} if it accesses a restricted package from
234
* the caller's class loader.
235
*
236
* @param ccl the caller's class loader
237
* @param interfaces the list of interfaces that a proxy class implements
238
*/
239
public static void checkProxyPackageAccess(ClassLoader ccl,
240
Class<?>... interfaces)
241
{
242
@SuppressWarnings("removal")
243
SecurityManager sm = System.getSecurityManager();
244
if (sm != null) {
245
for (Class<?> intf : interfaces) {
246
ClassLoader cl = intf.getClassLoader();
247
if (needsPackageAccessCheck(ccl, cl)) {
248
privateCheckPackageAccess(sm, intf);
249
}
250
}
251
}
252
}
253
254
// Note that bytecode instrumentation tools may exclude 'sun.*'
255
// classes but not generated proxy classes and so keep it in com.sun.*
256
public static final String PROXY_PACKAGE = "com.sun.proxy";
257
258
/**
259
* Test if the given class is a proxy class that implements
260
* non-public interface. Such proxy class may be in a non-restricted
261
* package that bypasses checkPackageAccess.
262
*/
263
public static boolean isNonPublicProxyClass(Class<?> cls) {
264
if (!Proxy.isProxyClass(cls)) {
265
return false;
266
}
267
return !Modifier.isPublic(cls.getModifiers());
268
}
269
270
/**
271
* Check if the given method is a method declared in the proxy interface
272
* implemented by the given proxy instance.
273
*
274
* @param proxy a proxy instance
275
* @param method an interface method dispatched to a InvocationHandler
276
*
277
* @throws IllegalArgumentException if the given proxy or method is invalid.
278
*/
279
public static void checkProxyMethod(Object proxy, Method method) {
280
// check if it is a valid proxy instance
281
if (proxy == null || !Proxy.isProxyClass(proxy.getClass())) {
282
throw new IllegalArgumentException("Not a Proxy instance");
283
}
284
if (Modifier.isStatic(method.getModifiers())) {
285
throw new IllegalArgumentException("Can't handle static method");
286
}
287
288
Class<?> c = method.getDeclaringClass();
289
if (c == Object.class) {
290
String name = method.getName();
291
if (name.equals("hashCode") || name.equals("equals") || name.equals("toString")) {
292
return;
293
}
294
}
295
296
if (isSuperInterface(proxy.getClass(), c)) {
297
return;
298
}
299
300
// disallow any method not declared in one of the proxy interfaces
301
throw new IllegalArgumentException("Can't handle: " + method);
302
}
303
304
private static boolean isSuperInterface(Class<?> c, Class<?> intf) {
305
for (Class<?> i : c.getInterfaces()) {
306
if (i == intf) {
307
return true;
308
}
309
if (isSuperInterface(i, intf)) {
310
return true;
311
}
312
}
313
return false;
314
}
315
316
}
317
318