fix: don't use static vars of mutable LiteralArg class (#1005)
This commit is contained in:
@@ -843,7 +843,7 @@ public class InsnGen {
|
||||
InsnArg first = insn.getArg(0);
|
||||
InsnArg second = insn.getArg(1);
|
||||
ConditionGen condGen = new ConditionGen(this);
|
||||
if (first.equals(LiteralArg.TRUE) && second.equals(LiteralArg.FALSE)) {
|
||||
if (first.isTrue() && second.isFalse()) {
|
||||
condGen.add(code, insn.getCondition());
|
||||
} else {
|
||||
condGen.wrap(code, insn.getCondition());
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package jadx.core.dex.instructions.args;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
@@ -56,7 +58,7 @@ public abstract class InsnArg extends Typed {
|
||||
}
|
||||
|
||||
public static LiteralArg lit(long literal, ArgType type) {
|
||||
return new LiteralArg(literal, type);
|
||||
return LiteralArg.makeWithFixedType(literal, type);
|
||||
}
|
||||
|
||||
public static LiteralArg lit(InsnData insn, ArgType type) {
|
||||
@@ -210,6 +212,22 @@ public abstract class InsnArg extends Typed {
|
||||
return isLiteral() && (((LiteralArg) this)).getLiteral() == 0;
|
||||
}
|
||||
|
||||
public boolean isFalse() {
|
||||
if (isLiteral()) {
|
||||
LiteralArg litArg = (LiteralArg) this;
|
||||
return litArg.getLiteral() == 0 && Objects.equals(litArg.getType(), ArgType.BOOLEAN);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isTrue() {
|
||||
if (isLiteral()) {
|
||||
LiteralArg litArg = (LiteralArg) this;
|
||||
return litArg.getLiteral() == 1 && Objects.equals(litArg.getType(), ArgType.BOOLEAN);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isThis() {
|
||||
return contains(AFlag.THIS);
|
||||
}
|
||||
|
||||
@@ -6,24 +6,37 @@ import jadx.core.utils.exceptions.JadxRuntimeException;
|
||||
|
||||
public final class LiteralArg extends InsnArg {
|
||||
|
||||
public static final LiteralArg TRUE = new LiteralArg(1, ArgType.BOOLEAN);
|
||||
public static final LiteralArg FALSE = new LiteralArg(0, ArgType.BOOLEAN);
|
||||
public static LiteralArg make(long value, ArgType type) {
|
||||
return new LiteralArg(value, type);
|
||||
}
|
||||
|
||||
public static LiteralArg makeWithFixedType(long value, ArgType type) {
|
||||
return new LiteralArg(value, fixLiteralType(value, type));
|
||||
}
|
||||
|
||||
private static ArgType fixLiteralType(long value, ArgType type) {
|
||||
if (value == 0 || type.isTypeKnown() || type.contains(PrimitiveType.LONG) || type.contains(PrimitiveType.DOUBLE)) {
|
||||
return type;
|
||||
}
|
||||
if (value == 1) {
|
||||
return ArgType.NARROW_NUMBERS;
|
||||
}
|
||||
return ArgType.NARROW_NUMBERS_NO_BOOL;
|
||||
}
|
||||
|
||||
public static LiteralArg litFalse() {
|
||||
return new LiteralArg(0, ArgType.BOOLEAN);
|
||||
}
|
||||
|
||||
public static LiteralArg litTrue() {
|
||||
return new LiteralArg(1, ArgType.BOOLEAN);
|
||||
}
|
||||
|
||||
private final long literal;
|
||||
|
||||
public LiteralArg(long value, ArgType type) {
|
||||
if (value != 0) {
|
||||
if (type.isObject()) {
|
||||
throw new JadxRuntimeException("Wrong literal type: " + type + " for value: " + value);
|
||||
} else if (!type.isTypeKnown()
|
||||
&& !type.contains(PrimitiveType.LONG)
|
||||
&& !type.contains(PrimitiveType.DOUBLE)) {
|
||||
if (value != 1) {
|
||||
type = ArgType.NARROW_NUMBERS_NO_BOOL;
|
||||
} else {
|
||||
type = ArgType.NARROW_NUMBERS;
|
||||
}
|
||||
}
|
||||
private LiteralArg(long value, ArgType type) {
|
||||
if (value != 0 && type.isObject()) {
|
||||
throw new JadxRuntimeException("Wrong literal type: " + type + " for value: " + value);
|
||||
}
|
||||
this.literal = value;
|
||||
this.type = type;
|
||||
@@ -33,6 +46,11 @@ public final class LiteralArg extends InsnArg {
|
||||
return literal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setType(ArgType type) {
|
||||
super.setType(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLiteral() {
|
||||
return true;
|
||||
@@ -49,9 +67,7 @@ public final class LiteralArg extends InsnArg {
|
||||
|
||||
@Override
|
||||
public InsnArg duplicate() {
|
||||
LiteralArg copy = new LiteralArg(literal, getType());
|
||||
copy.type = type;
|
||||
return copyCommonParams(copy);
|
||||
return copyCommonParams(new LiteralArg(literal, type));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -4,7 +4,6 @@ import java.util.Collection;
|
||||
|
||||
import jadx.core.dex.instructions.InsnType;
|
||||
import jadx.core.dex.instructions.args.InsnArg;
|
||||
import jadx.core.dex.instructions.args.LiteralArg;
|
||||
import jadx.core.dex.instructions.args.RegisterArg;
|
||||
import jadx.core.dex.nodes.InsnNode;
|
||||
import jadx.core.dex.regions.conditions.IfCondition;
|
||||
@@ -18,7 +17,7 @@ public final class TernaryInsn extends InsnNode {
|
||||
this();
|
||||
setResult(result);
|
||||
|
||||
if (th.equals(LiteralArg.FALSE) && els.equals(LiteralArg.TRUE)) {
|
||||
if (th.isFalse() && els.isTrue()) {
|
||||
// inverted
|
||||
this.condition = IfCondition.invert(condition);
|
||||
addArg(els);
|
||||
|
||||
@@ -39,8 +39,8 @@ public final class Compare {
|
||||
* Change 'a != false' to 'a == true'
|
||||
*/
|
||||
public void normalize() {
|
||||
if (getOp() == IfOp.NE && getB().isLiteral() && getB().equals(LiteralArg.FALSE)) {
|
||||
insn.changeCondition(IfOp.EQ, getA(), LiteralArg.TRUE);
|
||||
if (getOp() == IfOp.NE && getB().isFalse()) {
|
||||
insn.changeCondition(IfOp.EQ, getA(), LiteralArg.litTrue());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -153,7 +153,7 @@ public final class IfCondition extends AttrNode {
|
||||
if (i != null) {
|
||||
return i;
|
||||
}
|
||||
if (c.getOp() == IfOp.EQ && c.getB().isLiteral() && c.getB().equals(LiteralArg.FALSE)) {
|
||||
if (c.getOp() == IfOp.EQ && c.getB().isFalse()) {
|
||||
cond = not(new IfCondition(c.invert()));
|
||||
} else {
|
||||
c.normalize();
|
||||
@@ -234,8 +234,8 @@ public final class IfCondition extends AttrNode {
|
||||
Mode mode = isTrue && arithOp == ArithOp.OR
|
||||
|| !isTrue && arithOp == ArithOp.AND ? Mode.OR : Mode.AND;
|
||||
|
||||
IfNode if1 = new IfNode(op, -1, wrapInsn.getArg(0), LiteralArg.FALSE);
|
||||
IfNode if2 = new IfNode(op, -1, wrapInsn.getArg(1), LiteralArg.FALSE);
|
||||
IfNode if1 = new IfNode(op, -1, wrapInsn.getArg(0), LiteralArg.litFalse());
|
||||
IfNode if2 = new IfNode(op, -1, wrapInsn.getArg(1), LiteralArg.litFalse());
|
||||
return new IfCondition(mode,
|
||||
Arrays.asList(new IfCondition(new Compare(if1)),
|
||||
new IfCondition(new Compare(if2))));
|
||||
|
||||
@@ -253,16 +253,16 @@ public class ModVisitor extends AbstractVisitor {
|
||||
}
|
||||
|
||||
public static TernaryInsn makeBooleanConvertInsn(RegisterArg result, InsnArg castArg, ArgType type) {
|
||||
InsnArg zero = new LiteralArg(0, type);
|
||||
InsnArg zero = LiteralArg.make(0, type);
|
||||
long litVal = 1;
|
||||
if (type == ArgType.DOUBLE) {
|
||||
litVal = DOUBLE_TO_BITS;
|
||||
} else if (type == ArgType.FLOAT) {
|
||||
litVal = FLOAT_TO_BITS;
|
||||
}
|
||||
InsnArg one = new LiteralArg(litVal, type);
|
||||
InsnArg one = LiteralArg.make(litVal, type);
|
||||
|
||||
IfNode ifNode = new IfNode(IfOp.EQ, -1, castArg, LiteralArg.TRUE);
|
||||
IfNode ifNode = new IfNode(IfOp.EQ, -1, castArg, LiteralArg.litTrue());
|
||||
IfCondition condition = IfCondition.fromIfNode(ifNode);
|
||||
return new TernaryInsn(condition, result, one, zero);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ public class EncodedValueUtils {
|
||||
case ENCODED_NULL:
|
||||
return InsnArg.lit(0, ArgType.OBJECT);
|
||||
case ENCODED_BOOLEAN:
|
||||
return Boolean.TRUE.equals(value) ? LiteralArg.TRUE : LiteralArg.FALSE;
|
||||
return Boolean.TRUE.equals(value) ? LiteralArg.litTrue() : LiteralArg.litFalse();
|
||||
case ENCODED_BYTE:
|
||||
return InsnArg.lit((Byte) value, ArgType.BYTE);
|
||||
case ENCODED_SHORT:
|
||||
|
||||
@@ -10,7 +10,6 @@ import jadx.core.dex.instructions.args.LiteralArg;
|
||||
import jadx.core.dex.regions.conditions.Compare;
|
||||
import jadx.core.dex.regions.conditions.IfCondition;
|
||||
|
||||
import static jadx.core.dex.instructions.args.LiteralArg.TRUE;
|
||||
import static jadx.core.dex.regions.conditions.IfCondition.Mode;
|
||||
import static jadx.core.dex.regions.conditions.IfCondition.Mode.AND;
|
||||
import static jadx.core.dex.regions.conditions.IfCondition.Mode.COMPARE;
|
||||
@@ -29,11 +28,11 @@ public class TestIfCondition {
|
||||
}
|
||||
|
||||
private static IfCondition makeSimpleCondition() {
|
||||
return makeCondition(IfOp.EQ, mockArg(), LiteralArg.TRUE);
|
||||
return makeCondition(IfOp.EQ, mockArg(), LiteralArg.litTrue());
|
||||
}
|
||||
|
||||
private static IfCondition makeNegCondition() {
|
||||
return makeCondition(IfOp.NE, mockArg(), LiteralArg.TRUE);
|
||||
return makeCondition(IfOp.NE, mockArg(), LiteralArg.litTrue());
|
||||
}
|
||||
|
||||
private static InsnArg mockArg() {
|
||||
@@ -44,13 +43,13 @@ public class TestIfCondition {
|
||||
public void testNormalize() {
|
||||
// 'a != false' => 'a == true'
|
||||
InsnArg a = mockArg();
|
||||
IfCondition c = makeCondition(IfOp.NE, a, LiteralArg.FALSE);
|
||||
IfCondition c = makeCondition(IfOp.NE, a, LiteralArg.litFalse());
|
||||
IfCondition simp = simplify(c);
|
||||
|
||||
assertThat(simp.getMode(), is(COMPARE));
|
||||
Compare compare = simp.getCompare();
|
||||
assertThat(compare.getA(), is(a));
|
||||
assertThat(compare.getB(), is(TRUE));
|
||||
assertThat(compare.getB(), is(LiteralArg.litTrue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user