From 0fd9a9df2938c1334d4a92a1feb995ad47394f3b Mon Sep 17 00:00:00 2001 From: Skylot Date: Thu, 11 May 2023 18:11:02 +0100 Subject: [PATCH] fix: check for annotations before remove empty default constructor (#1863) --- .editorconfig | 8 ++--- .../jadx/core/dex/visitors/ClassModifier.java | 26 +++++++++------ .../main/java/jadx/core/utils/BlockUtils.java | 3 ++ .../TestDefConstructorWithAnnotation.java | 33 +++++++++++++++++++ 4 files changed, 56 insertions(+), 14 deletions(-) create mode 100644 jadx-core/src/test/java/jadx/tests/integration/others/TestDefConstructorWithAnnotation.java diff --git a/.editorconfig b/.editorconfig index 587056e14..725f175ee 100644 --- a/.editorconfig +++ b/.editorconfig @@ -14,14 +14,14 @@ trim_trailing_whitespace = true [*.java] ij_java_continuation_indent_size = 8 ij_java_use_single_class_imports = true -ij_java_class_count_to_use_import_on_demand = 999 -ij_java_names_count_to_use_import_on_demand = 999 +ij_java_class_count_to_use_import_on_demand = 99 +ij_java_names_count_to_use_import_on_demand = 99 ij_java_packages_to_use_import_on_demand = * [*.kt] ij_kotlin_continuation_indent_size = 8 -ij_kotlin_name_count_to_use_star_import = 999 -ij_kotlin_name_count_to_use_star_import_for_members = 999 +ij_kotlin_name_count_to_use_star_import = 99 +ij_kotlin_name_count_to_use_star_import_for_members = 99 ij_kotlin_packages_to_use_import_on_demand = * [*.yml] diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/ClassModifier.java b/jadx-core/src/main/java/jadx/core/dex/visitors/ClassModifier.java index 563917177..5f893681f 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/ClassModifier.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/ClassModifier.java @@ -8,6 +8,7 @@ import java.util.Map; import java.util.Objects; import jadx.api.plugins.input.data.AccessFlags; +import jadx.api.plugins.input.data.attributes.JadxAttrType; import jadx.core.Consts; import jadx.core.dex.attributes.AFlag; import jadx.core.dex.attributes.AType; @@ -306,19 +307,24 @@ public class ClassModifier extends AbstractVisitor { * Remove public empty constructors (static or default) */ private static void removeEmptyMethods(MethodNode mth) { + if (!mth.getArgRegs().isEmpty()) { + return; + } AccessInfo af = mth.getAccessFlags(); - boolean publicConstructor = af.isConstructor() && af.isPublic(); + boolean publicConstructor = mth.isConstructor() && af.isPublic(); boolean clsInit = mth.getMethodInfo().isClassInit() && af.isStatic(); - if ((publicConstructor || clsInit) && mth.getArgRegs().isEmpty()) { - List bb = mth.getBasicBlocks(); - if (bb == null || bb.isEmpty() || BlockUtils.isAllBlocksEmpty(bb)) { - if (clsInit) { + if (publicConstructor || clsInit) { + if (!BlockUtils.isAllBlocksEmpty(mth.getBasicBlocks())) { + return; + } + if (clsInit) { + mth.add(AFlag.DONT_GENERATE); + } else { + // don't remove default constructor if other constructors exists or constructor has annotations + if (mth.isDefaultConstructor() + && !isNonDefaultConstructorExists(mth) + && !mth.contains(JadxAttrType.ANNOTATION_LIST)) { mth.add(AFlag.DONT_GENERATE); - } else { - // don't remove default constructor if other constructors exists - if (mth.isDefaultConstructor() && !isNonDefaultConstructorExists(mth)) { - mth.add(AFlag.DONT_GENERATE); - } } } } diff --git a/jadx-core/src/main/java/jadx/core/utils/BlockUtils.java b/jadx-core/src/main/java/jadx/core/utils/BlockUtils.java index 2d2a61535..835ddb611 100644 --- a/jadx-core/src/main/java/jadx/core/utils/BlockUtils.java +++ b/jadx-core/src/main/java/jadx/core/utils/BlockUtils.java @@ -981,6 +981,9 @@ public class BlockUtils { } public static boolean isAllBlocksEmpty(List blocks) { + if (Utils.isEmpty(blocks)) { + return true; + } for (BlockNode block : blocks) { if (!block.getInstructions().isEmpty()) { return false; diff --git a/jadx-core/src/test/java/jadx/tests/integration/others/TestDefConstructorWithAnnotation.java b/jadx-core/src/test/java/jadx/tests/integration/others/TestDefConstructorWithAnnotation.java new file mode 100644 index 000000000..307fef6fc --- /dev/null +++ b/jadx-core/src/test/java/jadx/tests/integration/others/TestDefConstructorWithAnnotation.java @@ -0,0 +1,33 @@ +package jadx.tests.integration.others; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.junit.jupiter.api.Test; + +import jadx.tests.api.IntegrationTest; + +import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat; + +public class TestDefConstructorWithAnnotation extends IntegrationTest { + + public static class TestCls { + @AnnotationTest + public TestCls() { + } + + @Target(ElementType.CONSTRUCTOR) + @Retention(RetentionPolicy.RUNTIME) + public @interface AnnotationTest { + } + } + + @Test + public void test() { + assertThat(getClassNode(TestCls.class)) + .code() + .containsOne("@AnnotationTest"); + } +}