IllegalArgumentException at Frame.getAbstractTypeFromDescriptor on class name with parentheses
Here's a code sample to reproduce:
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import static org.objectweb.asm.Opcodes.*;
public class Test {
public static void main(String[] args) {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
cw.visit(52, ACC_FINAL + ACC_SUPER, "A$()$1", null, null, null);
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "foo", "()V", null, null);
mv.visitMethodInsn(INVOKESPECIAL, "A$()$1$1", "<init>", "(LA$()$1;)V", false);
}
}
It fails with the following exception:
Exception in thread "main" java.lang.IllegalArgumentException
at org.objectweb.asm.Frame.getAbstractTypeFromDescriptor(Frame.java:367)
at org.objectweb.asm.Frame.push(Frame.java:544)
at org.objectweb.asm.Frame.execute(Frame.java:1035)
at org.objectweb.asm.MethodWriter.visitMethodInsn(MethodWriter.java:1056)
at Test.main(Test.java:12)
The problem is likely in Frame.push
: it assumes that )
appears only as a separator of method arguments and return type and uses indexOf(')')
to find that separator. Here, however, it's a part of the parameter's type name (which is not disallowed in method names, as per JVMS §4.2.2). I assume Frame.push
should parse the signature instead to locate the needed separator to avoid misinterpreting the given descriptor.
I was able to reproduce this issue on ASM versions since 6.1. On 6.0 it works as expected and doesn't crash.
We've met this problem in Kotlin 1.3.20 where we upgraded our ASM version and users started to get these exceptions. Apparently, it's a common scenario to use characters such as parentheses in test names to make them clearer, and as soon as you declare a local class or a capturing lambda in such test method, the compiler will crash this way.