xref: /aosp_15_r20/external/javassist/src/test/javassist/JvstTest5.java (revision f1fbf3c2ab775ce834e0af96b7a85bdc7a0eac65)
1 package javassist;
2 
3 import java.lang.annotation.Annotation;
4 import java.lang.reflect.TypeVariable;
5 
6 import javassist.bytecode.AccessFlag;
7 import javassist.bytecode.AnnotationsAttribute;
8 import javassist.bytecode.AttributeInfo;
9 import javassist.bytecode.ClassFile;
10 import javassist.bytecode.ConstPool;
11 import javassist.bytecode.InnerClassesAttribute;
12 import javassist.bytecode.NestHostAttribute;
13 import javassist.bytecode.NestMembersAttribute;
14 import javassist.expr.ExprEditor;
15 import javassist.expr.Handler;
16 import javassist.expr.MethodCall;
17 
18 @SuppressWarnings({"rawtypes","unchecked","unused"})
19 public class JvstTest5 extends JvstTestRoot {
JvstTest5(String name)20     public JvstTest5(String name) {
21         super(name);
22     }
23 
testDollarClassInStaticMethod()24     public void testDollarClassInStaticMethod() throws Exception {
25         CtClass cc = sloader.makeClass("test5.DollarClass");
26         CtMethod m = CtNewMethod.make("public static int run(){ return $class.getName().length(); }", cc);
27         cc.addMethod(m);
28         m = CtNewMethod.make("public int run2(){ return $class.getName().length(); }", cc);
29         cc.addMethod(m);
30         cc.writeFile();
31         Object obj = make(cc.getName());
32         assertEquals(cc.getName().length(), invoke(obj, "run"));
33         assertEquals(cc.getName().length(), invoke(obj, "run2"));
34     }
35 
testSuperDefaultMethodCall()36     public void testSuperDefaultMethodCall() throws Exception {
37         CtClass cc = sloader.get("test5.DefaultMethod");
38         CtMethod m = CtNewMethod.make("public int run(){ return test5.DefaultMethodIntf.super.foo(); }", cc);
39         cc.addMethod(m);
40         m = CtNewMethod.make("public int run2(){ return test5.DefaultMethodIntf.baz(); }", cc);
41         cc.addMethod(m);
42         m = CtNewMethod.make("public int run3(){ return test5.DefaultMethodIntf.super.baz(); }", cc);
43         cc.addMethod(m);
44         cc.writeFile();
45         Object obj = make(cc.getName());
46         assertEquals(1, invoke(obj, "run"));
47         assertEquals(10, invoke(obj, "run2"));
48         assertEquals(10, invoke(obj, "run3"));
49     }
50 
testTypeAnno()51     public void testTypeAnno() throws Exception {
52         CtClass cc = sloader.get("test5.TypeAnno");
53         cc.getClassFile().compact();
54         cc.writeFile();
55         Object obj = make(cc.getName());
56         TypeVariable<?> t = obj.getClass().getTypeParameters()[0];
57         Annotation[] annos = t.getAnnotations();
58         assertEquals("@test5.TypeAnnoA()", annos[0].toString());
59     }
60 
testJIRA241()61     public void testJIRA241() throws Exception {
62         CtClass cc = sloader.get("test5.JIRA241");
63         CtMethod testMethod = cc.getDeclaredMethod("test");
64         testMethod.insertAfter("System.out.println(\"inserted!\");");
65         cc.writeFile();
66         Object obj = make(cc.getName());
67         assertEquals(10, invoke(obj, "run"));
68     }
69 
testJIRA246()70     public void testJIRA246() throws Exception {
71         CtClass ctClass = sloader.makeClass("test5.JIRA246Test");
72         ctClass.addInterface(sloader.get(test5.JIRA246.Test.class.getName()));
73         String methodBody = "public void test() { defaultMethod(); }";
74         CtMethod ctMethod = CtMethod.make(methodBody, ctClass);
75         ctClass.addMethod(ctMethod);
76     }
77 
testJIRA246b()78     public void testJIRA246b() throws Exception {
79         CtClass ctClass = sloader.get(test5.JIRA246.A.class.getName());
80         String src = "public void id() { get(); }";
81         CtMethod make = CtNewMethod.make(src, ctClass);
82     }
83 
testJIRA242()84     public void testJIRA242() throws Exception {
85         Boolean ss = Boolean.valueOf(2 > 3);
86         ClassPool cp = ClassPool.getDefault();
87         CtClass cc = cp.get("test5.JIRA242$Hello");
88         CtMethod m = cc.getDeclaredMethod("say");
89         m.insertBefore("{ System.out.println(\"Say Hello...\"); }");
90 
91         StringBuilder sb = new StringBuilder();
92         sb.append("BOOL_SERIES = createBooleanSeriesStep();");
93         //Below code cause the issue
94         sb.append("BOOL_SERIES.setValue(3>=3);"); //lets comment this and run it will work
95         // Below code snippets will work
96         // this cast into exact class and call the same function
97         sb.append("((test5.JIRA242$BooleanDataSeries)BOOL_SERIES).setValue(3>=3);");
98         // this code snippet will set exact boolean variable to the function.
99         sb.append("boolean var = 3>=3;");
100         sb.append("BOOL_SERIES.setValue(var);");
101 
102         m.insertBefore(sb.toString());
103         cc.writeFile();
104         Object obj = make(cc.getName());
105         assertEquals(0, invoke(obj, "say"));
106     }
107 
testJIRA249()108     public void testJIRA249() throws Exception {
109         CtClass cc = sloader.get("test5.BoolTest");
110         CtMethod testMethod = cc.getDeclaredMethod("test");
111         testMethod.insertBefore("i = foo(true & true);");
112         cc.writeFile();
113         Object obj = make(cc.getName());
114         assertEquals(1, invoke(obj, "run"));
115     }
116 
testInnerClassAttributeRemove()117     public void testInnerClassAttributeRemove() throws Exception {
118         CtClass cc = sloader.get("test5.InnerClassRemove");
119         ClassFile cf = cc.getClassFile();
120         InnerClassesAttribute ica = (InnerClassesAttribute)cf.getAttribute(InnerClassesAttribute.tag);
121         String second = ica.innerClass(1);
122         String secondName = ica.innerName(1);
123         String third = ica.innerClass(2);
124         String thirdName = ica.innerName(2);
125         assertEquals(3, ica.remove(3));
126         assertEquals(2, ica.remove(0));
127         assertEquals(second, ica.innerClass(0));
128         assertEquals(secondName, ica.innerName(0));
129         assertEquals(third, ica.innerClass(1));
130         assertEquals(thirdName, ica.innerName(1));
131         assertEquals(1, ica.remove(1));
132         assertEquals(second, ica.innerClass(0));
133         assertEquals(secondName, ica.innerName(0));
134         cc.writeFile();
135         Object obj = make(cc.getName());
136         assertEquals(1, invoke(obj, "run"));
137     }
138 
testJIRA248()139     public void testJIRA248() throws Exception {
140         CtClass cc = sloader.get("test5.JIRA248");
141         String methodBody = "public int run() { return foo() + super.foo() + super.bar() + test5.JIRA248Intf2.super.baz(); }";
142         CtMethod ctMethod = CtMethod.make(methodBody, cc);
143         cc.addMethod(ctMethod);
144         cc.writeFile();
145         Object obj = make(cc.getName());
146         assertEquals(40271, invoke(obj, "run"));
147     }
148 
testInvalidCastWithDollar()149     public void testInvalidCastWithDollar() throws Exception {
150         String code = "{ new test5.JavassistInvalidCastTest().inspectReturn((Object) ($w) $_); } ";
151         CtClass c = sloader.get("test5.InvalidCastDollar");
152         for (CtMethod method : c.getDeclaredMethods())
153             method.insertAfter(code);
154     }
155 
testJIRA256()156     public void testJIRA256() throws Exception {
157         // CtClass ec = sloader.get("test5.Entity");
158 
159         CtClass cc = sloader.makeClass("test5.JIRA256");
160         ClassFile ccFile = cc.getClassFile();
161         ConstPool constpool = ccFile.getConstPool();
162 
163         AnnotationsAttribute attr = new AnnotationsAttribute(constpool, AnnotationsAttribute.visibleTag);
164         javassist.bytecode.annotation.Annotation entityAnno
165             = new javassist.bytecode.annotation.Annotation("test5.Entity", constpool);
166             // = new javassist.bytecode.annotation.Annotation(constpool, ec);
167 
168         entityAnno.addMemberValue("value", new javassist.bytecode.annotation.ArrayMemberValue(constpool));
169         attr.addAnnotation(entityAnno);
170         ccFile.addAttribute(attr);
171 
172         cc.writeFile();
173         Object o = make(cc.getName());
174         assertTrue(o.getClass().getName().equals("test5.JIRA256"));
175 
176         java.lang.annotation.Annotation[] annotations = o.getClass().getDeclaredAnnotations();
177         assertEquals(1, annotations.length);
178     }
179 
testJIRA250()180     public void testJIRA250() throws Exception {
181         CtClass cc = sloader.makeClass("test5.JIRA250", sloader.get("test5.JIRA250Super"));
182         cc.addMethod(CtNewMethod.make(
183                 "    public test5.JIRA250Bar getBar() {" +
184                 "        return super.getBar();\n" +
185                 "    }\n", cc));
186         cc.addMethod(CtNewMethod.make("public int run() { getBar(); return 1; }", cc));
187         cc.writeFile();
188         Object obj = make(cc.getName());
189         assertEquals(1, invoke(obj, "run"));
190     }
191 
testProceedToDefaultMethod()192     public void testProceedToDefaultMethod() throws Exception {
193         CtClass cc = ClassPool.getDefault().get("test5.ProceedDefault");
194         CtMethod mth = cc.getDeclaredMethod("bar");
195         mth.instrument(new ExprEditor() {
196             public void edit(MethodCall c) throws CannotCompileException {
197                 c.replace("$_ = $proceed($$) + 10000;");
198             }
199         });
200         cc.writeFile();
201         Object obj = make(cc.getName());
202         assertEquals(21713, invoke(obj, "run"));
203     }
204 
testBadClass()205     public void testBadClass() throws Exception {
206         CtClass badClass = ClassPool.getDefault().makeClass("badClass");
207         String src = String.join(System.getProperty("line.separator"),
208                 "public void eval () {",
209                 "    if (true) {",
210                 "        double t=0;",
211                 "    } else {",
212                 "        double t=0;",
213                 "    }",
214                 "    for (int i=0; i < 2; i++) {",
215                 "        int a=0;",
216                 "        int b=0;",
217                 "        int c=0;",
218                 "        int d=0;",
219                 "        if (true) {",
220                 "            int e = 0;",
221                 "        }",
222                 "    }",
223                 "}");
224         System.out.println(src);
225         badClass.addMethod(CtMethod.make(src, badClass));
226         Class clazzz = badClass.toClass(Class.forName("DefineClassCapability"));
227         Object obj = clazzz.getConstructor().newInstance(); // <-- falls here
228     }
229 
test83StackmapWithArrayType()230     public void test83StackmapWithArrayType() throws Exception {
231     	final CtClass ctClass = sloader.get("test5.StackmapWithArray83");
232         final CtMethod method = ctClass.getDeclaredMethod("bytecodeVerifyError");
233         method.addLocalVariable("test_localVariable", CtClass.intType);
234         method.insertBefore("{ test_localVariable = 1; }");
235 
236         final CtMethod method2 = ctClass.getDeclaredMethod("bytecodeVerifyError2");
237         method2.addLocalVariable("test_localVariable", CtClass.intType);
238         method2.insertBefore("{ test_localVariable = 1; }");
239 
240         ctClass.writeFile();
241         Object obj = make(ctClass.getName());
242         assertEquals(1, invoke(obj, "run"));
243     }
244 
testLoaderClassPath()245     public void testLoaderClassPath() throws Exception {
246         ClassPool cp = new ClassPool();
247         cp.appendClassPath(new LoaderClassPath(new Loader()));
248         assertNotNull(cp.get(Object.class.getName()));
249         assertNotNull(cp.get(this.getClass().getName()));
250     }
251 
testAddDefaultMethod()252     public void testAddDefaultMethod() throws Exception {
253         CtClass cc = sloader.makeInterface("test5.AddDefaultMethod");
254         cc.addMethod(CtNewMethod.make("static int foo() { return 1; }", cc));
255         cc.addMethod(CtNewMethod.make("public static int foo1() { return 1; }", cc));
256         cc.addMethod(CtNewMethod.make("public int foo2() { return 1; }", cc));
257         cc.addMethod(CtNewMethod.make("int foo3() { return 1; }", cc));
258         try {
259             cc.addMethod(CtNewMethod.make("private int foo4() { return 1; }", cc));
260             fail();
261         } catch (CannotCompileException e) {}
262         try {
263             cc.addMethod(CtNewMethod.make("private static int foo5() { return 1; }", cc));
264             fail();
265         } catch (CannotCompileException e) {}
266     }
267 
testRemoveAnnotatino()268     public void testRemoveAnnotatino() throws Exception {
269         CtClass cc = sloader.get("test5.RemoveAnnotation");
270         AnnotationsAttribute aa
271             = (AnnotationsAttribute)cc.getClassFile().getAttribute(AnnotationsAttribute.invisibleTag);
272         assertTrue(aa.removeAnnotation("test5.RemoveAnno1"));
273         AttributeInfo ai = cc.getClassFile().removeAttribute(AnnotationsAttribute.invisibleTag);
274         assertEquals(ai.getName(), AnnotationsAttribute.invisibleTag);
275 
276         CtMethod foo = cc.getDeclaredMethod("foo");
277         AnnotationsAttribute aa2 = (AnnotationsAttribute)foo.getMethodInfo().getAttribute(AnnotationsAttribute.invisibleTag);
278         assertTrue(aa2.removeAnnotation("test5.RemoveAnno1"));
279 
280         CtMethod bar = cc.getDeclaredMethod("bar");
281         AnnotationsAttribute aa3 = (AnnotationsAttribute)bar.getMethodInfo().getAttribute(AnnotationsAttribute.invisibleTag);
282         assertFalse(aa3.removeAnnotation("test5.RemoveAnno1"));
283         assertTrue(aa3.removeAnnotation("test5.RemoveAnno2"));
284         AttributeInfo ai2 = bar.getMethodInfo().removeAttribute(AnnotationsAttribute.invisibleTag);
285         assertEquals(ai2.getName(), AnnotationsAttribute.invisibleTag);
286 
287         CtMethod run = cc.getDeclaredMethod("run");
288         AttributeInfo ai3 = run.getMethodInfo().removeAttribute(AnnotationsAttribute.invisibleTag);
289         assertNull(ai3);
290 
291         CtField baz = cc.getDeclaredField("baz");
292         AttributeInfo ai4 = baz.getFieldInfo().removeAttribute(AnnotationsAttribute.invisibleTag);
293         assertEquals(ai4.getName(), AnnotationsAttribute.invisibleTag);
294 
295         cc.writeFile();
296         Object obj = make(cc.getName());
297         assertEquals(3, invoke(obj, "run"));
298     }
299 
testInnerClassModifiers()300     public void testInnerClassModifiers() throws Exception {
301         CtClass cc = sloader.get("test5.InnerModifier$NonStatic");
302         try {
303             cc.setModifiers(Modifier.PUBLIC | Modifier.STATIC);
304             fail();
305         }
306         catch (RuntimeException e) {
307             if (!e.getMessage().startsWith("cannot change "))
308                 fail();
309         }
310 
311         cc.setModifiers(Modifier.PUBLIC);
312         cc.writeFile();
313 
314         assertEquals(Modifier.PUBLIC, cc.getModifiers());
315         InnerClassesAttribute ica = getInnerClassAttr(cc);
316         int i = ica.find("test5.InnerModifier$NonStatic");
317         assertTrue(i >= 0);
318         assertEquals(Modifier.PUBLIC, ica.accessFlags(i));
319 
320         CtClass cc2 = sloader.get("test5.InnerModifier$Static");
321 
322         InnerClassesAttribute ica3 = getInnerClassAttr(cc2);
323         int i3 = ica3.find("test5.InnerModifier$Static");
324         assertTrue(i3 >= 0);
325         assertEquals(AccessFlag.STATIC, ica3.accessFlags(i3));
326 
327         cc2.setModifiers(Modifier.PROTECTED | Modifier.STATIC);
328         cc2.setModifiers(Modifier.PUBLIC);
329         cc2.writeFile();
330 
331         assertEquals(Modifier.PUBLIC | Modifier.STATIC, cc2.getModifiers());
332         InnerClassesAttribute ica2 = getInnerClassAttr(cc2);
333         int i2 = ica2.find("test5.InnerModifier$Static");
334         assertTrue(i2 >= 0);
335         assertEquals(AccessFlag.PUBLIC | AccessFlag.STATIC, ica2.accessFlags(i2));
336 
337         CtClass cc3 = cc.getDeclaringClass();
338         assertTrue(cc3.isModified());
339         cc3.writeFile();
340 
341         InnerClassesAttribute ica4 = getInnerClassAttr(cc3);
342         int i4 = ica4.find("test5.InnerModifier$Static");
343         assertTrue(i4 >= 0);
344         assertEquals(AccessFlag.PUBLIC | AccessFlag.STATIC, ica4.accessFlags(i4));
345         int i5 = ica4.find("test5.InnerModifier$NonStatic");
346         assertTrue(i5 >= 0);
347         assertEquals(Modifier.PUBLIC, ica4.accessFlags(i5));
348     }
349 
testInnerClassModifiers2()350     public void testInnerClassModifiers2() throws Exception {
351         CtClass cc = sloader.get("test5.InnerModifier2$Protected");
352         Class<?> ccc = Class.forName("test5.InnerModifier2$Protected");
353         assertEquals(cc.getModifiers(), ccc.getModifiers());
354         assertTrue(Modifier.isProtected(cc.getModifiers()));
355 
356         cc = sloader.get("test5.InnerModifier2$Public");
357         ccc = Class.forName("test5.InnerModifier2$Public");
358         assertEquals(cc.getModifiers(), ccc.getModifiers());
359         assertTrue(Modifier.isPublic(cc.getModifiers()));
360 
361         cc = sloader.get("test5.InnerModifier2$Private");
362         ccc = Class.forName("test5.InnerModifier2$Private");
363         assertEquals(cc.getModifiers(), ccc.getModifiers());
364         assertTrue(Modifier.isPrivate(cc.getModifiers()));
365 
366         cc = sloader.get("test5.InnerModifier2$Package");
367         ccc = Class.forName("test5.InnerModifier2$Package");
368         assertEquals(cc.getModifiers(), ccc.getModifiers());
369         assertTrue(Modifier.isPackage(cc.getModifiers()));
370 
371         cc = sloader.get("test5.InnerModifier2$ProtectedStatic");
372         ccc = Class.forName("test5.InnerModifier2$ProtectedStatic");
373         assertEquals(cc.getModifiers(), ccc.getModifiers());
374         assertTrue(Modifier.isProtected(cc.getModifiers()));
375         assertTrue(Modifier.isStatic(cc.getModifiers()));
376 
377         cc = sloader.get("test5.InnerModifier2$PublicStatic");
378         ccc = Class.forName("test5.InnerModifier2$PublicStatic");
379         assertEquals(cc.getModifiers(), ccc.getModifiers());
380         assertTrue(Modifier.isPublic(cc.getModifiers()));
381         assertTrue(Modifier.isStatic(cc.getModifiers()));
382 
383         cc = sloader.get("test5.InnerModifier2$PrivateStatic");
384         ccc = Class.forName("test5.InnerModifier2$PrivateStatic");
385         assertEquals(cc.getModifiers(), ccc.getModifiers());
386         assertTrue(Modifier.isPrivate(cc.getModifiers()));
387         assertTrue(Modifier.isStatic(cc.getModifiers()));
388 
389         cc = sloader.get("test5.InnerModifier2$PackageStatic");
390         ccc = Class.forName("test5.InnerModifier2$PackageStatic");
391         assertEquals(cc.getModifiers(), ccc.getModifiers());
392         assertTrue(Modifier.isPackage(cc.getModifiers()));
393         assertTrue(Modifier.isStatic(cc.getModifiers()));
394     }
395 
getInnerClassAttr(CtClass cc)396     private InnerClassesAttribute getInnerClassAttr(CtClass cc) {
397         return (InnerClassesAttribute)cc.getClassFile2().getAttribute(InnerClassesAttribute.tag);
398     }
399 
testVarArgsModifier()400     public void testVarArgsModifier() throws Exception {
401         CtClass cc = sloader.get("test5.VarArgsMethod");
402         assertTrue(Modifier.isVarArgs(cc.getDeclaredMethod("foo").getModifiers()));
403         assertFalse(Modifier.isVarArgs(cc.getDeclaredMethod("bar").getModifiers()));
404     }
405 
testIssue155()406     public void testIssue155() throws Exception {
407         CtClass cc = sloader.get("test5.Issue155");
408         CtMethod testMethod = cc.getDeclaredMethod("foo");
409         testMethod.instrument(
410                 new ExprEditor() {
411                     public void edit(Handler m)
412                             throws CannotCompileException {
413                         m.insertBefore("throw $1;");
414                     }
415                 });
416 
417         cc.writeFile();
418         Object obj = make(cc.getName());
419         assertEquals(1, invoke(obj, "test"));
420     }
421 
testNestHostAttribute()422     public void testNestHostAttribute() throws Exception {
423         CtClass cc = sloader.get("test5.NestHost$Foo");
424         ClassFile cf = cc.getClassFile();
425         NestHostAttribute attr = (NestHostAttribute)cf.getAttribute(NestHostAttribute.tag);
426         assertEquals(test5.NestHost.class.getName(),
427                      cf.getConstPool().getClassInfo(attr.hostClassIndex()));
428     }
429 
testNestMembersAttribute()430     public void testNestMembersAttribute() throws Exception {
431         CtClass cc = sloader.get("test5.NestHost");
432         ClassFile cf = cc.getClassFile();
433         NestMembersAttribute attr = (NestMembersAttribute)cf.getAttribute(NestMembersAttribute.tag);
434         assertEquals(2, attr.numberOfClasses());
435         String[] names = new String[2];
436         for (int i = 0; i < 2; i++)
437             names[i] = cf.getConstPool().getClassInfo(attr.memberClass(i));
438 
439         assertFalse(names[0].equals(names[1]));
440         assertTrue(names[0].equals("test5.NestHost$Foo") || names[0].equals("test5.NestHost$Bar"));
441         assertTrue(names[1].equals("test5.NestHost$Foo") || names[1].equals("test5.NestHost$Bar"));
442     }
443 
testNestMembersAttributeCopy()444     public void testNestMembersAttributeCopy() throws Exception {
445         CtClass cc = sloader.get("test5.NestHost2");
446         cc.getClassFile().compact();
447         cc.writeFile();
448         make(cc.getName());
449     }
450 
testNestHostAttributeCopy()451     public void testNestHostAttributeCopy() throws Exception {
452         CtClass cc = sloader.get("test5.NestHost2$Foo");
453         cc.getClassFile().compact();
454         cc.toClass(test5.DefineClassCapability.class);
455     }
456 }
457