From 632cc3ec166c46e00db549c5153f95a94c24cb31 Mon Sep 17 00:00:00 2001 From: Ahmed Ashour Date: Mon, 15 Apr 2019 17:09:01 +0200 Subject: [PATCH] fix: add primitive cast in ternary for byte and short (PR #601) --- .../main/java/jadx/core/codegen/InsnGen.java | 21 +++++++ .../integration/conditions/TestCast.java | 61 +++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 jadx-core/src/test/java/jadx/tests/integration/conditions/TestCast.java 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 bbb7241a..4125dafc 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java @@ -862,6 +862,7 @@ public class InsnGen { } else { condGen.wrap(code, insn.getCondition()); code.add(" ? "); + addCastIfNeeded(code, first, second); addArg(code, first, false); code.add(" : "); addArg(code, second, false); @@ -871,6 +872,26 @@ public class InsnGen { } } + private void addCastIfNeeded(CodeWriter code, InsnArg first, InsnArg second) { + if (first.isLiteral() && second.isLiteral()) { + if (first.getType() == ArgType.BYTE) { + long lit1 = ((LiteralArg) first).getLiteral(); + long lit2 = ((LiteralArg) second).getLiteral(); + if (lit1 != Byte.MAX_VALUE && lit1 != Byte.MIN_VALUE + && lit2 != Byte.MAX_VALUE && lit2 != Byte.MIN_VALUE) { + code.add("(byte) "); + } + } else if (first.getType() == ArgType.SHORT) { + long lit1 = ((LiteralArg) first).getLiteral(); + long lit2 = ((LiteralArg) second).getLiteral(); + if (lit1 != Short.MAX_VALUE && lit1 != Short.MIN_VALUE + && lit2 != Short.MAX_VALUE && lit2 != Short.MIN_VALUE) { + code.add("(short) "); + } + } + } + } + private void makeArith(ArithNode insn, CodeWriter code, Set state) throws CodegenException { if (insn.contains(AFlag.ARITH_ONEARG)) { makeArithOneArg(insn, code); diff --git a/jadx-core/src/test/java/jadx/tests/integration/conditions/TestCast.java b/jadx-core/src/test/java/jadx/tests/integration/conditions/TestCast.java new file mode 100644 index 00000000..44fc3aa7 --- /dev/null +++ b/jadx-core/src/test/java/jadx/tests/integration/conditions/TestCast.java @@ -0,0 +1,61 @@ +package jadx.tests.integration.conditions; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; + +import org.junit.jupiter.api.Test; + +import jadx.core.dex.nodes.ClassNode; +import jadx.tests.api.IntegrationTest; + +public class TestCast extends IntegrationTest { + + public static class TestCls { + + byte myByte; + short myShort; + + public void test1(boolean a) { + write(a ? (byte) 0 : 1); + } + + public void test2(boolean a) { + write(a ? 0 : myByte); + } + + public void test3(boolean a) { + write(a ? 0 : Byte.MAX_VALUE); + } + + public void test4(boolean a) { + write(a ? (short) 0 : 1); + } + + public void test5(boolean a) { + write(a ? myShort : 0); + } + + public void test6(boolean a) { + write(a ? Short.MIN_VALUE : 0); + } + + public void write(byte b) { + } + public void write(short b) { + } + } + + @Test + public void test() { + ClassNode cls = getClassNode(TestCls.class); + String code = cls.getCode().toString(); + + assertThat(code, containsString("write(a ? (byte) 0 : 1);")); + assertThat(code, containsString("write(a ? 0 : this.myByte);")); + assertThat(code, containsString("write(a ? 0 : Byte.MAX_VALUE);")); + + assertThat(code, containsString("write(a ? (short) 0 : 1);")); + assertThat(code, containsString("write(a ? this.myShort : 0);")); + assertThat(code, containsString("write(a ? Short.MIN_VALUE : 0);")); + } +} -- GitLab