jadx icon indicating copy to clipboard operation
jadx copied to clipboard

[core] `enum` is declared as `class`

Open bagipro opened this issue 1 year ago • 4 comments

Hey!

Please check the kotlinx/android/extensions/CacheImplementation.java file:

public final class CacheImplementation {
    SPARSE_ARRAY,
    HASH_MAP,
    NO_CACHE;

It's declared as class, but should be declared as enum

APK: https://drive.google.com/file/d/1NEIPWFwukzv1BgJDHpaqKZAznMf25lqW/view?usp=sharing

bagipro avatar Jul 31 '23 17:07 bagipro

Can i work on this issue?

pernelkanic avatar Feb 05 '24 13:02 pernelkanic

@pernelkanic you can try :+1: I hope you will be able to fix the root cause for this issue:

/* JADX WARN: Failed to restore enum class, 'enum' modifier and super class removed */
/* JADX WARN: Enum visitor error
jadx.core.utils.exceptions.JadxRuntimeException: Can't remove SSA var: r0v1 kotlinx.android.extensions.CacheImplementation, still in use, count: 1, list:
  (r0v1 kotlinx.android.extensions.CacheImplementation) from 0x002c: SPUT (r0v1 kotlinx.android.extensions.CacheImplementation) (LINE:45) kotlinx.android.extensions.CacheImplementation.DEFAULT kotlinx.android.extensions.CacheImplementation
	at jadx.core.utils.InsnRemover.removeSsaVar(InsnRemover.java:152)
	at jadx.core.utils.InsnRemover.unbindResult(InsnRemover.java:117)
	at jadx.core.utils.InsnRemover.lambda$unbindInsns$1(InsnRemover.java:89)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
	at jadx.core.utils.InsnRemover.unbindInsns(InsnRemover.java:88)
	at jadx.core.utils.InsnRemover.removeAllAndUnbind(InsnRemover.java:239)
	at jadx.core.dex.visitors.EnumVisitor.convertToEnum(EnumVisitor.java:180)
	at jadx.core.dex.visitors.EnumVisitor.visit(EnumVisitor.java:100)
 */

skylot avatar Feb 05 '24 19:02 skylot

The allmatcher function in removeSsaVar method appears to be the source of the issue , as it compares list elements and predicate test elements, returning false and resulting in JadxRuntimeException.

pernelkanic avatar Feb 06 '24 16:02 pernelkanic

Well, most of removeSsaVar method code are checks to make sure we can safely remove variable. In this case, removed variable still used in not removed code, so this is a root cause. I commit a simple test case to simplify debug and fix, check 5b87931 in issue-1973 branch:

public enum Mode {
	FIRST,
	SECOND,
	THIRD;

	private static final Mode DEFAULT = THIRD;
}

Here DEFAULT field initialized using enum field, and in class init method these fields use same variable (mode), so removing that variable will break init code:

static {
	...
	Mode mode = new Mode("THIRD", 2);
	THIRD = mode;
	$VALUES = $values();
	DEFAULT = mode;
}

To fix this, I suggest replacing that variable in DEFAULT field init with sget of references enum field. I made similar replace here: https://github.com/skylot/jadx/blob/8e7ffc8ddb36df052e5fe80c7a777217ee5bce8a/jadx-core/src/main/java/jadx/core/dex/visitors/EnumVisitor.java#L468

skylot avatar Feb 06 '24 18:02 skylot