darknesswind / NutCracker

fork from DamianXVI's squirrel decompiler
22 stars 11 forks source link

do/while loop detection is faulty #26

Open AdamMil opened 5 years ago

AdamMil commented 5 years ago

If a while loop contains a continue statement, NutCracker may misinterpret the loop as a do/while loop. For example, take this code:

local i,x
while(true)
{
  if(x) continue;
  i++;
}

If you compile and decompile it, you get this:

do
{
    local i;
    local x;
    // [002]  OP_JZ             4      4    0    0
}
while (x);
i++;

The problem is that PreprocessDoWhileInfo sees the backwards jump from the conditional continue statement and thinks that's the end of a do/while loop and it gets decompiled that way even though later instructions wouldn't make sense if it was a do/while loop.

The right fix is probably to rewrite NutCracker to do a proper basic block analysis rather than just looking for patterns in the instruction stream, but a hacky fix could be to abort do/while loop decompilation and retry as a non-do/while loop if NutCracker gets into a situation it doesn't understand.