fix: add explicit cast for byte literal in method invoke (#719)
This commit is contained in:
@@ -8,4 +8,9 @@ public interface CallMthInterface {
|
||||
MethodInfo getCallMth();
|
||||
|
||||
RegisterArg getInstanceArg();
|
||||
|
||||
/**
|
||||
* Return offset to match method args from {@link #getCallMth()}
|
||||
*/
|
||||
int getFirstArgOffset();
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ public class InvokeNode extends InsnNode implements CallMthInterface {
|
||||
private final MethodInfo mth;
|
||||
|
||||
public InvokeNode(MethodInfo mth, DecodedInstruction insn, InvokeType type, boolean isRange, int resReg) {
|
||||
super(InsnType.INVOKE, mth.getArgsCount() + (type != InvokeType.STATIC ? 1 : 0));
|
||||
super(InsnType.INVOKE, mth.getArgsCount() + (type == InvokeType.STATIC ? 0 : 1));
|
||||
this.mth = mth;
|
||||
this.type = type;
|
||||
|
||||
@@ -66,6 +66,11 @@ public class InvokeNode extends InsnNode implements CallMthInterface {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFirstArgOffset() {
|
||||
return type == InvokeType.STATIC ? 0 : 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InsnNode copy() {
|
||||
return copyCommonParams(new InvokeNode(mth, type, getArgsCount()));
|
||||
|
||||
@@ -92,6 +92,11 @@ public class ConstructorInsn extends InsnNode implements CallMthInterface {
|
||||
return callType == CallType.SELF;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFirstArgOffset() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSame(InsnNode obj) {
|
||||
if (this == obj) {
|
||||
|
||||
@@ -143,7 +143,7 @@ public class InsnNode extends LineAttrNode {
|
||||
return arg;
|
||||
}
|
||||
|
||||
protected int getArgIndex(InsnArg arg) {
|
||||
public int getArgIndex(InsnArg arg) {
|
||||
int count = getArgsCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (arg == arguments.get(i)) {
|
||||
|
||||
@@ -4,6 +4,8 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import jadx.core.dex.attributes.AFlag;
|
||||
import jadx.core.dex.info.MethodInfo;
|
||||
import jadx.core.dex.instructions.CallMthInterface;
|
||||
import jadx.core.dex.instructions.ConstStringNode;
|
||||
import jadx.core.dex.instructions.IndexInsnNode;
|
||||
import jadx.core.dex.instructions.InsnType;
|
||||
@@ -203,6 +205,10 @@ public class ConstInlineVisitor extends AbstractVisitor {
|
||||
}
|
||||
if (fieldNode != null) {
|
||||
litArg.wrapInstruction(mth, new IndexInsnNode(InsnType.SGET, fieldNode.getFieldInfo(), 0));
|
||||
} else {
|
||||
if (needExplicitCast(useInsn, litArg)) {
|
||||
litArg.add(AFlag.EXPLICIT_PRIMITIVE_TYPE);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!useInsn.replaceArg(arg, constArg.duplicate())) {
|
||||
@@ -214,4 +220,19 @@ public class ConstInlineVisitor extends AbstractVisitor {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean needExplicitCast(InsnNode insn, LiteralArg arg) {
|
||||
if (insn instanceof CallMthInterface) {
|
||||
CallMthInterface callInsn = (CallMthInterface) insn;
|
||||
MethodInfo callMth = callInsn.getCallMth();
|
||||
int offset = callInsn.getFirstArgOffset();
|
||||
int argIndex = insn.getArgIndex(arg);
|
||||
ArgType argType = callMth.getArgumentsTypes().get(argIndex - offset);
|
||||
if (argType.isPrimitive()) {
|
||||
arg.setType(argType);
|
||||
return argType.equals(ArgType.BYTE);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,9 +14,9 @@ public class TestInnerEnums extends IntegrationTest {
|
||||
public static class TestCls {
|
||||
|
||||
public enum Numbers {
|
||||
ONE(1, NumString.ONE), TWO(2, NumString.TWO);
|
||||
ONE((byte) 1, NumString.ONE), TWO((byte) 2, NumString.TWO);
|
||||
|
||||
private final int num;
|
||||
private final byte num;
|
||||
private final NumString str;
|
||||
|
||||
public enum NumString {
|
||||
@@ -33,7 +33,7 @@ public class TestInnerEnums extends IntegrationTest {
|
||||
}
|
||||
}
|
||||
|
||||
Numbers(int n, NumString str) {
|
||||
Numbers(byte n, NumString str) {
|
||||
this.num = n;
|
||||
this.str = str;
|
||||
}
|
||||
@@ -63,7 +63,7 @@ public class TestInnerEnums extends IntegrationTest {
|
||||
ClassNode cls = getClassNode(TestCls.class);
|
||||
String code = cls.getCode().toString();
|
||||
|
||||
assertThat(code, containsOne("ONE(1, NumString.ONE)"));
|
||||
assertThat(code, containsOne("ONE((byte) 1, NumString.ONE)"));
|
||||
assertThat(code, containsOne("ONE(\"one\")"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user