Fix NPE when decompiling constructor #654

master
Maxim Degtyarev 7 years ago committed by Egor Ushakov
parent 7c8e64da81
commit a74a9d7d25
  1. 11
      src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExprUtil.java
  2. 3
      test/org/jetbrains/java/decompiler/SingleClassesTest.java
  3. BIN
      testData/classes/pkg/TestMissingConstructorCallBad.class
  4. BIN
      testData/classes/pkg/TestMissingConstructorCallGood.class
  5. 50
      testData/results/TestMissingConstructorCallBad.dec
  6. 60
      testData/results/TestMissingConstructorCallGood.dec
  7. 42
      testData/src/pkg/TestMissingConstructorCallBad.jasm
  8. 50
      testData/src/pkg/TestMissingConstructorCallGood.jasm

@ -1,12 +1,11 @@
/* // Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
*/
package org.jetbrains.java.decompiler.modules.decompiler.exps; package org.jetbrains.java.decompiler.modules.decompiler.exps;
import org.jetbrains.java.decompiler.code.CodeConstants; import org.jetbrains.java.decompiler.code.CodeConstants;
import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode;
import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.main.rels.ClassWrapper; import org.jetbrains.java.decompiler.main.rels.ClassWrapper;
import org.jetbrains.java.decompiler.main.rels.MethodWrapper;
import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair;
import java.util.ArrayList; import java.util.ArrayList;
@ -25,7 +24,11 @@ public class ExprUtil {
ClassWrapper wrapper = node.getWrapper(); ClassWrapper wrapper = node.getWrapper();
if (wrapper != null) { if (wrapper != null) {
// own class // own class
mask = wrapper.getMethodWrapper(CodeConstants.INIT_NAME, descriptor).synthParameters; MethodWrapper methodWrapper = wrapper.getMethodWrapper(CodeConstants.INIT_NAME, descriptor);
if (methodWrapper == null) {
return null;
}
mask = methodWrapper.synthParameters;
} }
else if (parameters > 0 && node.type == ClassNode.CLASS_MEMBER && (node.access & CodeConstants.ACC_STATIC) == 0) { else if (parameters > 0 && node.type == ClassNode.CLASS_MEMBER && (node.access & CodeConstants.ACC_STATIC) == 0) {
// non-static member class // non-static member class

@ -104,6 +104,9 @@ public class SingleClassesTest {
@Test public void testPop2TwoIntPop2() { doTest("pkg/TestPop2TwoIntPop2"); } @Test public void testPop2TwoIntPop2() { doTest("pkg/TestPop2TwoIntPop2"); }
@Test public void testPop2TwoIntTwoPop() { doTest("pkg/TestPop2TwoIntTwoPop"); } @Test public void testPop2TwoIntTwoPop() { doTest("pkg/TestPop2TwoIntTwoPop"); }
@Test public void testSuperInner() { doTest("pkg/TestSuperInner", "pkg/TestSuperInnerBase"); } @Test public void testSuperInner() { doTest("pkg/TestSuperInner", "pkg/TestSuperInnerBase"); }
@Test public void testMissingConstructorCallGood() { doTest("pkg/TestMissingConstructorCallGood"); }
@Test public void testMissingConstructorCallBad() { doTest("pkg/TestMissingConstructorCallBad"); }
// TODO: fix all below // TODO: fix all below
//@Test public void testPackageInfo() { doTest("pkg/package-info"); } //@Test public void testPackageInfo() { doTest("pkg/package-info"); }

@ -0,0 +1,50 @@
package pkg;
public class TestMissingConstructorCallBad {
private TestMissingConstructorCallBad() {
System.out.println("Nobody will see what we do here!");// 14 15 16
this((Object)null);// 19 20
}// 21
public static void main(String... var0) {
try {
new TestMissingConstructorCallBad();
} catch (Throwable var2) {// 37
;
}
}// 39
}
class 'pkg/TestMissingConstructorCallBad' {
method '<init> ()V' {
0 4
3 4
5 4
9 5
a 5
d 6
}
method 'main ([Ljava/lang/String;)V' {
b 11
c 15
}
}
Lines mapping:
14 <-> 5
15 <-> 5
16 <-> 5
19 <-> 6
20 <-> 6
21 <-> 7
37 <-> 12
39 <-> 16
Not mapped:
18
28
29
30
31
33

@ -0,0 +1,60 @@
package pkg;
public class TestMissingConstructorCallGood {
private TestMissingConstructorCallGood(Object var1) {
}// 16
private TestMissingConstructorCallGood() {
System.out.println("Nobody will see what we do here!");// 22 23 24
this((Object)null);// 27 28
}// 29
public static void main(String... var0) {
try {
new TestMissingConstructorCallGood();
} catch (Throwable var2) {// 45
;
}
}// 47
}
class 'pkg/TestMissingConstructorCallGood' {
method '<init> (Ljava/lang/Object;)V' {
4 4
}
method '<init> ()V' {
0 7
3 7
5 7
9 8
a 8
d 9
}
method 'main ([Ljava/lang/String;)V' {
b 14
c 18
}
}
Lines mapping:
16 <-> 5
22 <-> 8
23 <-> 8
24 <-> 8
27 <-> 9
28 <-> 9
29 <-> 10
45 <-> 15
47 <-> 19
Not mapped:
14
15
26
36
37
38
39
41

@ -0,0 +1,42 @@
/**
* This code can be assembled with <a href="https://wiki.openjdk.java.net/display/CodeTools/asmtools">asmtools</a>
* using <code>asmtools jasm -g *.jasm</code> command line.
*/
package pkg;
super public class TestMissingConstructorCallBad
version 52:0
{
private Method "<init>":"()V"
stack 2 locals 1
{
getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
ldc String "Nobody will see what we do here!";
invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V";
aload_0;
aconst_null;
invokespecial Method "<init>":"(Ljava/lang/Object;)V";
return;
}
public static varargs Method main:"([Ljava/lang/String;)V"
stack 2 locals 2
{
try t0;
new class TestMissingConstructorCallBad;
dup;
invokespecial Method "<init>":"()V";
pop;
endtry t0;
goto L12;
catch t0 java/lang/Throwable;
stack_frame_type stack1;
stack_map class java/lang/Throwable;
astore_1;
L12: stack_frame_type same;
return;
}
} // end Class TestMissingConstructorCallBad

@ -0,0 +1,50 @@
/**
* This code can be assembled with <a href="https://wiki.openjdk.java.net/display/CodeTools/asmtools">asmtools</a>
* using <code>asmtools jasm -g *.jasm</code> command line.
*/
package pkg;
super public class TestMissingConstructorCallGood
version 52:0
{
private Method "<init>":"(Ljava/lang/Object;)V"
stack 1 locals 2
{
aload_0;
invokespecial Method java/lang/Object."<init>":"()V";
return;
}
private Method "<init>":"()V"
stack 2 locals 1
{
getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
ldc String "Nobody will see what we do here!";
invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V";
aload_0;
aconst_null;
invokespecial Method "<init>":"(Ljava/lang/Object;)V";
return;
}
public static varargs Method main:"([Ljava/lang/String;)V"
stack 2 locals 2
{
try t0;
new class TestMissingConstructorCallGood;
dup;
invokespecial Method "<init>":"()V";
pop;
endtry t0;
goto L12;
catch t0 java/lang/Throwable;
stack_frame_type stack1;
stack_map class java/lang/Throwable;
astore_1;
L12: stack_frame_type same;
return;
}
} // end Class TestMissingConstructorCallGood
Loading…
Cancel
Save