diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/debuginfo/DebugInfoAttachVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/debuginfo/DebugInfoAttachVisitor.java index 84ec2011d..abc1c1120 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/debuginfo/DebugInfoAttachVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/debuginfo/DebugInfoAttachVisitor.java @@ -1,15 +1,14 @@ package jadx.core.dex.visitors.debuginfo; -import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import jadx.api.plugins.input.data.IDebugInfo; import jadx.api.plugins.input.data.ILocalVar; import jadx.core.dex.attributes.AFlag; import jadx.core.dex.attributes.nodes.LocalVarsDebugInfoAttr; import jadx.core.dex.attributes.nodes.RegDebugInfoAttr; -import jadx.core.dex.instructions.InsnType; import jadx.core.dex.instructions.args.ArgType; import jadx.core.dex.instructions.args.InsnArg; import jadx.core.dex.instructions.args.RegisterArg; @@ -20,7 +19,6 @@ import jadx.core.dex.visitors.AbstractVisitor; import jadx.core.dex.visitors.JadxVisitor; import jadx.core.dex.visitors.blocks.BlockSplitter; import jadx.core.dex.visitors.ssa.SSATransform; -import jadx.core.utils.ListUtils; import jadx.core.utils.exceptions.InvalidDataException; import jadx.core.utils.exceptions.JadxException; @@ -59,32 +57,46 @@ public class DebugInfoAttachVisitor extends AbstractVisitor { if (lineMapping.isEmpty()) { return; } - Map linesStat = new HashMap<>(); // count repeating lines for (Map.Entry entry : lineMapping.entrySet()) { try { - Integer offset = entry.getKey(); - InsnNode insn = insnArr[offset]; + InsnNode insn = insnArr[entry.getKey()]; if (insn != null) { - int line = entry.getValue(); - insn.setSourceLine(line); - if (insn.getType() != InsnType.NOP) { - linesStat.merge(line, 1, (v, one) -> v + 1); - } + insn.setSourceLine(entry.getValue()); } } catch (Exception e) { mth.addWarnComment("Error attach source line", e); + return; } } - // 3 here is allowed maximum for lines repeat, - // can occur in indexed 'for' loops (3 instructions with same line) - List> repeatingLines = ListUtils.filter(linesStat.entrySet(), p -> p.getValue() > 3); - if (repeatingLines.isEmpty()) { - mth.add(AFlag.USE_LINES_HINTS); + String ignoreReason = verifyDebugLines(lineMapping); + if (ignoreReason != null) { + mth.addDebugComment("Don't trust debug lines info. " + ignoreReason); } else { - mth.addDebugComment("Don't trust debug lines info. Repeating lines: " + repeatingLines); + mth.add(AFlag.USE_LINES_HINTS); } } + private String verifyDebugLines(Map lineMapping) { + // search min line in method + int minLine = lineMapping.values().stream().mapToInt(v -> v).min().orElse(Integer.MAX_VALUE); + if (minLine < 3) { + return "Lines numbers was adjusted: min line is " + minLine; + } + + // count repeating lines + // 3 here is allowed maximum for line repeat count + // can occur in indexed 'for' loops (3 instructions with the same line) + var repeatingLines = lineMapping.values().stream() + .collect(Collectors.toMap(l -> l, l -> 1, Integer::sum)) + .entrySet().stream() + .filter(p -> p.getValue() > 3) + .collect(Collectors.toList()); + if (!repeatingLines.isEmpty()) { + return "Repeating lines: " + repeatingLines; + } + return null; + } + private void attachDebugInfo(MethodNode mth, List localVars, InsnNode[] insnArr) { if (localVars.isEmpty()) { return; diff --git a/jadx-core/src/test/java/jadx/tests/integration/others/TestConstructor2.java b/jadx-core/src/test/java/jadx/tests/integration/others/TestConstructor2.java index d9a4090b8..92a66206e 100644 --- a/jadx-core/src/test/java/jadx/tests/integration/others/TestConstructor2.java +++ b/jadx-core/src/test/java/jadx/tests/integration/others/TestConstructor2.java @@ -15,6 +15,7 @@ public class TestConstructor2 extends SmaliTest { public void test() { assertThat(getClassNodeFromSmaliFiles()) .code() - .containsOne("A a = new A();"); + .containsOne("A a = new A();") + .doesNotContain("return"); } } diff --git a/jadx-core/src/test/java/jadx/tests/integration/others/TestConstructorBranched3.java b/jadx-core/src/test/java/jadx/tests/integration/others/TestConstructorBranched3.java index a88cb6b72..c5c34cbdc 100644 --- a/jadx-core/src/test/java/jadx/tests/integration/others/TestConstructorBranched3.java +++ b/jadx-core/src/test/java/jadx/tests/integration/others/TestConstructorBranched3.java @@ -14,6 +14,6 @@ public class TestConstructorBranched3 extends SmaliTest { disableCompilation(); assertThat(getClassNodeFromSmali()) .code() - .countString(4, "return new f("); + .countString(2, "return new f("); } }