leibnitz27 / cfr

This is the public repository for the CFR Java decompiler
https://www.benf.org/other/cfr
MIT License
2.01k stars 258 forks source link

Variable increment inside expression causes behaviour changes (i.e. array access+increment in loop, comparison+increment in loop, etc...) #249

Closed nbauma109 closed 3 years ago

nbauma109 commented 3 years ago

CFR version

CFR 0.152-SNAPSHOT (bc8d9a2)

Compiler

javac 1.8.0_252

Description

Index variables can be incremented while accessing an array but if that happens in a loop expression, the variable is incremented at each iteration instead of once.

Example

The following program prints character 'a' from the array in an infinite loop (sorry for a dumb example)

public class TestCFR {
    public static void main(String[] args) {
        String s = "a";
        char[] cArray = s.toCharArray();
        int index = -1;
        ++index;
        while (cArray[index] == 'a') {
            System.out.println(cArray[index]);
        }
    }
}

The decompiled output changes the meaning of the program completely. Now the index is incremented at each loop iteration.

public class TestCFR {
    public static void main(String[] stringArray) {
        String string = "a";
        char[] cArray = string.toCharArray();
        int n = -1;
        while (cArray[++n] == 'a') {
            System.out.println(n);
        }
    }
}
nbauma109 commented 3 years ago

The issue is not specific to the array access but rather related to a systematic contraction of expression and variable increment.

Here is another example

public class TestCFR {
    public static void main(final String[] args) {
        int length = args.length;
        --length;
        for (int i = 0; i < length; i++) {
            System.out.println(args[i]);
        }
    }
}

And the decompilation result

public class TestCFR {
    public static void main(String[] stringArray) {
        int n = stringArray.length;
        for (int i = 0; i < --n; ++i) {
            System.out.println(stringArray[i]);
        }
    }
}