core: MethodNode: Fix possible decompilation failure on refresh inner class

checkInstructions() may fail with NPE:
ERROR - NullPointerException in pass: BlockSplitter in method: com.google.common.primitives.Ints.IntArrayAsList.<init>(int[], int, int):void, dex: out.dex
java.lang.NullPointerException: null
        at jadx.core.dex.nodes.MethodNode.checkInstructions(MethodNode.java:159)
        at jadx.core.dex.visitors.blocksmaker.BlockSplitter.visit(BlockSplitter.java:49)
        at jadx.core.dex.visitors.DepthTraversal.visit(DepthTraversal.java:31)
        at jadx.core.dex.visitors.DepthTraversal.lambda$visit$1(DepthTraversal.java:16)
        at java.util.ArrayList.forEach(ArrayList.java:1257)
        at jadx.core.dex.visitors.DepthTraversal.visit(DepthTraversal.java:16)
        at jadx.core.dex.visitors.DepthTraversal.lambda$visit$0(DepthTraversal.java:15)
        at java.util.ArrayList.forEach(ArrayList.java:1257)
        at jadx.core.dex.visitors.DepthTraversal.visit(DepthTraversal.java:15)
        at jadx.core.ProcessClass.process(ProcessClass.java:41)
        at jadx.core.ProcessClass.generateCode(ProcessClass.java:58)
        at jadx.core.dex.nodes.ClassNode.decompile(ClassNode.java:292)
        at jadx.core.dex.nodes.ClassNode.decompile(ClassNode.java:271)
        at jadx.core.dex.nodes.ClassNode.refresh(ClassNode.java:303)
        at jadx.api.JavaClass.refresh(JavaClass.java:61)
        at jadx.gui.treemodel.JClass.refresh(JClass.java:63)
...

This happens because MethodNode.unloadInsnArr() call from BlockSplitter.visit() - after it instructions[] become null.
So, try to reload method before processing its instructions array.
This commit is contained in:
S-trace
2020-01-02 21:30:40 +03:00
committed by Soul Trace
parent df520a1134
commit d346ed0570
@@ -154,6 +154,15 @@ public class MethodNode extends LineAttrNode implements ILoadable, ICodeNode {
public void checkInstructions() {
List<RegisterArg> list = new ArrayList<>();
if (instructions == null) {
LOG.debug("Instructions == null, reloading method {}.{}", getClass().getName(), getName());
unload();
try {
load();
} catch (DecodeException e) {
throw new JadxRuntimeException("Failed to reload method " + getClass().getName() + "." + getName());
}
}
for (InsnNode insnNode : instructions) {
if (insnNode == null) {
continue;