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

fix: conditions in ternary if (#449) (PR #558)

parent ac1d1a58
......@@ -6,6 +6,7 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import jadx.core.dex.instructions.ArithNode;
import jadx.core.dex.instructions.ArithOp;
......@@ -118,7 +119,7 @@ public final class IfCondition {
case COMPARE:
return new IfCondition(cond.getCompare().invert());
case TERNARY:
return ternary(not(cond.first()), cond.third(), cond.second());
return ternary(cond.first(), not(cond.second()), not(cond.third()));
case NOT:
return cond.first();
case AND:
......@@ -137,6 +138,9 @@ public final class IfCondition {
if (cond.getMode() == Mode.NOT) {
return cond.first();
}
if (cond.getCompare() != null) {
return new IfCondition(cond.compare.invert());
}
return new IfCondition(Mode.NOT, Collections.singletonList(cond));
}
......@@ -281,4 +285,30 @@ public final class IfCondition {
}
return "??";
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof IfCondition)) {
return false;
}
IfCondition other = (IfCondition) obj;
if (mode != other.mode) {
return false;
}
return Objects.equals(other.args, other.args)
&& Objects.equals(compare, other.compare);
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + mode.hashCode();
result = 31 * result + args.hashCode();
result = 31 * result + (compare != null ? compare.hashCode() : 0);
return result;
}
}
......@@ -18,7 +18,7 @@ public class TestTernaryInIf extends IntegrationTest {
}
public int test2(boolean a, boolean b, boolean c) {
return (a ? b : c) ? 1 : 2;
return (!a ? c : b) ? 1 : 2;
}
}
......
package jadx.tests.integration.conditions;
import static jadx.tests.api.utils.JadxMatchers.containsLines;
import static org.hamcrest.MatcherAssert.assertThat;
import org.junit.jupiter.api.Test;
import jadx.core.dex.nodes.ClassNode;
import jadx.tests.api.SmaliTest;
public class TestTernaryInIf2 extends SmaliTest {
public static class TestCls {
private String a;
private String b;
public boolean equals(TestCls other) {
if (this.a == null ? other.a == null : this.a.equals(other.a)) {
if (this.b == null ? other.b == null : this.b.equals(other.b)) {
return true;
}
}
return false;
}
}
@Test
public void test() {
ClassNode cls = getClassNode(TestCls.class);
String code = cls.getCode().toString();
assertThat(code, containsLines(2, "if (this.a != null ? this.a.equals(other.a) : other.a == null) {"));
assertThat(code, containsLines(3, "if (this.b != null ? this.b.equals(other.b) : other.b == null) {"));
assertThat(code, containsLines(4, "return true;"));
assertThat(code, containsLines(2, "return false;"));
}
@Test
public void test2() {
getClassNodeFromSmaliWithPath("conditions", "TestTernaryInIf2");
}
}
.class public LTestTernaryInIf2;
.super Ljava/lang/Object;
# instance fields
.field private a:Ljava/lang/String;
.field private b:Ljava/lang/String;
.field private c:Ljava/lang/String;
# direct methods
.method public constructor <init>()V
.locals 0
.line 10
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
return-void
.end method
# virtual methods
.method public equals(Ljava/lang/Object;)Z
.locals 4
const/4 v0, 0x1
if-ne p0, p1, :cond_0
return v0
:cond_0
const/4 v1, 0x0
if-eqz p1, :cond_a
.line 110
invoke-virtual {p0}, Ljava/lang/Object;->getClass()Ljava/lang/Class;
move-result-object v2
invoke-virtual {p1}, Ljava/lang/Object;->getClass()Ljava/lang/Class;
move-result-object v3
if-eq v2, v3, :cond_1
goto :goto_4
.line 112
:cond_1
check-cast p1, LTestTernaryInIf2;
.line 114
iget-object v2, p0, LTestTernaryInIf2;->a:Ljava/lang/String;
if-eqz v2, :cond_2
iget-object v2, p0, LTestTernaryInIf2;->a:Ljava/lang/String;
iget-object v3, p1, LTestTernaryInIf2;->a:Ljava/lang/String;
invoke-virtual {v2, v3}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v2
if-nez v2, :cond_3
goto :goto_0
:cond_2
iget-object v2, p1, LTestTernaryInIf2;->a:Ljava/lang/String;
if-eqz v2, :cond_3
:goto_0
return v1
.line 116
:cond_3
iget-object v2, p0, LTestTernaryInIf2;->b:Ljava/lang/String;
if-eqz v2, :cond_4
iget-object v2, p0, LTestTernaryInIf2;->b:Ljava/lang/String;
iget-object v3, p1, LTestTernaryInIf2;->b:Ljava/lang/String;
invoke-virtual {v2, v3}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v2
if-nez v2, :cond_5
goto :goto_1
:cond_4
iget-object v2, p1, LTestTernaryInIf2;->b:Ljava/lang/String;
if-eqz v2, :cond_5
:goto_1
return v1
.line 118
:cond_5
iget-object v2, p0, LTestTernaryInIf2;->c:Ljava/lang/String;
if-eqz v2, :cond_6
iget-object v2, p0, LTestTernaryInIf2;->c:Ljava/lang/String;
iget-object v3, p1, LTestTernaryInIf2;->c:Ljava/lang/String;
invoke-virtual {v2, v3}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v2
if-nez v2, :cond_7
return v1
:cond_6
iget-object v2, p1, LTestTernaryInIf2;->c:Ljava/lang/String;
if-eqz v2, :cond_7
.line 120
:cond_7
:cond_8
const/4 v0, 0x0
:goto_3
return v0
:cond_a
:goto_4
return v1
.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