Commit e1dfb4ee authored by Ahmed Ashour's avatar Ahmed Ashour Committed by skylot

fix: byte to number without cast (#596) (PR #638)

parent 031582dd
......@@ -46,6 +46,7 @@ public class InvokeNode extends InsnNode implements CallMthInterface {
return type;
}
@Override
public MethodInfo getCallMth() {
return mth;
}
......
......@@ -81,6 +81,7 @@ public class RegisterArg extends InsnArg implements Named {
}
}
@Override
public String getName() {
if (isThis()) {
return THIS_ARG_NAME;
......@@ -91,6 +92,7 @@ public class RegisterArg extends InsnArg implements Named {
return sVar.getName();
}
@Override
public void setName(String name) {
if (sVar != null && name != null) {
sVar.setName(name);
......
package jadx.core.dex.visitors.typeinference;
import org.jetbrains.annotations.Nullable;
import jadx.core.dex.instructions.args.ArgType;
import jadx.core.dex.instructions.args.RegisterArg;
public interface ITypeBound {
BoundEnum getBound();
ArgType getType();
@Nullable
RegisterArg getArg();
}
......@@ -3,14 +3,22 @@ package jadx.core.dex.visitors.typeinference;
import java.util.Objects;
import jadx.core.dex.instructions.args.ArgType;
import jadx.core.dex.instructions.args.RegisterArg;
public final class TypeBoundConst implements ITypeBound {
private final BoundEnum bound;
private final ArgType type;
private final RegisterArg arg;
public TypeBoundConst(BoundEnum bound, ArgType type) {
this(bound, type, null);
}
public TypeBoundConst(BoundEnum bound, ArgType type, RegisterArg arg) {
this.bound = bound;
this.type = type;
this.arg = arg;
}
@Override
......@@ -24,6 +32,11 @@ public final class TypeBoundConst implements ITypeBound {
}
@Override
public RegisterArg getArg() {
return arg;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
......
......@@ -21,6 +21,7 @@ import jadx.core.dex.instructions.IndexInsnNode;
import jadx.core.dex.instructions.InsnType;
import jadx.core.dex.instructions.PhiInsn;
import jadx.core.dex.instructions.args.ArgType;
import jadx.core.dex.instructions.args.CodeVar;
import jadx.core.dex.instructions.args.InsnArg;
import jadx.core.dex.instructions.args.LiteralArg;
import jadx.core.dex.instructions.args.PrimitiveType;
......@@ -81,7 +82,11 @@ public final class TypeInferenceVisitor extends AbstractVisitor {
resolved = false;
}
}
if (!resolved) {
if (resolved) {
for (SSAVar var : new ArrayList<>(mth.getSVars())) {
processIncompatiblePrimitives(mth, var);
}
} else {
for (SSAVar var : new ArrayList<>(mth.getSVars())) {
tryInsertAdditionalInsn(mth, var);
}
......@@ -249,7 +254,7 @@ public final class TypeInferenceVisitor extends AbstractVisitor {
if (insn == null) {
return null;
}
return new TypeBoundConst(BoundEnum.USE, regArg.getInitType());
return new TypeBoundConst(BoundEnum.USE, regArg.getInitType(), regArg);
}
private boolean tryPossibleTypes(SSAVar var, ArgType type) {
......@@ -375,4 +380,39 @@ public final class TypeInferenceVisitor extends AbstractVisitor {
}
return false;
}
private void processIncompatiblePrimitives(MethodNode mth, SSAVar var) {
if (var.getAssign().getType() == ArgType.BOOLEAN) {
for (ITypeBound bound : var.getTypeInfo().getBounds()) {
if (bound.getBound() == BoundEnum.USE
&& bound.getType().isPrimitive() && bound.getType() != ArgType.BOOLEAN) {
InsnNode insn = bound.getArg().getParentInsn();
if (insn.getType() == InsnType.CAST) {
continue;
};
IndexInsnNode castNode = new IndexInsnNode(InsnType.CAST, bound.getType(), 1);
castNode.addArg(bound.getArg());
castNode.setResult(InsnArg.reg(bound.getArg().getRegNum(), bound.getType()));
SSAVar newVar = mth.makeNewSVar(castNode.getResult().getRegNum(), castNode.getResult());
CodeVar codeVar = new CodeVar();
codeVar.setType(bound.getType());
newVar.setCodeVar(codeVar);
newVar.getTypeInfo().setType(bound.getType());
for (int i = insn.getArgsCount() - 1; i >= 0; i--) {
if (insn.getArg(i) == bound.getArg()) {
insn.setArg(i, castNode.getResult().duplicate());
break;
}
}
BlockNode blockNode = BlockUtils.getBlockByInsn(mth, insn);
List<InsnNode> insnList = blockNode.getInstructions();
insnList.add(insnList.indexOf(insn), castNode);
}
}
}
}
}
......@@ -5,11 +5,10 @@ import static org.hamcrest.Matchers.containsString;
import org.junit.jupiter.api.Test;
import jadx.NotYetImplemented;
import jadx.core.dex.nodes.ClassNode;
import jadx.tests.api.SmaliTest;
public class TestBooleanToInt2 extends SmaliTest {
public class TestBooleanToInt extends SmaliTest {
/**
private boolean showConsent;
......@@ -17,14 +16,13 @@ public class TestBooleanToInt2 extends SmaliTest {
public void write(int b) {
}
public void writeToParcel(TestBooleanToInt2 testBooleanToInt2) {
testBooleanToInt2.write(this.showConsent ? 1 : 0);
public void writeToParcel(TestBooleanToInt testBooleanToInt) {
testBooleanToInt.write(this.showConsent ? 1 : 0);
}
*/
@Test
@NotYetImplemented
public void test() {
ClassNode cls = getClassNodeFromSmaliWithPath("conditions", "TestBooleanToInt2");
ClassNode cls = getClassNodeFromSmaliWithPath("conditions", "TestBooleanToInt");
String code = cls.getCode().toString();
assertThat(code, containsString("write(this.showConsent ? 1 : 0);"));
......
.class public LTestBooleanToInt2;
.class public LTestBooleanToInt;
.super Ljava/lang/Object;
.field private showConsent:Z
.method public writeToParcel(LTestBooleanToInt2;)V
.method public writeToParcel(LTestBooleanToInt;)V
.locals 0
iget-boolean p1, p0, LTestBooleanToInt2;->showConsent:Z
iget-boolean p1, p0, LTestBooleanToInt;->showConsent:Z
invoke-virtual {p0, p1}, LTestBooleanToInt2;->write(I)V
invoke-virtual {p0, p1}, LTestBooleanToInt;->write(I)V
return-void
.end method
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment