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 8491e341d..84aa0f153 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 @@ -739,7 +739,7 @@ public class AVM2Graph extends Graph { return part; } - private List checkTry(List currentRet, List output, List foundGotos, Map> partCodes, Map partCodePos, AVM2LocalData localData, GraphPart part, List stopPart, List loops, Set allParts, TranslateStack stack, int staticOperation, String path) throws InterruptedException { + private boolean checkTry(List currentRet, List foundGotos, Map> partCodes, Map partCodePos, AVM2LocalData localData, GraphPart part, List stopPart, List loops, Set allParts, TranslateStack stack, int staticOperation, String path) throws InterruptedException { if (localData.parsedExceptions == null) { localData.parsedExceptions = new ArrayList<>(); } @@ -1036,7 +1036,7 @@ public class AVM2Graph extends Graph { } if (!inlinedFinally && catchCommands.isEmpty() && finallyCommands.isEmpty() && tryCommands.isEmpty()) { - return null; + return false; } //remove default assignment to switched register @@ -1046,10 +1046,9 @@ public class AVM2Graph extends Graph { currentRet.remove(currentRet.size() - 1); } - List ret = new ArrayList<>(); if (!inlinedFinally && catchedExceptions.isEmpty() && finallyCommands.isEmpty()) { - ret.addAll(tryCommands); - return ret; + currentRet.addAll(tryCommands); + return true; } @@ -1077,29 +1076,33 @@ public class AVM2Graph extends Graph { tryItem = new TryAVM2Item(subTry.tryCommands, subTry.catchExceptions, subTry.catchCommands, tryItem.finallyCommands, ""); } - ret.add(tryItem); + currentRet.add(tryItem); if (afterPart != null) { if (finallyIndex > -1 && localData.finallyIndicesWithDoublePush.contains(finallyIndex)) { stack.push(new AnyItem()); } - ret.addAll(printGraph(foundGotos, partCodes, partCodePos, localData, stack, allParts, null, afterPart, stopPart, loops, staticOperation, path)); + currentRet.addAll(printGraph(foundGotos, partCodes, partCodePos, localData, stack, allParts, null, afterPart, stopPart, loops, staticOperation, path)); } - return ret; + return true; } - return null; + return false; + } + + @Override + protected boolean checkPartOutput(List currentRet, List foundGotos, Map> partCodes, Map partCodePos, GraphSource code, BaseLocalData localData, Set allParts, TranslateStack stack, GraphPart parent, GraphPart part, List stopPart, List loops, Loop currentLoop, int staticOperation, String path) throws InterruptedException { + AVM2LocalData aLocalData = (AVM2LocalData) localData; + return checkTry(currentRet, foundGotos, partCodes, partCodePos, aLocalData, part, stopPart, loops, allParts, stack, staticOperation, path); } @Override protected List check(List currentRet, List foundGotos, Map> partCodes, Map partCodePos, GraphSource code, BaseLocalData localData, Set allParts, TranslateStack stack, GraphPart parent, GraphPart part, List stopPart, List loops, List output, Loop currentLoop, int staticOperation, String path) throws InterruptedException { List ret = null; - AVM2LocalData aLocalData = (AVM2LocalData) localData; - ret = checkTry(currentRet, output, foundGotos, partCodes, partCodePos, aLocalData, part, stopPart, loops, allParts, stack, staticOperation, path); - if (ret != null) { + /*if (ret != null) { return ret; - } + }*/ //Detect switch if ((part.nextParts.size() == 2) && (!stack.isEmpty()) && (stack.peek() instanceof StrictEqAVM2Item)) { GraphSourceItem switchStartItem = code.get(part.start); 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 20aabebbc..386c66989 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java @@ -914,7 +914,7 @@ public class Graph { if (!onFalse.isEmpty() && ((onFalse.get(onFalse.size() - 1) instanceof BreakItem) || (onFalse.get(onFalse.size() - 1) instanceof ExitItem) - || (onFalse.get(onFalse.size() - 1) instanceof ContinueItem) ) + || (onFalse.get(onFalse.size() - 1) instanceof ContinueItem)) && !(onFalse.get(onFalse.size() - 1) instanceof ScriptEndItem) && (onTrue.isEmpty() || !((onTrue.get(onTrue.size() - 1) instanceof BreakItem) || (onTrue.get(onTrue.size() - 1) instanceof ExitItem) @@ -1444,6 +1444,10 @@ public class Graph { return part.nextParts; } + protected boolean checkPartOutput(List currentRet, List foundGotos, Map> partCodes, Map partCodePos, GraphSource code, BaseLocalData localData, Set allParts, TranslateStack stack, GraphPart parent, GraphPart part, List stopPart, List loops, Loop currentLoop, int staticOperation, String path) throws InterruptedException { + return false; + } + protected List printGraph(List foundGotos, Map> partCodes, Map partCodePos, Set visited, BaseLocalData localData, TranslateStack stack, Set allParts, GraphPart parent, GraphPart part, List stopPart, List loops, List ret, int staticOperation, String path, int recursionLevel) throws InterruptedException { if (Thread.currentThread().isInterrupted()) { throw new InterruptedException(); @@ -1612,25 +1616,11 @@ public class Graph { //****************************DECOMPILING PART************* List output = new ArrayList<>(); - List parts = new ArrayList<>(); - if (part instanceof GraphPartMulti) { - parts = ((GraphPartMulti) part).parts; + if (checkPartOutput(currentRet, foundGotos, partCodes, partCodePos, code, localData, allParts, stack, parent, part, stopPart, loops, currentLoop, staticOperation, path)) { + parseNext = false; } else { - parts.add(part); - /*while (getNextParts(localData, part).size() == 1 && getNextParts(localData, part).get(0).refs.size() == 1) { - if (stopPart.contains(getNextParts(localData, part).get(0))) { //it might be referenced with try statement - break; - } - part = getNextParts(localData, part).get(0); - parts.add(part); - }*/ - } - for (GraphPart p : parts) { - int end = p.end; - int start = p.start; - - output.addAll(code.translatePart(p, localData, stack, start, end, staticOperation, path)); - if ((end >= code.size() - 1) && getNextParts(localData, p).isEmpty()) { + output.addAll(code.translatePart(part, localData, stack, part.start, part.end, staticOperation, path)); + if ((part.end >= code.size() - 1) && getNextParts(localData, part).isEmpty()) { output.add(new ScriptEndItem()); } } @@ -2389,26 +2379,6 @@ public class Graph { return localData; } - protected GraphPart makeMultiPart(GraphPart part) { - List parts = new ArrayList<>(); - do { - parts.add(part); - if (part.nextParts.size() == 1 && part.nextParts.get(0).refs.size() == 1) { - part = part.nextParts.get(0); - } else { - part = null; - } - } while (part != null); - if (parts.size() > 1) { - GraphPartMulti ret = new GraphPartMulti(parts); - ret.refs.addAll(parts.get(0).refs); - ret.nextParts.addAll(parts.get(parts.size() - 1).nextParts); - return ret; - } else { - return parts.get(0); - } - } - protected List getPartItems(GraphPart part) { List ret = new ArrayList<>(); do { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/GraphPartMulti.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/GraphPartMulti.java deleted file mode 100644 index 8f8d7358e..000000000 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/GraphPartMulti.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2010-2021 JPEXS, All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3.0 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ -package com.jpexs.decompiler.graph; - -import java.util.Collections; -import java.util.List; - -/** - * - * @author JPEXS - */ -public class GraphPartMulti extends GraphPart { - - public List parts; - - public GraphPartMulti(List parts) { - super(parts.get(0).start, parts.get(parts.size() - 1).end); - this.parts = parts; - this.path = parts.get(0).path; - } - - @Override - public String toString() { - StringBuilder ret = new StringBuilder(); - ret.append("[multi "); - boolean first = true; - for (GraphPart g : parts) { - if (first) { - first = false; - } else { - ret.append(", "); - } - ret.append(g.toString()); - } - ret.append("]"); - return ret.toString(); - } - - @Override - public int getHeight() { - int ret = 0; - for (GraphPart p : parts) { - ret += p.getHeight(); - } - return ret; - } - - @Override - public int getPosAt(int offset) { - int ofs = 0; - int pos = 0; - for (GraphPart p : parts) { - for (int i = 0; i < p.getHeight(); i++) { - pos = p.start + i; - ofs += 1; - if (ofs == offset) { - return pos; - } - } - } - return -1; - } - - @Override - public List getSubParts() { - return Collections.unmodifiableList(parts); - } -} diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicAirDecompileTest.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicAirDecompileTest.java index 625b722ae..6565c9fec 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicAirDecompileTest.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicAirDecompileTest.java @@ -1150,6 +1150,24 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile false); } + @Test + public void testTryIf() { + decompileMethod("classic_air", "testTryIf", "var a:int = Math.random();\r\n" + + "try\r\n" + + "{\r\n" + + "if(a > 5 && a < 50)\r\n" + + "{\r\n" + + "trace(\"in limits\");\r\n" + + "}\r\n" + + "trace(\"next\");\r\n" + + "}\r\n" + + "catch(e:Error)\r\n" + + "{\r\n" + + "trace(\"in catch\");\r\n" + + "}\r\n", + false); + } + @Test public void testTryReturn() { decompileMethod("classic_air", "testTryReturn", "var i:int = 0;\r\n" diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicDecompileTest.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicDecompileTest.java index f1379e4b8..5e5dc9fe0 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicDecompileTest.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicDecompileTest.java @@ -1139,6 +1139,24 @@ public class ActionScript3ClassicDecompileTest extends ActionScript3DecompileTes false); } + @Test + public void testTryIf() { + decompileMethod("classic", "testTryIf", "var a:int = Math.random();\r\n" + + "try\r\n" + + "{\r\n" + + "if(a > 5 && a < 50)\r\n" + + "{\r\n" + + "trace(\"in limits\");\r\n" + + "}\r\n" + + "trace(\"next\");\r\n" + + "}\r\n" + + "catch(e:Error)\r\n" + + "{\r\n" + + "trace(\"in catch\");\r\n" + + "}\r\n", + false); + } + @Test public void testTryReturn() { decompileMethod("classic", "testTryReturn", "var i:int = 0;\r\n" diff --git a/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.air.swf b/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.air.swf index eae1d8d81..c78efad36 100644 Binary files a/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.air.swf and b/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.air.swf differ diff --git a/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.flex.swf b/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.flex.swf index 0369104d2..8529df168 100644 Binary files a/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.flex.swf and b/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.flex.swf differ diff --git a/libsrc/ffdec_lib/testdata/as3_new/src/Main.as b/libsrc/ffdec_lib/testdata/as3_new/src/Main.as index f8d155dfc..1d638e23d 100644 --- a/libsrc/ffdec_lib/testdata/as3_new/src/Main.as +++ b/libsrc/ffdec_lib/testdata/as3_new/src/Main.as @@ -77,6 +77,7 @@ package TestSwitchDefault; TestTernarOperator; TestTry; + TestTryIf; TestTryReturn; TestTryReturn2; TestUsagesTry; diff --git a/libsrc/ffdec_lib/testdata/as3_new/src/tests/TestTryIf.as b/libsrc/ffdec_lib/testdata/as3_new/src/tests/TestTryIf.as new file mode 100644 index 000000000..1dbe3d828 --- /dev/null +++ b/libsrc/ffdec_lib/testdata/as3_new/src/tests/TestTryIf.as @@ -0,0 +1,23 @@ +package tests +{ + + public class TestTryIf + { + public function run():* + { + var a:int = Math.random(); + try + { + if (a > 5 && a < 50) + { + trace("in limits"); + } + trace("next"); + } + catch (e:Error) + { + trace("in catch"); + } + } + } +}