Open rehwinkel opened 3 years ago
This is a minimal example that explains how this bug is created:
public class Test implements java.lang.Comparable<Test> {
public int compareTo(Test t) {
return 0;
}
}
The code generated is this:
{
public Test();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 1: 0
public int compareTo(Test);
descriptor: (LTest;)I
flags: (0x0001) ACC_PUBLIC
Code:
stack=1, locals=2, args_size=2
0: iconst_0
1: ireturn
LineNumberTable:
line 3: 0
public int compareTo(java.lang.Object);
descriptor: (Ljava/lang/Object;)I
flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
Code:
stack=2, locals=2, args_size=2
0: aload_0
1: aload_1
2: checkcast #7 // class Test
5: invokevirtual #9 // Method compareTo:(LTest;)I
8: ireturn
LineNumberTable:
line 1: 0
}
As you can see, the synthetic compareTo method calls the specialized version. However, if the specialized version is renamed by a deobfuscator, CFR can no longer correctly decompile this code.
CFR version
CFR 0.151
Compiler
Unknown, but presumably javac with proguard
Description
When decompiling a class implementing
java.lang.Comparable
the interface methodcompareTo
, which, because it is generic, takesObject
as a parameter, will be decompiled as such, rendering the decompiled code invalid because the parameter of thecompareTo
function doesnt match the generic argument.Example
I assume that in this example, the
compareTo
method has been generated by an obfuscator when themethod_26_a
was renamed. However,Comparable
should be accessible to CFR which means it should be able to fill in the erased type. The decompiled code of this is roughly this: