From 9c8642593c77e9a596d69e1f054a7bb5640d37a7 Mon Sep 17 00:00:00 2001 From: Skylot Date: Wed, 8 Sep 2021 19:07:25 +0100 Subject: [PATCH] fix: don't visit inner classes twice in pre-processing --- .../java/jadx/core/dex/nodes/ClassNode.java | 19 +++++++++++-------- .../java/jadx/core/dex/nodes/RootNode.java | 12 +++++++++--- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java b/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java index 2066c783b..f8c9014bb 100644 --- a/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java @@ -450,15 +450,18 @@ public class ClassNode extends NotificationAttrNode implements ILoadable, ICodeN } public ClassNode getParentClass() { - if (parentClass == null) { - if (clsInfo.isInner()) { - ClassNode parent = root.resolveClass(clsInfo.getParentClass()); - parentClass = parent == null ? this : parent; - } else { - parentClass = this; + return parentClass; + } + + public void updateParentClass() { + if (clsInfo.isInner()) { + ClassNode parent = root.resolveClass(clsInfo.getParentClass()); + if (parent != null) { + parentClass = parent; + return; } } - return parentClass; + parentClass = this; } public ClassNode getTopParentClass() { @@ -548,7 +551,7 @@ public class ClassNode extends NotificationAttrNode implements ILoadable, ICodeN } public boolean isInner() { - return parentClass != null; + return parentClass != this; } @Nullable diff --git a/jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java b/jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java index 3b8f0c3af..f1d4c3e97 100644 --- a/jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java @@ -100,14 +100,16 @@ public class RootNode { markDuplicatedClasses(classes); } classes = new ArrayList<>(clsMap.values()); - // sort classes by name, expect top classes before inner - classes.sort(Comparator.comparing(ClassNode::getFullName)); - initInnerClasses(); // print stats for loaded classes int mthCount = classes.stream().mapToInt(c -> c.getMethods().size()).sum(); int insnsCount = classes.stream().flatMap(c -> c.getMethods().stream()).mapToInt(MethodNode::getInsnsCount).sum(); LOG.info("Loaded classes: {}, methods: {}, instructions: {}", classes.size(), mthCount, insnsCount); + + // sort classes by name, expect top classes before inner + classes.sort(Comparator.comparing(ClassNode::getFullName)); + // move inner classes + initInnerClasses(); } private void addDummyClass(IClassData classData, Exception exc) { @@ -254,6 +256,7 @@ public class RootNode { innerCls.getClassInfo().updateNames(this); } } + classes.forEach(ClassNode::updateParentClass); } public void runPreDecompileStage() { @@ -266,6 +269,9 @@ public class RootNode { LOG.error("Visitor init failed: {}", pass.getClass().getSimpleName(), e); } for (ClassNode cls : classes) { + if (cls.isInner()) { + continue; + } DepthTraversal.visit(pass, cls); } if (debugEnabled) {