Skip to content

Commit

Permalink
fix: add primitive cast in ternary for byte and short (PR #601)
Browse files Browse the repository at this point in the history
  • Loading branch information
asashour authored and skylot committed Apr 15, 2019
1 parent bcfed5b commit 632cc3e
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 0 deletions.
21 changes: 21 additions & 0 deletions jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,7 @@ private void makeTernary(TernaryInsn insn, CodeWriter code, Set<Flags> state) th
} else {
condGen.wrap(code, insn.getCondition());
code.add(" ? ");
addCastIfNeeded(code, first, second);
addArg(code, first, false);
code.add(" : ");
addArg(code, second, false);
Expand All @@ -871,6 +872,26 @@ private void makeTernary(TernaryInsn insn, CodeWriter code, Set<Flags> state) th
}
}

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<Flags> state) throws CodegenException {
if (insn.contains(AFlag.ARITH_ONEARG)) {
makeArithOneArg(insn, code);
Expand Down
Original file line number Diff line number Diff line change
@@ -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);"));
}
}

0 comments on commit 632cc3e

Please sign in to comment.