Fix NPE when decompiling constructor #654
This commit is contained in:
committed by
Egor Ushakov
parent
7c8e64da81
commit
a74a9d7d25
@@ -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"); }
|
||||||
|
|||||||
BIN
testData/classes/pkg/TestMissingConstructorCallBad.class
Normal file
BIN
testData/classes/pkg/TestMissingConstructorCallBad.class
Normal file
Binary file not shown.
BIN
testData/classes/pkg/TestMissingConstructorCallGood.class
Normal file
BIN
testData/classes/pkg/TestMissingConstructorCallGood.class
Normal file
Binary file not shown.
50
testData/results/TestMissingConstructorCallBad.dec
Normal file
50
testData/results/TestMissingConstructorCallBad.dec
Normal file
@@ -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
|
||||||
60
testData/results/TestMissingConstructorCallGood.dec
Normal file
60
testData/results/TestMissingConstructorCallGood.dec
Normal file
@@ -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
|
||||||
42
testData/src/pkg/TestMissingConstructorCallBad.jasm
Normal file
42
testData/src/pkg/TestMissingConstructorCallBad.jasm
Normal file
@@ -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
|
||||||
50
testData/src/pkg/TestMissingConstructorCallGood.jasm
Normal file
50
testData/src/pkg/TestMissingConstructorCallGood.jasm
Normal file
@@ -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
|
||||||
Reference in New Issue
Block a user