diff --git a/CHANGELOG.md b/CHANGELOG.md index 34cde5a52..207a1f879 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ All notable changes to this project will be documented in this file. - AS2 direct editation - not generating Pop in class header ifs - AS1/2 deobfuscation - ActionRandom fixed for nonpositive numbers - AS1/2 switch statement detection - fixes of default section position +- AS1/2: break on the end of for..in loop ## [11.0.0] - 2018-01-17 ### Added diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/FinalProcessLocalData.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/FinalProcessLocalData.java index 50eecdd4f..6d6cced57 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/FinalProcessLocalData.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/FinalProcessLocalData.java @@ -12,10 +12,13 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash; +import com.jpexs.decompiler.graph.Loop; import java.util.HashSet; +import java.util.List; /** * @@ -24,8 +27,10 @@ import java.util.HashSet; public class FinalProcessLocalData { public final HashSet temporaryRegisters; + public final List loops; - public FinalProcessLocalData() { + public FinalProcessLocalData(List loops) { temporaryRegisters = new HashSet<>(); + this.loops = loops; } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionGraph.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionGraph.java index a8ec73a74..ba3f09202 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionGraph.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionGraph.java @@ -49,6 +49,7 @@ import com.jpexs.decompiler.graph.TranslateStack; import com.jpexs.decompiler.graph.model.BreakItem; import com.jpexs.decompiler.graph.model.ContinueItem; import com.jpexs.decompiler.graph.model.DefaultItem; +import com.jpexs.decompiler.graph.model.IfItem; import com.jpexs.decompiler.graph.model.SwitchItem; import com.jpexs.decompiler.graph.model.WhileItem; import java.util.ArrayList; @@ -171,31 +172,48 @@ public class ActionGraph extends Graph { } while (again); for (int t = 1/*not first*/; t < list.size(); t++) { GraphTargetItem it = list.get(t); + List checkedBody = null; + GraphTargetItem checkedCondition = null; + Loop checkedLoop = null; if (it instanceof WhileItem) { WhileItem wi = (WhileItem) it; - if ((!wi.commands.isEmpty()) && (wi.commands.get(0) instanceof SetTypeActionItem)) { - SetTypeActionItem sti = (SetTypeActionItem) wi.commands.get(0); - if (wi.expression.get(wi.expression.size() - 1) instanceof NeqActionItem) { - NeqActionItem ne = (NeqActionItem) wi.expression.get(wi.expression.size() - 1); - if (ne.rightSide instanceof DirectValueActionItem) { - DirectValueActionItem dv = (DirectValueActionItem) ne.rightSide; - if (dv.value == Null.INSTANCE) { - GraphTargetItem en = list.get(t - 1); - if (en instanceof EnumerateActionItem) { - EnumerateActionItem eti = (EnumerateActionItem) en; - list.remove(t); - wi.commands.remove(0); - list.add(t, new ForInActionItem(null, null, wi.loop, sti.getObject(), eti.object, wi.commands)); - list.remove(t - 1); - t--; + checkedBody = wi.commands; + checkedCondition = wi.expression.get(wi.expression.size() - 1); + checkedLoop = wi.loop; + } else if (it instanceof IfItem) { + IfItem ifi = (IfItem) it; + if (ifi.onFalse.isEmpty()) { + checkedBody = ifi.onTrue; + checkedCondition = ifi.expression; + checkedLoop = null; + } + } + if (checkedBody != null && (!checkedBody.isEmpty()) && (checkedBody.get(0) instanceof SetTypeActionItem)) { + SetTypeActionItem sti = (SetTypeActionItem) checkedBody.get(0); + if (checkedCondition instanceof NeqActionItem) { + NeqActionItem ne = (NeqActionItem) checkedCondition; + if (ne.rightSide instanceof DirectValueActionItem) { + DirectValueActionItem dv = (DirectValueActionItem) ne.rightSide; + if (dv.value == Null.INSTANCE) { + GraphTargetItem en = list.get(t - 1); + if (en instanceof EnumerateActionItem) { + EnumerateActionItem eti = (EnumerateActionItem) en; + list.remove(t); + checkedBody.remove(0); + if (checkedLoop == null) { + checkedLoop = new Loop(localData.loops.size(), null, null); + checkedBody.add(new BreakItem(null, null, checkedLoop.id)); } + list.add(t, new ForInActionItem(null, null, checkedLoop, sti.getObject(), eti.object, checkedBody)); + list.remove(t - 1); + t--; } - } + } } - } + } //Handle for loops at the end: super.finalProcess(list, level, localData, path); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/clauses/ForInActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/clauses/ForInActionItem.java index ad2e4bf53..921dfc9d3 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/clauses/ForInActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/clauses/ForInActionItem.java @@ -12,7 +12,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.action.model.clauses; import com.jpexs.decompiler.flash.SWF; 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 297bf6638..6e445b030 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java @@ -676,7 +676,7 @@ public class Graph { List ret = printGraph(new HashMap<>(), new HashMap<>(), localData, stack, allParts, null, heads.get(0), null, loops, staticOperation, path); processIfs(ret); finalProcessStack(stack, ret, path); - finalProcessAll(ret, 0, new FinalProcessLocalData(), path); + finalProcessAll(ret, 0, new FinalProcessLocalData(loops), path); return ret; } 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 c557b9895..700e78f3f 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript2Test.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript2Test.java @@ -1935,4 +1935,17 @@ public class ActionScript2Test extends ActionScript2TestBase { + "}\r\n" ); } + + @Test + public void frame69_forInBreakTest() { + compareSrc(69, "trace(\"forInBreakTest\");\r\n" + + "var obj = {a:5,b:6,c:7};\r\n" + + "for(var k in obj)\r\n" + + "{\r\n" + + "trace(k);\r\n" + + "break;\r\n" + + "}\r\n" + + "trace(\"after\");\r\n" + ); + } } diff --git a/libsrc/ffdec_lib/testdata/as2/as2.fla b/libsrc/ffdec_lib/testdata/as2/as2.fla index a84106d38..4b38fcd38 100644 Binary files a/libsrc/ffdec_lib/testdata/as2/as2.fla and b/libsrc/ffdec_lib/testdata/as2/as2.fla differ diff --git a/libsrc/ffdec_lib/testdata/as2/as2.swf b/libsrc/ffdec_lib/testdata/as2/as2.swf index 58a2056d8..3b1088827 100644 Binary files a/libsrc/ffdec_lib/testdata/as2/as2.swf and b/libsrc/ffdec_lib/testdata/as2/as2.swf differ