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;
|
||||
|
||||
import org.jetbrains.java.decompiler.code.CodeConstants;
|
||||
import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode;
|
||||
import org.jetbrains.java.decompiler.main.DecompilerContext;
|
||||
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 java.util.ArrayList;
|
||||
@@ -25,7 +24,11 @@ public class ExprUtil {
|
||||
ClassWrapper wrapper = node.getWrapper();
|
||||
if (wrapper != null) {
|
||||
// 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) {
|
||||
// non-static member class
|
||||
|
||||
@@ -104,6 +104,9 @@ public class SingleClassesTest {
|
||||
@Test public void testPop2TwoIntPop2() { doTest("pkg/TestPop2TwoIntPop2"); }
|
||||
@Test public void testPop2TwoIntTwoPop() { doTest("pkg/TestPop2TwoIntTwoPop"); }
|
||||
@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
|
||||
//@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