Commit 37071dba authored by Skylot's avatar Skylot

fix: use soft checks for objects and arrays in 'if' type listener (#401)

parent 87c12314
......@@ -518,6 +518,14 @@ public abstract class ArgType {
return false;
}
public boolean canBeObject() {
return isObject() || (!isTypeKnown() && contains(PrimitiveType.OBJECT));
}
public boolean canBeArray() {
return isArray() || (!isTypeKnown() && contains(PrimitiveType.ARRAY));
}
public static ArgType convertFromPrimitiveType(PrimitiveType primitiveType) {
switch (primitiveType) {
case BOOLEAN:
......
......@@ -306,7 +306,18 @@ public final class TypeUpdate {
InsnArg firstArg = insn.getArg(0);
InsnArg secondArg = insn.getArg(1);
InsnArg updateArg = firstArg == arg ? secondArg : firstArg;
return updateTypeChecked(updateInfo, updateArg, candidateType);
TypeUpdateResult result = updateTypeChecked(updateInfo, updateArg, candidateType);
if (result == REJECT) {
// soft checks for objects and array - exact type not compared
ArgType updateArgType = updateArg.getType();
if (candidateType.isObject() && updateArgType.canBeObject()) {
return SAME;
}
if (candidateType.isArray() && updateArgType.canBeArray()) {
return SAME;
}
}
return result;
}
private static boolean isAssign(InsnNode insn, InsnArg arg) {
......
package jadx.tests.integration.types;
import org.junit.Test;
import jadx.core.dex.nodes.ClassNode;
import jadx.tests.api.IntegrationTest;
import static jadx.tests.api.utils.JadxMatchers.containsOne;
import static org.hamcrest.Matchers.anyOf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThat;
public class TestConstTypeInference extends IntegrationTest {
public static class TestCls {
private final int a;
public TestCls() {
this(0);
}
public TestCls(int a) {
this.a = a;
}
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj != null) {
if (getClass() == obj.getClass()) {
TestCls other = (TestCls) obj;
return this.a == other.a;
}
}
return false;
}
public void check() {
TestCls seven = new TestCls(7);
assertEquals(seven, seven);
assertNotEquals(seven, null);
TestCls six = new TestCls(6);
assertNotEquals(seven, six);
}
}
@Test
public void test() {
ClassNode cls = getClassNode(TestCls.class);
String code = cls.getCode().toString();
assertThat(code, containsOne("obj == this"));
assertThat(code, anyOf(containsOne("obj == null"), containsOne("obj != null")));
}
@Test
public void test2() {
noDebugInfo();
getClassNode(TestCls.class);
}
}
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