fix: handle method arguments in primitive types conversion (#956)
This commit is contained in:
@@ -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)) {
|
||||
|
||||
+3
-9
@@ -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
|
||||
Reference in New Issue
Block a user