fix: check args of inlined insns on reorder (#1919)

This commit is contained in:
Skylot 2023-06-19 15:05:06 +01:00
parent 2aa7438346
commit 6620e650ef
No known key found for this signature in database
GPG Key ID: 1E23F5B52567AA39
2 changed files with 65 additions and 12 deletions

View File

@ -13,6 +13,7 @@ import jadx.core.dex.instructions.args.RegisterArg;
import jadx.core.dex.instructions.mods.TernaryInsn;
import jadx.core.dex.nodes.InsnNode;
import jadx.core.utils.EmptyBitSet;
import jadx.core.utils.Utils;
import jadx.core.utils.exceptions.JadxRuntimeException;
final class ArgsInfo {
@ -62,6 +63,27 @@ final class ArgsInfo {
return args;
}
public BitSet getArgsSet() {
if (args.isEmpty() && Utils.isEmpty(wrappedInsns)) {
return EmptyBitSet.EMPTY;
}
BitSet set = new BitSet();
fillArgsSet(set);
return set;
}
private void fillArgsSet(BitSet set) {
for (RegisterArg arg : args) {
set.set(arg.getRegNum());
}
List<ArgsInfo> wrapList = wrappedInsns;
if (wrapList != null) {
for (ArgsInfo wrappedInsn : wrapList) {
wrappedInsn.fillArgsSet(set);
}
}
}
public WrapInfo checkInline(int assignPos, RegisterArg arg) {
if (assignPos >= inlineBorder || !canMove(assignPos, inlineBorder)) {
return null;
@ -80,18 +102,9 @@ final class ArgsInfo {
if (start > to) {
throw new JadxRuntimeException("Invalid inline insn positions: " + start + " - " + to);
}
BitSet movedSet;
List<RegisterArg> movedArgs = startInfo.getArgs();
if (movedArgs.isEmpty()) {
if (startInfo.insn.isConstInsn()) {
return true;
}
movedSet = EmptyBitSet.EMPTY;
} else {
movedSet = new BitSet();
for (RegisterArg arg : movedArgs) {
movedSet.set(arg.getRegNum());
}
BitSet movedSet = startInfo.getArgsSet();
if (movedSet == EmptyBitSet.EMPTY && startInfo.insn.isConstInsn()) {
return true;
}
boolean canReorder = startInfo.canReorder();
for (int i = start; i < to; i++) {

View File

@ -0,0 +1,40 @@
package jadx.tests.integration.code;
import org.junit.jupiter.api.Test;
import jadx.tests.api.IntegrationTest;
import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
public class TestArrayAccessReorder extends IntegrationTest {
public static class TestCls {
public int[] test(int[] arr) {
int len = arr.length;
int[] result = new int[len];
int i = 0;
int k = len;
while (k != 0) {
int v = arr[i];
k--;
int t = -v;
i++;
result[k] = t * 5;
}
return result;
}
public void check() {
assertThat(test(new int[] { 1, 2, 3 })).isEqualTo(new int[] { -15, -10, -5 });
}
}
@Test
public void test() {
noDebugInfo();
getArgs().setRawCFGOutput(true);
assertThat(getClassNode(TestCls.class))
.code()
.containsOne("i++");
}
}