Fixed: #2486 AS Loop in loop producing gotos in some cases

This commit is contained in:
Jindra Petřík
2025-07-13 18:45:54 +02:00
parent 405c9d4475
commit 7bfa09cd98
8 changed files with 148 additions and 6 deletions

View File

@@ -31,6 +31,7 @@ All notable changes to this project will be documented in this file.
- [#2338] AS1/2/3 Obfuscated code - jump to jump handling
- [#1277] AS1/2 Propagate break/continue to avoid loop/switch labels
- [#2483] Editing shape gradient records - RGB vs RGBA
- [#2486] AS Loop in loop producing gotos in some cases
### Changed
- Icon of "Deobfuscation options" menu from pile of pills to medkit
@@ -3917,6 +3918,7 @@ Major version of SWF to XML export changed to 2.
[#2338]: https://www.free-decompiler.com/flash/issues/2338
[#1277]: https://www.free-decompiler.com/flash/issues/1277
[#2483]: https://www.free-decompiler.com/flash/issues/2483
[#2486]: https://www.free-decompiler.com/flash/issues/2486
[#2476]: https://www.free-decompiler.com/flash/issues/2476
[#2404]: https://www.free-decompiler.com/flash/issues/2404
[#1418]: https://www.free-decompiler.com/flash/issues/1418

View File

@@ -111,19 +111,19 @@ public class Graph {
/**
* Debug flag to print all parts
*/
private boolean debugPrintAllParts = false;
private final boolean debugPrintAllParts = false;
/**
* Debug flag to print loop list
*/
private boolean debugPrintLoopList = false;
private final boolean debugPrintLoopList = false;
/**
* Debug flag to print getLoops
*/
private boolean debugGetLoops = false;
private final boolean debugGetLoops = false;
/**
* Debug flag to print decompilation progress (printGraph method)
*/
private boolean debugPrintGraph = false;
private final boolean debugPrintGraph = false;
/**
* Debug flag to not process Ifs
*/
@@ -1600,7 +1600,14 @@ public class Graph {
for (Loop el : loops) {
el.backEdges.clear();
Set<GraphPart> uniqueRefs = new HashSet<>(el.loopContinue.refs);
for (GraphPart r : uniqueRefs) {
loopr: for (GraphPart r : uniqueRefs) {
for (Loop el2 : loops) {
if (el2.phase == 1) {
if (el2.loopContinue == r) {
continue loopr;
}
}
}
if (el.loopContinue.leadsTo(localData, this, code, r, loops, throwStates, true)) {
el.backEdges.add(r);
}
@@ -3208,7 +3215,7 @@ public class Graph {
if (stopPart.get(i) == part) {
isRealStopPart = true;
}
break;
break;
}
}

View File

@@ -1500,6 +1500,44 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile
false);
}
@Test
public void testLoopInLoop() {
decompileMethod("classic_air", "testLoopInLoop", "var i:* = undefined;\r\n"
+ "var a:Boolean = true;\r\n"
+ "var b:Boolean = true;\r\n"
+ "var c:Boolean = true;\r\n"
+ "do\r\n"
+ "{\r\n"
+ "trace(\"A\");\r\n"
+ "for(i = 0; i < 10; i++)\r\n"
+ "{\r\n"
+ "if(!a)\r\n"
+ "{\r\n"
+ "trace(\"B\");\r\n"
+ "if(c)\r\n"
+ "{\r\n"
+ "trace(\"C\");\r\n"
+ "}\r\n"
+ "else\r\n"
+ "{\r\n"
+ "trace(\"D\");\r\n"
+ "if(b)\r\n"
+ "{\r\n"
+ "continue;\r\n"
+ "}\r\n"
+ "trace(\"H\");\r\n"
+ "}\r\n"
+ "if(c)\r\n"
+ "{\r\n"
+ "trace(\"L\");\r\n"
+ "}\r\n"
+ "}\r\n"
+ "}\r\n"
+ "}\r\n"
+ "while(!a);\r\n",
false);
}
@Test
public void testManualConvert() {
decompileMethod("classic_air", "testManualConvert", "trace(\"String(this).length\");\r\n"

View File

@@ -1496,6 +1496,46 @@ public class ActionScript3ClassicDecompileTest extends ActionScript3DecompileTes
false);
}
@Test
public void testLoopInLoop() {
decompileMethod("classic", "testLoopInLoop", "var i:* = undefined;\r\n"
+ "var a:Boolean = true;\r\n"
+ "var b:Boolean = true;\r\n"
+ "for(var c:Boolean = true; true; )\r\n"
+ "{\r\n"
+ "trace(\"A\");\r\n"
+ "for(i = 0; i < 10; i++)\r\n"
+ "{\r\n"
+ "if(!a)\r\n"
+ "{\r\n"
+ "trace(\"B\");\r\n"
+ "if(c)\r\n"
+ "{\r\n"
+ "trace(\"C\");\r\n"
+ "}\r\n"
+ "else\r\n"
+ "{\r\n"
+ "trace(\"D\");\r\n"
+ "if(b)\r\n"
+ "{\r\n"
+ "continue;\r\n"
+ "}\r\n"
+ "trace(\"H\");\r\n"
+ "}\r\n"
+ "if(c)\r\n"
+ "{\r\n"
+ "trace(\"L\");\r\n"
+ "}\r\n"
+ "}\r\n"
+ "}\r\n"
+ "if(a)\r\n"
+ "{\r\n"
+ "break;\r\n"
+ "}\r\n"
+ "}\r\n",
false);
}
@Test
public void testManualConvert() {
decompileMethod("classic", "testManualConvert", "trace(\"String(this).length\");\r\n"

View File

@@ -88,6 +88,7 @@ package
TestInnerFunctionScope;
TestInnerIf;
TestInnerTry;
TestLoopInLoop;
TestLogicalComputing;
TestManualConvert;
TestMetadata;

View File

@@ -0,0 +1,54 @@
package tests
{
public class TestLoopInLoop
{
public function run():*
{
var a:Boolean = true;
var b:Boolean = true;
var c:Boolean = true;
for (;;)
{
trace("A");
for (var i = 0; i < 10; i++)
{
if (a)
{
continue;
}
trace("B");
if (c)
{
trace("C");
}
else
{
trace("D");
if (b)
{
continue;
}
trace("H");
}
if (c)
{
trace("L");
}
}
if (a)
{
break;
}
}
}
}
}