Skip to content

Commit cc03734

Browse files
author
Mandy Chung
committed
8266925: Add a test to verify that hidden class's members are not statically invocable
Reviewed-by: alanb
1 parent 271a0c7 commit cc03734

File tree

2 files changed

+165
-0
lines changed

2 files changed

+165
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/*
2+
* Copyright (c) 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+
/*
25+
* @test
26+
* @bug 8266925
27+
* @summary hidden class members can't be statically invocable
28+
* @modules java.base/jdk.internal.misc java.base/jdk.internal.org.objectweb.asm
29+
* @build java.base/*
30+
* @run testng StaticInvocableTest
31+
*/
32+
33+
import java.lang.invoke.MethodHandle;
34+
import java.lang.invoke.MethodHandles.Lookup;
35+
import java.lang.invoke.MethodType;
36+
import java.lang.invoke.LookupHelper;
37+
import jdk.internal.org.objectweb.asm.*;
38+
import org.testng.annotations.Test;
39+
40+
import static jdk.internal.org.objectweb.asm.Opcodes.*;
41+
42+
public class StaticInvocableTest {
43+
public static void main(String[] args) throws Throwable {
44+
StaticInvocableTest test = new StaticInvocableTest();
45+
test.testJavaLang();
46+
test.testJavaUtil();
47+
test.testJdkInternalMisc();
48+
test.testJavaLangInvoke();
49+
test.testProhibitedJavaPkg();
50+
System.out.println("TEST PASSED");
51+
}
52+
53+
// Test hidden classes from different packages
54+
// (see j.l.i.InvokerBytecodeGenerator::isStaticallyInvocable).
55+
@Test public void testJavaLang() throws Throwable { test("java/lang"); }
56+
@Test public void testJavaUtil() throws Throwable { test("java/util"); }
57+
@Test public void testJdkInternalMisc() throws Throwable { test("jdk/internal/misc"); }
58+
@Test public void testJavaLangInvoke() throws Throwable { test("java/lang/invoke"); }
59+
@Test public void testProhibitedJavaPkg() throws Throwable {
60+
try {
61+
test("java/prohibited");
62+
} catch (IllegalArgumentException e) {
63+
return;
64+
}
65+
throw new RuntimeException("Expected SecurityException");
66+
}
67+
68+
private static void test(String pkg) throws Throwable {
69+
byte[] bytes = dumpClass(pkg);
70+
Lookup lookup;
71+
if (pkg.equals("java/prohibited")) {
72+
StaticInvocableTest sampleclass = new StaticInvocableTest();
73+
lookup = LookupHelper.newLookup(sampleclass.getClass());
74+
} else if (pkg.equals("java/lang")) {
75+
lookup = LookupHelper.newLookup(Object.class);
76+
} else if (pkg.equals("java/util")) {
77+
lookup = LookupHelper.newLookup(java.util.ArrayList.class);
78+
} else if (pkg.equals("jdk/internal/misc")) {
79+
lookup = LookupHelper.newLookup(jdk.internal.misc.Signal.class);
80+
} else if (pkg.equals("java/lang/invoke")) {
81+
lookup = LookupHelper.newLookup(java.lang.invoke.CallSite.class);
82+
} else {
83+
throw new RuntimeException("Unexpected pkg: " + pkg);
84+
}
85+
86+
// Define hidden class
87+
Lookup l = lookup.defineHiddenClass(bytes, true);
88+
89+
MethodType t = MethodType.methodType(Object.class, int.class);
90+
MethodHandle target = l.findStatic(l.lookupClass(), "get", t);
91+
92+
// Wrap target into LF (convert) to get "target" referenced from LF
93+
MethodHandle wrappedMH = target.asType(MethodType.methodType(Object.class, Integer.class));
94+
95+
// Invoke enough times to provoke LF compilation to bytecode.
96+
for (int i = 0; i<100; i++) {
97+
Object r = wrappedMH.invokeExact((Integer)1);
98+
}
99+
}
100+
101+
/*
102+
* Constructs bytecode for the following class:
103+
* public class pkg.MyClass {
104+
* MyClass() {}
105+
* public Object get(int i) { return null; }
106+
* }
107+
*/
108+
public static byte[] dumpClass(String pkg) {
109+
ClassWriter cw = new ClassWriter(0);
110+
MethodVisitor mv;
111+
112+
cw.visit(52, ACC_SUPER | ACC_PUBLIC, pkg+"/MyClass", null, "java/lang/Object", null);
113+
{
114+
mv = cw.visitMethod(0, "<init>", "()V", null, null);
115+
mv.visitCode();
116+
mv.visitVarInsn(ALOAD, 0);
117+
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
118+
mv.visitInsn(RETURN);
119+
mv.visitMaxs(1, 1);
120+
mv.visitEnd();
121+
}
122+
{
123+
mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "get", "(I)Ljava/lang/Object;", null, null);
124+
mv.visitCode();
125+
mv.visitInsn(ACONST_NULL);
126+
mv.visitInsn(ARETURN);
127+
mv.visitMaxs(1, 1);
128+
mv.visitEnd();
129+
}
130+
cw.visitEnd();
131+
return cw.toByteArray();
132+
}
133+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright (c) 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+
package java.lang.invoke;
25+
26+
import java.lang.invoke.MethodHandles.Lookup;
27+
28+
public class LookupHelper {
29+
public static Lookup newLookup(Class<?> c) {
30+
return new Lookup(c);
31+
}
32+
}

0 commit comments

Comments
 (0)