diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b21d1475..484c77b3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -73,6 +73,7 @@ All notable changes to this project will be documented in this file. - AS1/2 ActionStringExtract incorrectly decompiled as String.substr instead of substring global function - [#2516] AS1/2 Renaming of identifiers not setting function length correctly - AS1/2 Renaming of identifiers must not rename integer array offsets +- [#2517] Loop break detection problems in some cases ### Changed - Icon of "Deobfuscation options" menu from pile of pills to medkit @@ -3985,6 +3986,7 @@ Major version of SWF to XML export changed to 2. [#2511]: https://www.free-decompiler.com/flash/issues/2511 [#2515]: https://www.free-decompiler.com/flash/issues/2515 [#2516]: https://www.free-decompiler.com/flash/issues/2516 +[#2517]: https://www.free-decompiler.com/flash/issues/2517 [#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 diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java index 4320541e9..fb1c29516 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java @@ -2656,6 +2656,7 @@ public class Graph { currentLoop = null; if (isLoop) { currentLoop = new Loop(loops.size(), part, null); + currentLoop.stopParts = stopPart == null ? new ArrayList<>() : stopPart; currentLoop.phase = 1; loops.add(currentLoop); } @@ -2803,6 +2804,29 @@ public class Graph { } + + //When some of breakcandidates pass through current stoppart, + //Remove other candidantes. + if (!currentLoop.stopParts.isEmpty()) { + List bcsLeft = new ArrayList<>(); + for (int c = 0; c < currentLoop.breakCandidates.size(); c++) { + GraphPart cand = currentLoop.breakCandidates.get(c); + GraphPart sp = currentLoop.stopParts.get(currentLoop.stopParts.size() - 1); + if (cand == sp || cand.leadsTo(localData, this, code, sp, new ArrayList<>() /*ingore existing loop states*/, throwStates, false /* ?? */)) { + bcsLeft.add(c); + } + } + + if (!bcsLeft.isEmpty()) { + for (int c = currentLoop.breakCandidates.size() - 1; c >= 0; c--) { + if (!bcsLeft.contains(c)) { + currentLoop.breakCandidates.remove(c); + currentLoop.breakCandidatesLevels.remove(c); + } + } + } + } + do { found = null; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Loop.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Loop.java index 8849bccc2..72110c98f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Loop.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Loop.java @@ -87,6 +87,11 @@ public class Loop implements Serializable { * Break candidates are locked */ public int breakCandidatesLocked = 0; + + /** + * Stop parts before entering the loop + */ + public List stopParts = new ArrayList<>(); /** * Constructs a loop diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript2Test.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript2Test.java index d56500334..37f0a898b 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript2Test.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript2Test.java @@ -2562,5 +2562,51 @@ public class ActionScript2Test extends ActionScript2TestBase { + "}\r\n" ); } + + @Test + public void frame95_breakDetectionTest() { + compareSrc(95, "function myFunction(item)\r\n" + + "{\r\n" + + "var _loc2_;\r\n" + + "var _loc4_;\r\n" + + "if(!isNaN(item))\r\n" + + "{\r\n" + + "_loc2_ = [1,2,3];\r\n" + + "for(var _loc3_ in _loc2_)\r\n" + + "{\r\n" + + "switch(_loc3_)\r\n" + + "{\r\n" + + "case \"A\":\r\n" + + "if(item == \"a\")\r\n" + + "{\r\n" + + "return true;\r\n" + + "}\r\n" + + "case \"B\":\r\n" + + "if(item == \"b\")\r\n" + + "{\r\n" + + "return true;\r\n" + + "}\r\n" + + "case \"C\":\r\n" + + "if(item == \"c\")\r\n" + + "{\r\n" + + "return true;\r\n" + + "}\r\n" + + "case \"D\":\r\n" + + "if(item == \"d\")\r\n" + + "{\r\n" + + "return true;\r\n" + + "}\r\n" + + "}\r\n" + + "}\r\n" + + "}\r\n" + + "else\r\n" + + "{\r\n" + + "trace(\"item is nan\");\r\n" + + "}\r\n" + + "return false;\r\n" + + "}\r\n" + + "trace(\"breakDetectionTest\");\r\n" + ); + } //--FRAMES-END-- } diff --git a/libsrc/ffdec_lib/testdata/as2/as2.swf b/libsrc/ffdec_lib/testdata/as2/as2.swf index 6006adea4..7cba80eef 100644 Binary files a/libsrc/ffdec_lib/testdata/as2/as2.swf and b/libsrc/ffdec_lib/testdata/as2/as2.swf differ diff --git a/libsrc/ffdec_lib/testdata/as2/as2/DOMDocument.xml b/libsrc/ffdec_lib/testdata/as2/as2/DOMDocument.xml index d47205626..3175ac93c 100644 --- a/libsrc/ffdec_lib/testdata/as2/as2/DOMDocument.xml +++ b/libsrc/ffdec_lib/testdata/as2/as2/DOMDocument.xml @@ -31,9 +31,9 @@ - + - + @@ -771,9 +771,9 @@ +!3054 7490[3050 7494 3050 7457!3050 7457[3050 7441 3159 7239!3159 7239[3270 7033 3327 6947!3327 6947[3353 6908 3412 6794!3412 6794[3470 6682 3500 6639!3500 6639[3602 6491 3649 6692!3649 6692|3713 6670!3713 6670[3760 6655 3782 6655!3782 + 6655[3942 6655 3985 6781!3985 6781[4007 6844 3996 6914!3996 6914[3996 6948 3999 6995!3999 6995[4000 7031 3993 7054!3993 7054[3976 7106 3860 7224!3860 7224[3847 7237 3741 7292!3741 7292[3638 7346 3616 7372!3616 7372[3594 7396 3511 7442 +!3511 7442[3435 7483 3427 7483!3427 7483[3409 7483 3407 7468!3407 7468[3405 7453 3386 7453!3386 7453[3361 7468 3330 7483!3330 7483[3270 7512 3235 7512!3235 7512[3220 7512 3156 7501!3156 7501[3091 7490 3054 7490"/> + @@ -3478,6 +3478,53 @@ switch(test) case 3: trace("B"); } +]]> + + + + + + diff --git a/libsrc/ffdec_lib/testdata/as2/as2/LIBRARY/NineSlice.xml b/libsrc/ffdec_lib/testdata/as2/as2/LIBRARY/NineSlice.xml index cea1a482b..72532e16b 100644 --- a/libsrc/ffdec_lib/testdata/as2/as2/LIBRARY/NineSlice.xml +++ b/libsrc/ffdec_lib/testdata/as2/as2/LIBRARY/NineSlice.xml @@ -37,30 +37,27 @@ - - - - + + + + + + + + + - - - - - diff --git a/libsrc/ffdec_lib/testdata/as2/as2/LIBRARY/blue.xml b/libsrc/ffdec_lib/testdata/as2/as2/LIBRARY/blue.xml index f59b98d61..960671973 100644 --- a/libsrc/ffdec_lib/testdata/as2/as2/LIBRARY/blue.xml +++ b/libsrc/ffdec_lib/testdata/as2/as2/LIBRARY/blue.xml @@ -36,8 +36,8 @@ trace("init_blue"); - + diff --git a/libsrc/ffdec_lib/testdata/as2/as2/META-INF/metadata.xml b/libsrc/ffdec_lib/testdata/as2/as2/META-INF/metadata.xml index cc69783f7..9798438a6 100644 --- a/libsrc/ffdec_lib/testdata/as2/as2/META-INF/metadata.xml +++ b/libsrc/ffdec_lib/testdata/as2/as2/META-INF/metadata.xml @@ -5,8 +5,8 @@ xmlns:xmp="http://ns.adobe.com/xap/1.0/"> Adobe Flash CS4 Professional 2010-08-03T10:48:58+02:00 - 2025-07-21T09:57:55-07:00 - 2025-07-21T09:57:55-07:00 + 2025-08-20T13:44:47-07:00 + 2025-08-20T13:44:47-07:00 @@ -22,7 +22,7 @@ xmp.did:8DD71700DC9EDF1194ADAC9B23608190 xmp.did:F0EB4FF7CAC3ED11AC9DC078F41E1AA7 - xmp.iid:5606F1423266F01194B1B97CA76F6B16 + xmp.iid:FE548D82067EF0118C3CCBF8FBB9AA8B xmp.did:8DD71700DC9EDF1194ADAC9B23608190 @@ -500,6 +500,12 @@ 2010-08-03T10:48:58+02:00 Adobe Flash Professional CS6 - build 481 + + created + xmp.iid:FE548D82067EF0118C3CCBF8FBB9AA8B + 2010-08-03T10:48:58+02:00 + Adobe Flash Professional CS6 - build 481 + diff --git a/libsrc/ffdec_lib/testdata/as2/as2/bin/SymDepend.cache b/libsrc/ffdec_lib/testdata/as2/as2/bin/SymDepend.cache index 43e15297a..e58d15356 100644 Binary files a/libsrc/ffdec_lib/testdata/as2/as2/bin/SymDepend.cache and b/libsrc/ffdec_lib/testdata/as2/as2/bin/SymDepend.cache differ