diff --git a/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java b/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java index db8d4bebd..09a06b416 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java @@ -309,7 +309,7 @@ public class InsnGen { break; case APUT: - code.add(arg(insn, 0)).add('[').add(arg(insn, 1)).add("] = ").add(arg(insn, 2)); + code.add(arg(insn, 0)).add('[').add(arg(insn.getArg(1), false)).add("] = ").add(arg(insn.getArg(2), false)); break; case IGET: { diff --git a/jadx-core/src/main/java/jadx/core/codegen/RegionGen.java b/jadx-core/src/main/java/jadx/core/codegen/RegionGen.java index 7fcd2fae1..4b4a7666a 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/RegionGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/RegionGen.java @@ -167,7 +167,7 @@ public class RegionGen extends InsnGen { return "!" + makeCondition(condition.getArgs().get(0)); case AND: case OR: - String mode = condition.getMode() == IfCondition.MODE.AND ? " && " : " || "; + String mode = condition.getMode() == IfCondition.Mode.AND ? " && " : " || "; StringBuilder sb = new StringBuilder(); for (IfCondition arg : condition.getArgs()) { if (sb.length() != 0) { diff --git a/jadx-core/src/main/java/jadx/core/dex/regions/IfCondition.java b/jadx-core/src/main/java/jadx/core/dex/regions/IfCondition.java index ef4aed819..d22a05c7b 100644 --- a/jadx-core/src/main/java/jadx/core/dex/regions/IfCondition.java +++ b/jadx-core/src/main/java/jadx/core/dex/regions/IfCondition.java @@ -5,6 +5,7 @@ import jadx.core.dex.instructions.IfOp; import jadx.core.dex.instructions.args.InsnArg; import jadx.core.dex.nodes.BlockNode; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -21,16 +22,18 @@ public final class IfCondition { return new IfCondition(new Compare(insn)); } - public static IfCondition not(IfCondition a) { - return new IfCondition(MODE.NOT, Arrays.asList(a)); - } - - public static IfCondition and(IfCondition a, IfCondition b) { - return new IfCondition(MODE.AND, Arrays.asList(a, b)); - } - - public static IfCondition or(IfCondition a, IfCondition b) { - return new IfCondition(MODE.OR, Arrays.asList(a, b)); + public static IfCondition merge(Mode mode, IfCondition a, IfCondition b) { + if (a.getMode() == mode) { + IfCondition n = new IfCondition(a); + n.addArg(b); + return n; + } else if (b.getMode() == mode) { + IfCondition n = new IfCondition(b); + n.addArg(a); + return n; + } else { + return new IfCondition(mode, Arrays.asList(a, b)); + } } public static final class Compare { @@ -61,30 +64,36 @@ public final class IfCondition { } } - public static enum MODE { + public static enum Mode { COMPARE, NOT, AND, OR } - private final MODE mode; + private final Mode mode; private final List args; private final Compare compare; private IfCondition(Compare compare) { - this.mode = MODE.COMPARE; + this.mode = Mode.COMPARE; this.compare = compare; this.args = null; } - private IfCondition(MODE mode, List args) { + private IfCondition(Mode mode, List args) { this.mode = mode; this.args = args; this.compare = null; } - public MODE getMode() { + private IfCondition(IfCondition c) { + this.mode = c.mode; + this.compare = c.compare; + this.args = new ArrayList(c.args); + } + + public Mode getMode() { return mode; } @@ -92,8 +101,12 @@ public final class IfCondition { return args; } + public void addArg(IfCondition c) { + args.add(c); + } + public boolean isCompare() { - return mode == MODE.COMPARE; + return mode == Mode.COMPARE; } public Compare getCompare() { diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionMaker.java b/jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionMaker.java index e1e2a3590..448e159aa 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionMaker.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionMaker.java @@ -40,6 +40,7 @@ import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static jadx.core.dex.regions.IfCondition.Mode; import static jadx.core.utils.BlockUtils.getBlockByOffset; import static jadx.core.utils.BlockUtils.isPathExists; import static jadx.core.utils.BlockUtils.selectOther; @@ -400,6 +401,7 @@ public class RegionMaker { IfCondition condition; boolean inverted = false; + IfCondition nestedCondition = IfCondition.fromIfNode(nestedIfInsn); if (isPathExists(bElse, nestedIfBlock)) { // else branch if (bThen != nbThen) { @@ -409,7 +411,7 @@ public class RegionMaker { nestedIfInsn.invertOp(nbElse.getStartOffset()); inverted = true; } - condition = IfCondition.or(ifRegion.getCondition(), IfCondition.fromIfNode(nestedIfInsn)); + condition = IfCondition.merge(Mode.OR, ifRegion.getCondition(), nestedCondition); } else { // then branch if (bElse != nbElse) { @@ -419,7 +421,7 @@ public class RegionMaker { nestedIfInsn.invertOp(nbElse.getStartOffset()); inverted = true; } - condition = IfCondition.and(ifRegion.getCondition(), IfCondition.fromIfNode(nestedIfInsn)); + condition = IfCondition.merge(Mode.AND, ifRegion.getCondition(), nestedCondition); } ifRegion.setCondition(condition); nestedIfBlock.getAttributes().add(AttributeFlag.SKIP); diff --git a/jadx-core/src/test/java/jadx/tests/internal/TestRedundantBrackets.java b/jadx-core/src/test/java/jadx/tests/internal/TestRedundantBrackets.java index 541c409d4..a8f5f37d8 100644 --- a/jadx-core/src/test/java/jadx/tests/internal/TestRedundantBrackets.java +++ b/jadx-core/src/test/java/jadx/tests/internal/TestRedundantBrackets.java @@ -31,6 +31,17 @@ public class TestRedundantBrackets extends InternalJadxTest { } return b; } + + public void method4(int num) { + if (num == 4 || num == 6 || num == 8 || num == 10) { + method2(null); + } + } + + public void method5(int a[], int n) { + a[1] = n * 2; + a[n - 1] = 1; + } } @Test @@ -42,5 +53,9 @@ public class TestRedundantBrackets extends InternalJadxTest { assertThat(code, containsString("if (obj instanceof String)")); assertThat(code, containsString("if (a + b < 10)")); assertThat(code, containsString("if ((a & b) != 0)")); + assertThat(code, containsString("if (num == 4 || num == 6 || num == 8 || num == 10)")); + + assertThat(code, containsString("a[1] = n * 2;")); + assertThat(code, containsString("a[n - 1] = 1;")); } } diff --git a/jadx-samples/src/main/java/jadx/samples/TestConditions.java b/jadx-samples/src/main/java/jadx/samples/TestConditions.java index bdb4fc9a7..aeafc398f 100644 --- a/jadx-samples/src/main/java/jadx/samples/TestConditions.java +++ b/jadx-samples/src/main/java/jadx/samples/TestConditions.java @@ -50,6 +50,16 @@ public class TestConditions extends AbstractTest { test1(0); } + public void test4(int num) { + if (num == 4 || num == 6 || num == 8 || num == 10) { + accept("a"); + } + } + + public boolean test5(int num) { + return num > 5 && (num < 10 || num == 7); + } + public boolean accept(String name) { return name.startsWith("Test") && name.endsWith(".class") && !name.contains("$"); } @@ -71,6 +81,12 @@ public class TestConditions extends AbstractTest { assertTrue(accept("Test.class")); test3(false, false); + + assertFalse(test5(4)); + assertFalse(test5(11)); + assertTrue(test5(6)); + assertTrue(test5(7)); + assertTrue(test5(8)); return true; }