Commit 41abbb12 authored by Skylot's avatar Skylot

fix: resolve check cast exception in string constructor simplify

parent 89b80900
...@@ -17,6 +17,7 @@ import jadx.core.dex.instructions.ArithNode; ...@@ -17,6 +17,7 @@ import jadx.core.dex.instructions.ArithNode;
import jadx.core.dex.instructions.ArithOp; import jadx.core.dex.instructions.ArithOp;
import jadx.core.dex.instructions.CallMthInterface; import jadx.core.dex.instructions.CallMthInterface;
import jadx.core.dex.instructions.ConstStringNode; import jadx.core.dex.instructions.ConstStringNode;
import jadx.core.dex.instructions.FilledNewArrayNode;
import jadx.core.dex.instructions.IfNode; import jadx.core.dex.instructions.IfNode;
import jadx.core.dex.instructions.IndexInsnNode; import jadx.core.dex.instructions.IndexInsnNode;
import jadx.core.dex.instructions.InsnType; import jadx.core.dex.instructions.InsnType;
...@@ -124,7 +125,7 @@ public class SimplifyVisitor extends AbstractVisitor { ...@@ -124,7 +125,7 @@ public class SimplifyVisitor extends AbstractVisitor {
break; break;
case CONSTRUCTOR: case CONSTRUCTOR:
simplfyConstructor(mth.root(), (ConstructorInsn) insn); simplifyStringConstructor(mth.root(), (ConstructorInsn) insn);
break; break;
default: default:
...@@ -133,42 +134,44 @@ public class SimplifyVisitor extends AbstractVisitor { ...@@ -133,42 +134,44 @@ public class SimplifyVisitor extends AbstractVisitor {
return null; return null;
} }
private static void simplfyConstructor(RootNode root, ConstructorInsn insn) { private static void simplifyStringConstructor(RootNode root, ConstructorInsn insn) {
if (insn.getArgsCount() != 0 if (insn.getCallMth().getDeclClass().getType().equals(ArgType.STRING)
&& insn.getCallMth().getDeclClass().getType().equals(ArgType.STRING)) { && insn.getArgsCount() != 0
InsnArg arg = insn.getArg(0); && insn.getArg(0).isInsnWrap()) {
InsnNode node = arg.isInsnWrap() InsnNode arrInsn = ((InsnWrapArg) insn.getArg(0)).getWrapInsn();
? ((InsnWrapArg) arg).getWrapInsn() if (arrInsn.getType() == InsnType.FILLED_NEW_ARRAY
: insn; && arrInsn.getArgsCount() != 0) {
if (node.getArgsCount() != 0) { ArgType elemType = ((FilledNewArrayNode) arrInsn).getElemType();
ArgType argType = node.getArg(0).getType(); if (elemType == ArgType.BYTE || elemType == ArgType.CHAR) {
if (node.getType() == InsnType.FILLED_NEW_ARRAY int printable = 0;
&& (argType == ArgType.BYTE || argType == ArgType.CHAR)) { byte[] arr = new byte[arrInsn.getArgsCount()];
int printable = 0; for (int i = 0; i < arr.length; i++) {
byte[] arr = new byte[node.getArgsCount()]; InsnArg arrArg = arrInsn.getArg(i);
for (int i = 0; i < arr.length; i++) { if (!arrArg.isLiteral()) {
arr[i] = (byte) ((LiteralArg) node.getArg(i)).getLiteral(); return;
if (NameMapper.isPrintableChar(arr[i])) { }
printable++; arr[i] = (byte) ((LiteralArg) arrArg).getLiteral();
} if (NameMapper.isPrintableChar(arr[i])) {
} printable++;
if (printable >= arr.length - printable) { }
InsnWrapArg wa = new InsnWrapArg(new ConstStringNode(new String(arr))); }
if (insn.getArgsCount() == 1) { if (printable >= arr.length - printable) {
insn.setArg(0, wa); InsnWrapArg wa = new InsnWrapArg(new ConstStringNode(new String(arr)));
} else { if (insn.getArgsCount() == 1) {
MethodInfo mi = MethodInfo.externalMth( insn.setArg(0, wa);
ClassInfo.fromType(root, ArgType.STRING), } else {
"getBytes", MethodInfo mi = MethodInfo.externalMth(
Collections.emptyList(), ClassInfo.fromType(root, ArgType.STRING),
ArgType.array(ArgType.BYTE)); "getBytes",
InvokeNode in = new InvokeNode(mi, InvokeType.VIRTUAL, 1); Collections.emptyList(),
in.addArg(wa); ArgType.array(ArgType.BYTE));
insn.setArg(0, new InsnWrapArg(in)); InvokeNode in = new InvokeNode(mi, InvokeType.VIRTUAL, 1);
} in.addArg(wa);
} insn.setArg(0, new InsnWrapArg(in));
} }
} }
}
}
} }
} }
......
...@@ -83,4 +83,17 @@ public class TestStringConstructor extends IntegrationTest { ...@@ -83,4 +83,17 @@ public class TestStringConstructor extends IntegrationTest {
assertThat(code, containsOne("tag = new String();")); assertThat(code, containsOne("tag = new String();"));
} }
public static class TestClsNegative2 {
public byte b = 32;
public String tag = new String(new byte[] { 31, b });
}
@Test
public void testNegative2() {
ClassNode cls = getClassNode(TestClsNegative2.class);
String code = cls.getCode().toString();
assertThat(code, containsOne("tag = new String(new byte[]{31, this.b});"));
}
} }
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