Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/java/lang/Class/getDeclaredField/FieldSetAccessibleTest.java
41153 views
1
/*
2
* Copyright (c) 2014, 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.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
import java.io.FilePermission;
25
import java.io.IOException;
26
import java.io.UncheckedIOException;
27
import java.lang.module.ModuleFinder;
28
import java.lang.reflect.AccessibleObject;
29
import java.lang.reflect.Field;
30
import java.lang.reflect.Modifier;
31
import java.lang.reflect.InaccessibleObjectException;
32
import java.lang.reflect.ReflectPermission;
33
import java.net.URI;
34
import java.nio.file.FileSystem;
35
import java.nio.file.FileSystems;
36
import java.nio.file.Files;
37
import java.nio.file.Path;
38
import java.security.CodeSource;
39
import java.security.Permission;
40
import java.security.PermissionCollection;
41
import java.security.Permissions;
42
import java.security.Policy;
43
import java.security.ProtectionDomain;
44
import java.util.ArrayList;
45
import java.util.Arrays;
46
import java.util.Collections;
47
import java.util.Enumeration;
48
import java.util.Iterator;
49
import java.util.List;
50
import java.util.Set;
51
import java.util.PropertyPermission;
52
import java.util.concurrent.atomic.AtomicBoolean;
53
import java.util.concurrent.atomic.AtomicLong;
54
import java.util.stream.Collectors;
55
import java.util.stream.Stream;
56
57
import jdk.internal.module.Modules;
58
59
/**
60
* @test
61
* @bug 8065552
62
* @summary test that all public fields returned by getDeclaredFields() can
63
* be set accessible if the right permission is granted; this test
64
* loads all classes and get their declared fields
65
* and call setAccessible(false) followed by setAccessible(true);
66
* @modules java.base/jdk.internal.module
67
* @run main/othervm --add-modules=ALL-SYSTEM FieldSetAccessibleTest UNSECURE
68
* @run main/othervm --add-modules=ALL-SYSTEM -Djava.security.manager=allow FieldSetAccessibleTest SECURE
69
*
70
* @author danielfuchs
71
*/
72
public class FieldSetAccessibleTest {
73
74
static final List<String> cantread = new ArrayList<>();
75
static final List<String> failed = new ArrayList<>();
76
static final AtomicLong classCount = new AtomicLong();
77
static final AtomicLong fieldCount = new AtomicLong();
78
static long startIndex = 0;
79
static long maxSize = Long.MAX_VALUE;
80
static long maxIndex = Long.MAX_VALUE;
81
static final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
82
83
84
// Test that all fields for any given class can be made accessibles
85
static void testSetFieldsAccessible(Class<?> c) {
86
Module self = FieldSetAccessibleTest.class.getModule();
87
Module target = c.getModule();
88
String pn = c.getPackageName();
89
boolean exported = self.canRead(target) && target.isExported(pn, self);
90
for (Field f : c.getDeclaredFields()) {
91
fieldCount.incrementAndGet();
92
93
// setAccessible succeeds only if it's exported and the member
94
// is public and of a public class, or it's opened
95
// otherwise it would fail.
96
boolean isPublic = Modifier.isPublic(f.getModifiers()) &&
97
Modifier.isPublic(c.getModifiers());
98
boolean access = (exported && isPublic) || target.isOpen(pn, self);
99
try {
100
f.setAccessible(false);
101
f.setAccessible(true);
102
if (!access) {
103
throw new RuntimeException(
104
String.format("Expected InaccessibleObjectException is not thrown "
105
+ "for field %s in class %s%n", f.getName(), c.getName()));
106
}
107
} catch (InaccessibleObjectException expected) {
108
if (access) {
109
throw new RuntimeException(expected);
110
}
111
}
112
}
113
}
114
115
// Performs a series of test on the given class.
116
// At this time, we only call testSetFieldsAccessible(c)
117
public static boolean test(Class<?> c, boolean addExports) {
118
Module self = FieldSetAccessibleTest.class.getModule();
119
Module target = c.getModule();
120
String pn = c.getPackageName();
121
boolean exported = self.canRead(target) && target.isExported(pn, self);
122
if (addExports && !exported) {
123
Modules.addExports(target, pn, self);
124
exported = true;
125
}
126
127
classCount.incrementAndGet();
128
129
// Call getDeclaredFields() and try to set their accessible flag.
130
testSetFieldsAccessible(c);
131
132
// add more tests here...
133
134
return c == Class.class;
135
}
136
137
// Prints a summary at the end of the test.
138
static void printSummary(long secs, long millis, long nanos) {
139
System.out.println("Tested " + fieldCount.get() + " fields of "
140
+ classCount.get() + " classes in "
141
+ secs + "s " + millis + "ms " + nanos + "ns");
142
}
143
144
145
/**
146
* @param args the command line arguments:
147
*
148
* SECURE|UNSECURE [startIndex (default=0)] [maxSize (default=Long.MAX_VALUE)]
149
*
150
* @throws java.lang.Exception if the test fails
151
*/
152
public static void main(String[] args) throws Exception {
153
if (args == null || args.length == 0) {
154
args = new String[] {"SECURE", "0"};
155
} else if (args.length > 3) {
156
throw new RuntimeException("Expected at most one argument. Found "
157
+ Arrays.asList(args));
158
}
159
try {
160
if (args.length > 1) {
161
startIndex = Long.parseLong(args[1]);
162
if (startIndex < 0) {
163
throw new IllegalArgumentException("startIndex args[1]: "
164
+ startIndex);
165
}
166
}
167
if (args.length > 2) {
168
maxSize = Long.parseLong(args[2]);
169
if (maxSize <= 0) {
170
maxSize = Long.MAX_VALUE;
171
}
172
maxIndex = (Long.MAX_VALUE - startIndex) < maxSize
173
? Long.MAX_VALUE : startIndex + maxSize;
174
}
175
TestCase.valueOf(args[0]).run();
176
} catch (OutOfMemoryError oome) {
177
System.err.println(classCount.get());
178
throw oome;
179
}
180
}
181
182
public static void run(TestCase test) {
183
System.out.println("Testing " + test);
184
test(listAllClassNames());
185
System.out.println("Passed " + test);
186
}
187
188
static Iterable<String> listAllClassNames() {
189
return new ClassNameJrtStreamBuilder();
190
}
191
192
static void test(Iterable<String> iterable) {
193
final long start = System.nanoTime();
194
boolean classFound = false;
195
int index = 0;
196
for (String s : iterable) {
197
if (index == maxIndex) break;
198
try {
199
if (index < startIndex) continue;
200
if (test(s, false)) {
201
classFound = true;
202
}
203
} finally {
204
index++;
205
}
206
}
207
208
// Re-test with all packages exported
209
for (String s : iterable) {
210
test(s, true);
211
}
212
213
classCount.set(classCount.get() / 2);
214
fieldCount.set(fieldCount.get() / 2);
215
long elapsed = System.nanoTime() - start;
216
long secs = elapsed / 1000_000_000;
217
long millis = (elapsed % 1000_000_000) / 1000_000;
218
long nanos = elapsed % 1000_000;
219
System.out.println("Unreadable path elements: " + cantread);
220
System.out.println("Failed path elements: " + failed);
221
printSummary(secs, millis, nanos);
222
223
if (!failed.isEmpty()) {
224
throw new RuntimeException("Test failed for the following classes: " + failed);
225
}
226
if (!classFound && startIndex == 0 && index < maxIndex) {
227
// this is just to verify that we have indeed parsed rt.jar
228
// (or the java.base module)
229
throw new RuntimeException("Test failed: Class.class not found...");
230
}
231
if (classCount.get() == 0 && startIndex == 0) {
232
throw new RuntimeException("Test failed: no class found?");
233
}
234
}
235
236
static boolean test(String s, boolean addExports) {
237
String clsName = s.replace('/', '.').substring(0, s.length() - 6);
238
try {
239
System.out.println("Loading " + clsName);
240
final Class<?> c = Class.forName(
241
clsName,
242
false,
243
systemClassLoader);
244
return test(c, addExports);
245
} catch (VerifyError ve) {
246
System.err.println("VerifyError for " + clsName);
247
ve.printStackTrace(System.err);
248
failed.add(s);
249
} catch (Exception t) {
250
t.printStackTrace(System.err);
251
failed.add(s);
252
} catch (NoClassDefFoundError e) {
253
e.printStackTrace(System.err);
254
failed.add(s);
255
}
256
return false;
257
}
258
259
static class ClassNameJrtStreamBuilder implements Iterable<String>{
260
261
final FileSystem jrt;
262
final Path root;
263
final Set<String> modules;
264
ClassNameJrtStreamBuilder() {
265
jrt = FileSystems.getFileSystem(URI.create("jrt:/"));
266
root = jrt.getPath("/modules");
267
modules = systemModules();
268
}
269
270
@Override
271
public Iterator<String> iterator() {
272
try {
273
return Files.walk(root)
274
.filter(p -> p.getNameCount() > 2)
275
.filter(p -> modules.contains(p.getName(1).toString()))
276
.map(p -> p.subpath(2, p.getNameCount()))
277
.map(p -> p.toString())
278
.filter(s -> s.endsWith(".class") && !s.endsWith("module-info.class"))
279
.iterator();
280
} catch(IOException x) {
281
throw new UncheckedIOException("Unable to walk \"/modules\"", x);
282
}
283
}
284
285
/*
286
* Filter deployment modules
287
*/
288
static Set<String> systemModules() {
289
Set<String> mods = Set.of("javafx.deploy", "jdk.deploy", "jdk.plugin", "jdk.javaws",
290
// All JVMCI packages other than jdk.vm.ci.services are dynamically
291
// exported to jdk.internal.vm.compiler
292
"jdk.internal.vm.compiler"
293
);
294
return ModuleFinder.ofSystem().findAll().stream()
295
.map(mref -> mref.descriptor().name())
296
.filter(mn -> !mods.contains(mn))
297
.collect(Collectors.toSet());
298
}
299
}
300
301
// Test with or without a security manager
302
public static enum TestCase {
303
UNSECURE, SECURE;
304
public void run() throws Exception {
305
System.out.println("Running test case: " + name());
306
Configure.setUp(this);
307
FieldSetAccessibleTest.run(this);
308
}
309
}
310
311
// A helper class to configure the security manager for the test,
312
// and bypass it when needed.
313
static class Configure {
314
static Policy policy = null;
315
static final ThreadLocal<AtomicBoolean> allowAll = new ThreadLocal<AtomicBoolean>() {
316
@Override
317
protected AtomicBoolean initialValue() {
318
return new AtomicBoolean(false);
319
}
320
};
321
static void setUp(TestCase test) {
322
switch (test) {
323
case SECURE:
324
if (policy == null && System.getSecurityManager() != null) {
325
throw new IllegalStateException("SecurityManager already set");
326
} else if (policy == null) {
327
policy = new SimplePolicy(TestCase.SECURE, allowAll);
328
Policy.setPolicy(policy);
329
System.setSecurityManager(new SecurityManager());
330
}
331
if (System.getSecurityManager() == null) {
332
throw new IllegalStateException("No SecurityManager.");
333
}
334
if (policy == null) {
335
throw new IllegalStateException("policy not configured");
336
}
337
break;
338
case UNSECURE:
339
if (System.getSecurityManager() != null) {
340
throw new IllegalStateException("SecurityManager already set");
341
}
342
break;
343
default:
344
throw new InternalError("No such testcase: " + test);
345
}
346
}
347
static void doPrivileged(Runnable run) {
348
allowAll.get().set(true);
349
try {
350
run.run();
351
} finally {
352
allowAll.get().set(false);
353
}
354
}
355
}
356
357
// A Helper class to build a set of permissions.
358
static final class PermissionsBuilder {
359
final Permissions perms;
360
public PermissionsBuilder() {
361
this(new Permissions());
362
}
363
public PermissionsBuilder(Permissions perms) {
364
this.perms = perms;
365
}
366
public PermissionsBuilder add(Permission p) {
367
perms.add(p);
368
return this;
369
}
370
public PermissionsBuilder addAll(PermissionCollection col) {
371
if (col != null) {
372
for (Enumeration<Permission> e = col.elements(); e.hasMoreElements(); ) {
373
perms.add(e.nextElement());
374
}
375
}
376
return this;
377
}
378
public Permissions toPermissions() {
379
final PermissionsBuilder builder = new PermissionsBuilder();
380
builder.addAll(perms);
381
return builder.perms;
382
}
383
}
384
385
// Policy for the test...
386
public static class SimplePolicy extends Policy {
387
388
static final Policy DEFAULT_POLICY = Policy.getPolicy();
389
390
final Permissions permissions;
391
final Permissions allPermissions;
392
final ThreadLocal<AtomicBoolean> allowAll;
393
public SimplePolicy(TestCase test, ThreadLocal<AtomicBoolean> allowAll) {
394
this.allowAll = allowAll;
395
396
// Permission needed by the tested code exercised in the test
397
permissions = new Permissions();
398
permissions.add(new RuntimePermission("fileSystemProvider"));
399
permissions.add(new RuntimePermission("createClassLoader"));
400
permissions.add(new RuntimePermission("closeClassLoader"));
401
permissions.add(new RuntimePermission("getClassLoader"));
402
permissions.add(new RuntimePermission("accessDeclaredMembers"));
403
permissions.add(new RuntimePermission("accessSystemModules"));
404
permissions.add(new ReflectPermission("suppressAccessChecks"));
405
permissions.add(new PropertyPermission("*", "read"));
406
permissions.add(new FilePermission("<<ALL FILES>>", "read"));
407
408
// these are used for configuring the test itself...
409
allPermissions = new Permissions();
410
allPermissions.add(new java.security.AllPermission());
411
}
412
413
@Override
414
public boolean implies(ProtectionDomain domain, Permission permission) {
415
if (allowAll.get().get()) return allPermissions.implies(permission);
416
if (permissions.implies(permission)) return true;
417
if (permission instanceof java.lang.RuntimePermission) {
418
if (permission.getName().startsWith("accessClassInPackage.")) {
419
// add these along to the set of permission we have, when we
420
// discover that we need them.
421
permissions.add(permission);
422
return true;
423
}
424
}
425
if (DEFAULT_POLICY.implies(domain, permission)) return true;
426
return false;
427
}
428
429
@Override
430
public PermissionCollection getPermissions(CodeSource codesource) {
431
return new PermissionsBuilder().addAll(allowAll.get().get()
432
? allPermissions : permissions).toPermissions();
433
}
434
435
@Override
436
public PermissionCollection getPermissions(ProtectionDomain domain) {
437
return new PermissionsBuilder().addAll(allowAll.get().get()
438
? allPermissions : permissions).toPermissions();
439
}
440
}
441
442
}
443
444