skylot / jadx

Dex to Java decompiler
Apache License 2.0
41.96k stars 4.9k forks source link

[core] Default switch case lost in endless loop #2351

Closed eybisi closed 5 days ago

eybisi commented 1 week ago

Issue details

if switch is inside endless while loop, (while(true)) default switch branch is always discarded and lost. Following java code:

    public int jadxEndlessSwitch(int r){
        int r0;
        while(true){
            switch(r){
                case 42:
                    r0 = 32;
                    break;
                case 52:
                    r0 = 42;
                    break;
                default:
                    System.out.println("Default switch case");
                    return 1;
            }
            r = r0;
        }
    }

results in:

     /* JADX WARN: Code restructure failed: missing block: B:8:0x0004, code lost:

        java.lang.System.out.println("Default switch case");
     */
    /* JADX WARN: Code restructure failed: missing block: B:9:0x000c, code lost:

        return 1;
     */
    /*
        Code decompiled incorrectly, please refer to instructions dump.
    */
    public int jadxEndlessSwitch(int r) {
        int r0;
        while (true) {
            switch (r) {
                case 42:
                    r0 = 32;
                    break;
                case 52:
                    r0 = 42;
                    break;
            }
            r = r0;
        }
    }

I've attached sample app.

Relevant log output or stacktrace

WARN : Code restructure failed: missing block: B:8:0x0004, code lost:

    java.lang.System.out.println("Default switch case");
 in method: org.abc.obfusactiontests.MainActivity.jadxEndlessSwitch(int):int, file: classes3.dex
WARN : Code restructure failed: missing block: B:9:0x000c, code lost:

    return 1;
 in method: org.abc.obfusactiontests.MainActivity.jadxEndlessSwitch(int):int, file: classes3.dex

Provide sample and class/method full name

app-debug.zip

class : org.abc.obfusactiontests.MainActivity method : jadxEndlessSwitch

Jadx version

dev

skylot commented 1 week ago

@eybisi thanks for test case! Actually, right now I am working on a new approach for break/continue handling (related to #2339), so it affects loops and switches. And I will add your test case into that change, it may take some time though :slightly_smiling_face:

MrIkso commented 1 week ago

vineflower or fernflower handles this case, maybe it's worth looking at how they perform code generation for such cases...

skylot commented 5 days ago

Fixed. Cause of the issue was incorrect checks for empty default case, hope fix will cover all cases. Also, rework mentioned above, not going well and will be postponed, so I made a fix just for this case.