diff --git a/CHANGELOG.md b/CHANGELOG.md index a919b1fad..87c3a48ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +### Fixed +- [#2636] ActionScript - Incorrect always-break detection causing insertion of while(true) +- [#2636] ActionScript 3 - Incorrect switch detection ## [25.1.0] - 2026-02-17 ### Added diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java index ce871126d..7cd6aee75 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java @@ -1905,38 +1905,39 @@ public class AVM2Graph extends Graph { //determine whether local register are on left or on right side of === operator // -1 = there's no register, // -2 = there are mixed registers, + // -3 = there is missing register in some cases // N = there is always register number N int leftReg = -1; int rightReg = -1; for (int cv = 0; cv < caseValuesMapLeft.size(); cv++) { - if (caseValuesMapLeft.get(cv) instanceof LocalRegAVM2Item) { + if (leftReg != -3 && caseValuesMapLeft.get(cv) instanceof LocalRegAVM2Item) { int reg = ((LocalRegAVM2Item) caseValuesMapLeft.get(cv)).regIndex; if (leftReg == -1) { leftReg = reg; - } else { - if (leftReg != reg) { - leftReg = -2; - } + } else if (leftReg != reg) { + leftReg = -2; } + } else { + leftReg = -3; } - if (caseValuesMapRight.get(cv) instanceof LocalRegAVM2Item) { + if (rightReg != -3 && caseValuesMapRight.get(cv) instanceof LocalRegAVM2Item) { int reg = ((LocalRegAVM2Item) caseValuesMapRight.get(cv)).regIndex; if (rightReg == -1) { rightReg = reg; - } else { - if (rightReg != reg) { - rightReg = -2; - } + } else if (rightReg != reg) { + rightReg = -2; } + } else { + rightReg = -3; } } List otherSide = new ArrayList<>(); - if (leftReg > 0) { + if (leftReg >= 0) { switchedObject = new LocalRegAVM2Item(null, null, leftReg, null, TypeItem.UNBOUNDED /*?*/); caseValuesMap = caseValuesMapRight; otherSide = caseValuesMapLeft; - } else if (rightReg > 0) { + } else if (rightReg >= 0) { switchedObject = new LocalRegAVM2Item(null, null, rightReg, null, TypeItem.UNBOUNDED /*?*/); otherSide = caseValuesMapRight; } 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 f62a71fec..8b34fbeaf 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java @@ -3865,12 +3865,15 @@ public class Graph { /* Detect forward jumps (breaks) in always-break loops. - FIXME!!! */ if (localData.secondPassData != null) { if (next != null) { Set ig = new HashSet<>(); + Set backEdges = new HashSet<>(); for (Loop el : loops) { + for (GraphPart be : el.backEdges) { + backEdges.add(new GraphPartEdge(be, el.loopContinue)); + } if (el.phase == 1) { if (el.loopContinue != null) { ig.add(el.loopContinue); @@ -3891,12 +3894,17 @@ public class Graph { if (p == part) { continue; } - for (GraphPart r : p.refs) { - // #2636, it has no test - if (!part.leadsTo(localData, this, code, r, loops, throwStates)) { - //System.err.println("Part " + part + " do not lead"); + for (GraphPart r : p.refs) { + // #2636 + GraphPartEdge edge = new GraphPartEdge(r, p); + if (backEdges.contains(edge)) { continue; } + // also #2636 + if (!part.leadsTo(localData, this, code, r, loops, throwStates)) { + continue; + } + if (r == part) { continue; }