leibnitz27 / cfr

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

CFR may reverse the execution order of statements inside a loop, which may lead to wrong execution results #304

Open AIRTEspresso opened 2 years ago

AIRTEspresso commented 2 years ago

CFR version

CFR version: 0.152

Compiler

Java openJDK, version: 11.0.13

Description

Hi! I was doing some research work on CFR, and I really like this word as CFR is quite useful and can generation high-quality code from java bytecode artifacts. However, recently I found several cases that the code generated by CFR gave different execution results compared with the source code. Here is the first one: in the source code, the 'iMeth()' is called before 'iArrFld[i]+= instanceCount', which is reversed in the code generated by CFR, and it is harmful because 'instanceCount' is assigned in 'iMeth()'. The total case is available at error example and I hope it can be helpful.

Example

The source code:

    void mainTest(){
        int i , i1 = 173 , i2 = 1;
        for(i = 149; i > 7; i -= 2){
            i1 <<= iMeth();
            iArrFld[i]+= instanceCount;
            i2 -= i1;
            iArrFld[i - 1]= i;
        }
        System.out.println("the sum of iArrFld is :" + checkSum(iArrFld));
    }
    int iMeth() {
        this.instanceCount = 115L;
        return 12;
    }

The code decompiled by CFR:

    void mainTest() {
        int n = 173;
        int n2 = 1;
        for (int i = 149; i > 7; i -= 2) {
            int n3 = i;
            this.iArrFld[n3] = (int)((long)this.iArrFld[n3] + this.instanceCount);
            n2 -= (n <<= this.iMeth());
            this.iArrFld[i - 1] = i;
        }
        System.out.println("the sum of iArrFld is :" + this.checkSum(this.iArrFld));
    }
    int iMeth() {
        this.instanceCount = 115L;
        return 12;
    }