fix: handle method arguments in primitive types conversion (#956)

This commit is contained in:
Skylot
2020-08-04 12:26:31 +01:00
parent ae26512601
commit bfd60b733a
5 changed files with 66 additions and 17 deletions
@@ -52,12 +52,8 @@ public class RegisterArg extends InsnArg implements Named {
sVar.setType(newType);
}
public void updateImmutableType(ArgType type) {
if (sVar == null) {
throw new JadxRuntimeException("Unknown SSA variable to update immutable type: " + this);
}
sVar.forceSetType(type);
sVar.getAssign().add(AFlag.IMMUTABLE_TYPE);
public void forceSetInitType(ArgType type) {
this.type = type;
}
@Nullable
@@ -8,7 +8,10 @@ import java.util.Set;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jadx.core.Consts;
import jadx.core.dex.attributes.AFlag;
import jadx.core.dex.attributes.AType;
import jadx.core.dex.attributes.nodes.RegDebugInfoAttr;
@@ -21,6 +24,8 @@ import jadx.core.utils.StringUtils;
import jadx.core.utils.exceptions.JadxRuntimeException;
public class SSAVar {
private static final Logger LOG = LoggerFactory.getLogger(SSAVar.class);
private final int regNum;
private final int version;
@@ -68,8 +73,8 @@ public class SSAVar {
@Nullable
public ArgType getImmutableType() {
if (assign.contains(AFlag.IMMUTABLE_TYPE)) {
return assign.getType();
if (isTypeImmutable()) {
return assign.getInitType();
}
return null;
}
@@ -78,6 +83,17 @@ public class SSAVar {
return assign.contains(AFlag.IMMUTABLE_TYPE);
}
public void markAsImmutable(ArgType type) {
assign.add(AFlag.IMMUTABLE_TYPE);
ArgType initType = assign.getInitType();
if (!initType.equals(type)) {
assign.forceSetInitType(type);
if (Consts.DEBUG_TYPE_INFERENCE) {
LOG.debug("Update immutable type at var {} assign with type: {} previous type: {}", this.toShortString(), type, initType);
}
}
}
public void setType(ArgType type) {
ArgType imType = getImmutableType();
if (imType != null && !imType.equals(type)) {
@@ -803,21 +803,15 @@ public final class TypeInferenceVisitor extends AbstractVisitor {
private static void assignImmutableTypes(MethodNode mth) {
for (SSAVar ssaVar : mth.getSVars()) {
ArgType imType = getSsaImmutableType(ssaVar);
if (imType != null) {
ssaVar.getAssign().updateImmutableType(imType);
ArgType immutableType = getSsaImmutableType(ssaVar);
if (immutableType != null) {
ssaVar.markAsImmutable(immutableType);
}
}
}
@Nullable
private static ArgType getSsaImmutableType(SSAVar ssaVar) {
if (ssaVar.isTypeImmutable()) {
ArgType type = ssaVar.getTypeInfo().getType();
if (type != ArgType.UNKNOWN) {
return type;
}
}
if (ssaVar.getAssign().contains(AFlag.IMMUTABLE_TYPE)) {
return ssaVar.getAssign().getInitType();
}
@@ -0,0 +1,28 @@
package jadx.tests.integration.types;
import org.junit.jupiter.api.Test;
import jadx.tests.api.SmaliTest;
import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
public class TestPrimitiveConversion extends SmaliTest {
// @formatter:off
/*
public void test(long j, boolean z) {
putByte(j, z ? (byte) 1 : (byte) 0);
}
private static void putByte(long j, byte z) {
}
*/
// @formatter:on
@Test
public void test() {
assertThat(getClassNodeFromSmali())
.code()
.doesNotContain("putByte(j, z);")
.containsOne("putByte(j, z ? (byte) 1 : 0);");
}
}
@@ -0,0 +1,15 @@
.class public Ltypes/TestPrimitiveConversion;
.super Ljava/lang/Object;
.method public test(JZ)V
.registers 5
invoke-static {p1, p2, p3}, Ltypes/TestPrimitiveConversion;->putByte(JB)V
return-void
.end method
.method private static putByte(JB)V
.registers 3
return-void
.end method