From 7f3bd8c6681f391abc336389483fed638c01decd Mon Sep 17 00:00:00 2001 From: Skylot Date: Mon, 24 Apr 2023 20:35:11 +0100 Subject: [PATCH] fix: additional checks for primitive deboxing (#1838) --- .../core/dex/visitors/DeboxingVisitor.java | 10 +++- .../integration/others/TestDeboxing5.java | 50 +++++++++++++++++++ 2 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 jadx-core/src/test/java/jadx/tests/integration/others/TestDeboxing5.java diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/DeboxingVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/DeboxingVisitor.java index fa8059b8f..ff31114c0 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/DeboxingVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/DeboxingVisitor.java @@ -99,7 +99,7 @@ public class DeboxingVisitor extends AbstractVisitor { } arg.setType(primitiveType); boolean forbidInline; - if (canChangeTypeToPrimitive(resArg)) { + if (canChangeTypeToPrimitive(resArg, boxType)) { resArg.setType(primitiveType); forbidInline = false; } else { @@ -132,7 +132,7 @@ public class DeboxingVisitor extends AbstractVisitor { return false; } - private boolean canChangeTypeToPrimitive(RegisterArg arg) { + private boolean canChangeTypeToPrimitive(RegisterArg arg, ArgType boxType) { for (SSAVar ssaVar : arg.getSVar().getCodeVar().getSsaVars()) { if (ssaVar.isTypeImmutable()) { return false; @@ -148,6 +148,12 @@ public class DeboxingVisitor extends AbstractVisitor { return false; } } + ArgType initType = assignInsn.getResult().getInitType(); + if (initType.isObject() && !initType.equals(boxType)) { + // some of related vars have another object type + return false; + } + for (RegisterArg useArg : ssaVar.getUseList()) { InsnNode parentInsn = useArg.getParentInsn(); if (parentInsn == null) { diff --git a/jadx-core/src/test/java/jadx/tests/integration/others/TestDeboxing5.java b/jadx-core/src/test/java/jadx/tests/integration/others/TestDeboxing5.java new file mode 100644 index 000000000..53c5f75dc --- /dev/null +++ b/jadx-core/src/test/java/jadx/tests/integration/others/TestDeboxing5.java @@ -0,0 +1,50 @@ +package jadx.tests.integration.others; + +import jadx.tests.api.IntegrationTest; +import jadx.tests.api.extensions.profiles.TestProfile; +import jadx.tests.api.extensions.profiles.TestWithProfiles; + +import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat; + +public class TestDeboxing5 extends IntegrationTest { + + @SuppressWarnings("WrapperTypeMayBePrimitive") + public static class TestCls { + private static String type; + + public static void test(String[] args) { + Float f = (float) -47.99; + Boolean b = args.length == 0; + Object o = ((b) ? false : f); + call(o); + } + + public static void call(Object o) { + if (o instanceof Boolean) { + type = "Boolean"; + } + if (o instanceof Float) { + type = "Float"; + } + } + + private static void verify(String[] arr, String str) { + type = null; + test(arr); + assertThat(type).isEqualTo(str); + } + + public void check() { + verify(new String[0], "Boolean"); + verify(new String[] { "1" }, "Float"); + } + } + + @TestWithProfiles(TestProfile.D8_J11) + public void test() { + noDebugInfo(); + assertThat(getClassNode(TestCls.class)) + .code() + .doesNotContain("boolean valueOf"); + } +}