fix: preserve original method details in inlined invocation (PR #1049)

This commit is contained in:
Jonas Konrad
2020-12-12 20:08:50 +01:00
committed by GitHub
parent 035fce6191
commit 96dea75bc8
2 changed files with 48 additions and 0 deletions
@@ -7,6 +7,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jadx.core.dex.attributes.AFlag;
import jadx.core.dex.attributes.AType;
import jadx.core.dex.attributes.nodes.MethodInlineAttr;
import jadx.core.dex.info.MethodInfo;
import jadx.core.dex.instructions.InsnType;
@@ -16,6 +17,7 @@ import jadx.core.dex.instructions.args.InsnArg;
import jadx.core.dex.instructions.args.RegisterArg;
import jadx.core.dex.instructions.args.SSAVar;
import jadx.core.dex.nodes.BlockNode;
import jadx.core.dex.nodes.IMethodDetails;
import jadx.core.dex.nodes.InsnNode;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.dex.visitors.typeinference.TypeInferenceVisitor;
@@ -103,9 +105,14 @@ public class InlineMethods extends AbstractVisitor {
}
}
}
IMethodDetails methodDetailsAttr = inlCopy.get(AType.METHOD_DETAILS);
if (!BlockUtils.replaceInsn(mth, block, insn, inlCopy)) {
mth.addWarnComment("Failed to inline method: " + callMth);
}
// replaceInsn replaces the attributes as well, make sure to preserve METHOD_DETAILS
if (methodDetailsAttr != null) {
inlCopy.addAttr(methodDetailsAttr);
}
}
private boolean isAssignNeeded(InsnNode inlineInsn, InvokeNode parentInsn, MethodNode callMthNode) {
@@ -0,0 +1,41 @@
package jadx.tests.integration.invoke;
import org.junit.jupiter.api.Test;
import jadx.tests.api.SmaliTest;
import static jadx.tests.api.utils.JadxMatchers.containsOne;
import static org.hamcrest.MatcherAssert.assertThat;
public class TestCastInOverloadedAccessor extends SmaliTest {
static class X {
void test() {
new Runnable() {
@Override
public void run() {
outerMethod("");
outerMethod("", "");
}
};
}
private void outerMethod(String s) {
}
private void outerMethod(String s, String t) {
}
private void outerMethod(int a) {
}
private void outerMethod(int a, int b) {
}
}
@Test
public void test() {
String code = getClassNode(X.class).getCode().getCodeStr();
assertThat(code, containsOne("outerMethod(\"\")"));
assertThat(code, containsOne("outerMethod(\"\", \"\")"));
}
}