Skip to content

Commit

Permalink
fix: byte to number without cast (#596) (PR #638)
Browse files Browse the repository at this point in the history
  • Loading branch information
asashour authored and skylot committed Apr 29, 2019
1 parent 031582d commit e1dfb4e
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public InvokeType getInvokeType() {
return type;
}

@Override
public MethodInfo getCallMth() {
return mth;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ void setSVar(@NotNull SSAVar sVar) {
}
}

@Override
public String getName() {
if (isThis()) {
return THIS_ARG_NAME;
Expand All @@ -91,6 +92,7 @@ public String getName() {
return sVar.getName();
}

@Override
public void setName(String name) {
if (sVar != null && name != null) {
sVar.setName(name);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
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();
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,22 @@
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
Expand All @@ -23,6 +31,11 @@ public ArgType getType() {
return type;
}

@Override
public RegisterArg getArg() {
return arg;
}

@Override
public boolean equals(Object o) {
if (this == o) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
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;
Expand Down Expand Up @@ -81,7 +82,11 @@ public void visit(MethodNode mth) {
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);
}
Expand Down Expand Up @@ -249,7 +254,7 @@ private ITypeBound makeUseBound(RegisterArg regArg) {
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) {
Expand Down Expand Up @@ -375,4 +380,39 @@ private boolean tryWiderObjects(MethodNode mth, SSAVar var) {
}
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);
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,24 @@

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;
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);"));
Expand Down
20 changes: 20 additions & 0 deletions jadx-core/src/test/smali/conditions/TestBooleanToInt.smali
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
.class public LTestBooleanToInt;
.super Ljava/lang/Object;

.field private showConsent:Z

.method public writeToParcel(LTestBooleanToInt;)V
.locals 0

iget-boolean p1, p0, LTestBooleanToInt;->showConsent:Z

invoke-virtual {p0, p1}, LTestBooleanToInt;->write(I)V

return-void
.end method

.method public write(I)V
.locals 0

return-void
.end method
20 changes: 0 additions & 20 deletions jadx-core/src/test/smali/conditions/TestBooleanToInt2.smali

This file was deleted.

0 comments on commit e1dfb4e

Please sign in to comment.