mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-08-02 16:01:15 +00:00
Fixed: AS3 break loop in catch clause
This commit is contained in:
@@ -21,8 +21,10 @@ import com.jpexs.decompiler.flash.FinalProcessLocalData;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.AVM2LocalData;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.CodeStats;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewCatchIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.debug.DebugLineIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfStrictEqIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.JumpIns;
|
||||
@@ -32,6 +34,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.DecLocalIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocalTypeIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.IncLocalIIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.IncLocalIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.KillIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocalTypeIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.HasNext2Ins;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.LabelIns;
|
||||
@@ -43,6 +46,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.DecLocalPIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.IncLocalPIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PopIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushByteIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushScopeIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceAIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertIIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item;
|
||||
@@ -166,10 +170,15 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canBeBreakCandidate(BaseLocalData localData, GraphPart part) {
|
||||
AVM2LocalData aLocalData = (AVM2LocalData) localData;
|
||||
protected boolean canBeBreakCandidate(BaseLocalData localData, GraphPart part, List<ThrowState> throwStates) {
|
||||
/*AVM2LocalData aLocalData = (AVM2LocalData) localData;
|
||||
if (aLocalData.finallyTargetParts.containsValue(part)) {
|
||||
return false;
|
||||
}*/
|
||||
for (ThrowState ts : throwStates) {
|
||||
if (ts.targetPart == part) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -177,7 +186,6 @@ public class AVM2Graph extends Graph {
|
||||
@Override
|
||||
protected void beforeGetLoops(BaseLocalData localData, String path, Set<GraphPart> allParts, List<ThrowState> throwStates) throws InterruptedException {
|
||||
AVM2LocalData avm2LocalData = ((AVM2LocalData) localData);
|
||||
|
||||
for (int e = 0; e < body.exceptions.length; e++) {
|
||||
ABCException ex = body.exceptions[e];
|
||||
if (ex.isFinally()) {
|
||||
@@ -185,7 +193,6 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
}
|
||||
|
||||
avm2LocalData.codeStats = avm2LocalData.code.getStats(avm2LocalData.abc, avm2LocalData.methodBody, avm2LocalData.methodBody.init_scope_depth, false);
|
||||
getIgnoredSwitches((AVM2LocalData) localData, allParts);
|
||||
Set<Integer> integerSwitchesIps = new HashSet<>();
|
||||
for (GraphPart p : avm2LocalData.ignoredSwitches.values()) {
|
||||
@@ -2065,7 +2072,11 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ThrowState> getThrowStates(Set<GraphPart> allParts) {
|
||||
protected List<ThrowState> getThrowStates(BaseLocalData localData, Set<GraphPart> allParts) {
|
||||
|
||||
AVM2LocalData avm2LocalData = (AVM2LocalData) localData;
|
||||
avm2LocalData.codeStats = avm2LocalData.code.getStats(avm2LocalData.abc, avm2LocalData.methodBody, avm2LocalData.methodBody.init_scope_depth, false);
|
||||
|
||||
List<ThrowState> ret = new ArrayList<>();
|
||||
for (int e = 0; e < body.exceptions.length; e++) {
|
||||
ThrowState ts = new ThrowState();
|
||||
@@ -2079,9 +2090,113 @@ public class AVM2Graph extends Graph {
|
||||
ts.throwingParts.add(p);
|
||||
}
|
||||
}
|
||||
GraphPart part = ts.targetPart;
|
||||
boolean wasNewCatch = false;
|
||||
int scopePos = -1;
|
||||
int ip = part.start;
|
||||
for (; ip <= part.end; ip++) {
|
||||
|
||||
if (avm2code.code.get(ip).definition instanceof NewCatchIns) {
|
||||
wasNewCatch = true;
|
||||
}
|
||||
if (avm2code.code.get(ip).definition instanceof PushScopeIns) {
|
||||
if (wasNewCatch) {
|
||||
scopePos = avm2LocalData.codeStats.instructionStats[ip].scopepos_after;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ip == part.end && part.nextParts.size() == 1 && part.nextParts.get(0).refs.size() == 1) {
|
||||
part = part.nextParts.get(0);
|
||||
ip = part.start - 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//Search all parts which have same or greater scope level, these all belong to catch
|
||||
Set<GraphPart> catchParts = new HashSet<>();
|
||||
if (scopePos > -1) {
|
||||
walkCatchParts(avm2LocalData.codeStats, part, ip, catchParts, scopePos);
|
||||
} else {
|
||||
logger.fine("No newcatch..pushscope found in catch, probably swftools");
|
||||
part = ts.targetPart;
|
||||
ip = part.start;
|
||||
int localRegId = -1;
|
||||
for (; ip <= part.end; ip++) {
|
||||
AVM2Instruction ins = avm2code.code.get(ip);
|
||||
if ((ins.definition instanceof NopIns)
|
||||
|| (ins.definition instanceof DebugLineIns)
|
||||
|| (ins.definition instanceof JumpIns)) {
|
||||
//ignore
|
||||
} else if (ins.definition instanceof SetLocalTypeIns) {
|
||||
localRegId = (((SetLocalTypeIns) ins.definition).getRegisterId(ins));
|
||||
break;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
if (ip == part.end && part.nextParts.size() == 1 && part.nextParts.get(0).refs.size() == 1) {
|
||||
part = part.nextParts.get(0);
|
||||
ip = part.start - 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (localRegId == -1) {
|
||||
logger.fine("Not even local reg assignment found in catch, weird :-(");
|
||||
} else {
|
||||
walkCatchPartsReg(localRegId, part, ip + 1, catchParts, new ArrayList<>(), new HashSet<>());
|
||||
}
|
||||
}
|
||||
ts.catchParts = catchParts;
|
||||
ret.add(ts);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private void walkCatchPartsReg(int registerId, GraphPart part, int startIp, Set<GraphPart> catchParts, List<GraphPart> path, Set<GraphPart> visited) {
|
||||
if (visited.contains(part)) {
|
||||
return;
|
||||
}
|
||||
visited.add(part);
|
||||
List<GraphPart> newPath = new ArrayList<>(path);
|
||||
newPath.add(part);
|
||||
for (int ip = startIp; ip <= part.end; ip++) {
|
||||
AVM2Instruction ins = avm2code.code.get(ip);
|
||||
if (ins.definition instanceof SetLocalTypeIns) {
|
||||
int setLocalId = ((SetLocalTypeIns) ins.definition).getRegisterId(ins);
|
||||
if (setLocalId == registerId) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (ins.definition instanceof KillIns) {
|
||||
int killId = ins.operands[0];
|
||||
if (killId == registerId) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (ins.definition instanceof GetLocalTypeIns) {
|
||||
int getLocalId = ((GetLocalTypeIns) ins.definition).getRegisterId(ins);
|
||||
if (getLocalId == registerId) {
|
||||
catchParts.addAll(newPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (GraphPart n : part.nextParts) {
|
||||
walkCatchPartsReg(registerId, n, n.start, catchParts, newPath, visited);
|
||||
}
|
||||
}
|
||||
|
||||
private void walkCatchParts(CodeStats stats, GraphPart part, int startIp, Set<GraphPart> catchParts, int scopePos) {
|
||||
if (catchParts.contains(part)) {
|
||||
return;
|
||||
}
|
||||
catchParts.add(part);
|
||||
for (int ip = startIp; ip <= part.end; ip++) {
|
||||
if (stats.instructionStats[ip].scopepos_after < scopePos) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (GraphPart n : part.nextParts) {
|
||||
walkCatchParts(stats, n, n.start, catchParts, scopePos);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ public class ActionGraph extends Graph {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canBeBreakCandidate(BaseLocalData localData, GraphPart part) {
|
||||
protected boolean canBeBreakCandidate(BaseLocalData localData, GraphPart part, List<ThrowState> throwStates) {
|
||||
if (part.refs.size() <= 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -481,7 +481,7 @@ public class Graph {
|
||||
|
||||
}
|
||||
|
||||
protected List<ThrowState> getThrowStates(Set<GraphPart> allParts) {
|
||||
protected List<ThrowState> getThrowStates(BaseLocalData localData, Set<GraphPart> allParts) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@@ -512,7 +512,7 @@ public class Graph {
|
||||
System.err.println("/parts");
|
||||
}
|
||||
TranslateStack stack = new TranslateStack(path);
|
||||
List<ThrowState> throwStates = getThrowStates(allParts);
|
||||
List<ThrowState> throwStates = getThrowStates(localData, allParts);
|
||||
beforeGetLoops(localData, path, allParts, throwStates);
|
||||
List<Loop> loops = new ArrayList<>();
|
||||
|
||||
@@ -1170,7 +1170,7 @@ public class Graph {
|
||||
clearThrowStates(throwStates);
|
||||
}
|
||||
|
||||
protected boolean canBeBreakCandidate(BaseLocalData localData, GraphPart part) {
|
||||
protected boolean canBeBreakCandidate(BaseLocalData localData, GraphPart part, List<ThrowState> throwStates) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1207,11 +1207,8 @@ public class Graph {
|
||||
}
|
||||
checkGetLoopsPart(part);
|
||||
|
||||
List<ThrowState> currentThrowStates = new ArrayList<>();
|
||||
|
||||
for (ThrowState ts : throwStates) {
|
||||
if (ts.throwingParts.contains(part) && ts.state != 1) {
|
||||
currentThrowStates.add(ts);
|
||||
if (ts.throwingParts.contains(part)) {
|
||||
ts.state = 1;
|
||||
}
|
||||
}
|
||||
@@ -1232,7 +1229,17 @@ public class Graph {
|
||||
|
||||
}
|
||||
}
|
||||
if (lastP1 != null && canBeBreakCandidate(localData, part)) {
|
||||
|
||||
boolean canBeCandidate = true;
|
||||
if (lastP1 != null) {
|
||||
for (ThrowState ts : throwStates) {
|
||||
if (!ts.catchParts.contains(lastP1.loopContinue) && ts.catchParts.contains(part)) {
|
||||
canBeCandidate = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lastP1 != null && canBeCandidate && canBeBreakCandidate(localData, part, throwStates)) {
|
||||
if (lastP1.breakCandidates.contains(part)) {
|
||||
lastP1.breakCandidates.add(part);
|
||||
lastP1.breakCandidatesLevels.add(level);
|
||||
@@ -1274,6 +1281,15 @@ public class Graph {
|
||||
//loopContinues.add(part);
|
||||
}
|
||||
|
||||
for (ThrowState ts : throwStates) {
|
||||
if (ts.throwingParts.contains(part)) {
|
||||
GraphPart t = ts.targetPart;
|
||||
if (!visited.contains(t)) {
|
||||
getLoopsWalk(localData, t, loops, throwStates, stopPart, false, visited, level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (part.nextParts.size() == 2 && !partIsSwitch(part)) {
|
||||
|
||||
List<GraphPart> nps;/* = new ArrayList<>(part.nextParts);
|
||||
@@ -1326,22 +1342,13 @@ public class Graph {
|
||||
getLoopsWalk(localData, part.nextParts.get(0), loops, throwStates, stopPart, false, visited, level);
|
||||
}
|
||||
|
||||
List<Loop> loops2 = new ArrayList<>(loops);
|
||||
/*List<Loop> loops2 = new ArrayList<>(loops);
|
||||
for (Loop l : loops2) {
|
||||
l.breakCandidatesLocked++;
|
||||
}
|
||||
for (ThrowState ts : throwStates) {
|
||||
if (ts.throwingParts.contains(part) && (currentThrowStates.contains(ts) || ts.state != 1)) {
|
||||
GraphPart t = ts.targetPart;
|
||||
if (!visited.contains(t)) {
|
||||
getLoopsWalk(localData, t, loops, throwStates, stopPart, false, visited, level + 1 /*???*/);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Loop l : loops2) {
|
||||
}*/
|
||||
/*for (Loop l : loops2) {
|
||||
l.breakCandidatesLocked--;
|
||||
}
|
||||
|
||||
}*/
|
||||
if (isLoop && currentLoop != null) {
|
||||
GraphPart found;
|
||||
|
||||
@@ -1386,7 +1393,7 @@ public class Graph {
|
||||
findPartsOutsideTry(ts, cand, outsideTry, new HashSet<>());
|
||||
|
||||
for (int j = outsideTry.size() - 1; j >= 0; j--) {
|
||||
if (!canBeBreakCandidate(localData, outsideTry.get(j))) {
|
||||
if (!canBeBreakCandidate(localData, outsideTry.get(j), throwStates)) {
|
||||
outsideTry.remove(j);
|
||||
}
|
||||
}
|
||||
@@ -1463,7 +1470,7 @@ public class Graph {
|
||||
|
||||
currentLoop.breakCandidates.add(other);
|
||||
currentLoop.breakCandidatesLevels.add(curLev);
|
||||
|
||||
|
||||
break loopcand;
|
||||
}
|
||||
}
|
||||
@@ -1486,7 +1493,7 @@ public class Graph {
|
||||
removed.put(found, maxlevel);
|
||||
}
|
||||
} while ((found != null) && (currentLoop.breakCandidates.size() > 1));
|
||||
|
||||
|
||||
Map<GraphPart, Integer> count = new HashMap<>();
|
||||
GraphPart winner = null;
|
||||
int winnerCount = 0;
|
||||
@@ -2082,7 +2089,7 @@ public class Graph {
|
||||
GraphTargetItem leftSide = expr.getNotCoercedNoDup();
|
||||
|
||||
boolean hideEmptyTrueFalse = true;
|
||||
|
||||
|
||||
if (leftSide instanceof DuplicateItem) {
|
||||
isIf = false;
|
||||
if (hideEmptyTrueFalse && prevExpr.getNotCoercedNoDup() instanceof FalseItem) {
|
||||
|
||||
@@ -13,6 +13,7 @@ public class ThrowState {
|
||||
|
||||
public Set<GraphPart> throwingParts = new HashSet<>();
|
||||
public GraphPart targetPart;
|
||||
public Set<GraphPart> catchParts = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
@@ -230,6 +230,35 @@ public class ActionScript3AssembledDecompileTest extends ActionScript3DecompileT
|
||||
false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTryCatchLoopBreakLevel2() {
|
||||
decompileMethod("assembled", "testTryCatchLoopBreakLevel2", "var a:int = 0;\r\n"
|
||||
+ "a = 0;\r\n"
|
||||
+ "trace(\"before loop\");\r\n"
|
||||
+ "loop0:\r\n"
|
||||
+ "while(true)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "try\r\n"
|
||||
+ "{\r\n"
|
||||
+ "trace(\"in try\");\r\n"
|
||||
+ "}\r\n"
|
||||
+ "catch(e:Error)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "trace(\"in catch1\");\r\n"
|
||||
+ "while(a <= 5)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "if(a > 5)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "break loop0;\r\n"
|
||||
+ "}\r\n"
|
||||
+ "}\r\n"
|
||||
+ "trace(\"in catch1c\");\r\n"
|
||||
+ "}\r\n"
|
||||
+ "}\r\n"
|
||||
+ "trace(\"after\");\r\n",
|
||||
false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTryDoWhile() {
|
||||
decompileMethod("assembled", "testTryDoWhile", "trace(\"first\");\r\n"
|
||||
|
||||
@@ -311,6 +311,124 @@ public class ActionScript3CrossCompileDecompileTest extends ActionScript3Decompi
|
||||
false);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "swfNamesProvider")
|
||||
public void testTryCatchLoopBreak2(String swfUsed) {
|
||||
decompileMethod(swfUsed, "testTryCatchLoopBreak2", "var a:int = 0;\r\n"
|
||||
+ "a = 0;\r\n"
|
||||
+ "trace(\"before loop\");\r\n"
|
||||
+ "while(a < 20)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "try\r\n"
|
||||
+ "{\r\n"
|
||||
+ "trace(\"in try\");\r\n"
|
||||
+ "return;\r\n"
|
||||
+ "}\r\n"
|
||||
+ "catch(e:Error)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "trace(\"in catch\");\r\n"
|
||||
+ "trace(\"a=\" + a);\r\n"
|
||||
+ "}\r\n"
|
||||
+ "}\r\n"
|
||||
+ "trace(\"after\");\r\n",
|
||||
false);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "swfNamesProvider")
|
||||
public void testTryCatchLoopBreak3(String swfUsed) {
|
||||
decompileMethod(swfUsed, "testTryCatchLoopBreak3", "var a:int = 0;\r\n"
|
||||
+ "a = 0;\r\n"
|
||||
+ "trace(\"before loop\");\r\n"
|
||||
+ "while(true)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "try\r\n"
|
||||
+ "{\r\n"
|
||||
+ "trace(\"in try\");\r\n"
|
||||
+ "}\r\n"
|
||||
+ "catch(e:Error)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "trace(\"in catch1\");\r\n"
|
||||
+ "break;\r\n"
|
||||
+ "}\r\n"
|
||||
+ "catch(e:EOFError)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "trace(\"in catch2\");\r\n"
|
||||
+ "break;\r\n"
|
||||
+ "}\r\n"
|
||||
+ "}\r\n"
|
||||
+ "trace(\"after\");\r\n",
|
||||
false);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "swfNamesProvider")
|
||||
public void testTryCatchLoopBreak4(String swfUsed) {
|
||||
decompileMethod(swfUsed, "testTryCatchLoopBreak4", "var a:int = 0;\r\n"
|
||||
+ "a = 0;\r\n"
|
||||
+ "trace(\"before loop\");\r\n"
|
||||
+ "while(true)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "try\r\n"
|
||||
+ "{\r\n"
|
||||
+ "trace(\"in try\");\r\n"
|
||||
+ "}\r\n"
|
||||
+ "catch(e:Error)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "trace(\"in catch1\");\r\n"
|
||||
+ "if(a > 5)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "trace(\"a\");\r\n"
|
||||
+ "if(a > 6)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "trace(\"b\");\r\n"
|
||||
+ "break;\r\n"
|
||||
+ "}\r\n"
|
||||
+ "trace(\"c\");\r\n"
|
||||
+ "}\r\n"
|
||||
+ "trace(\"in catch1b\");\r\n"
|
||||
+ "if(a > 10)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "trace(\"d\");\r\n"
|
||||
+ "if(a > 11)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "trace(\"e\");\r\n"
|
||||
+ "break;\r\n"
|
||||
+ "}\r\n"
|
||||
+ "trace(\"f\");\r\n"
|
||||
+ "}\r\n"
|
||||
+ "trace(\"in catch1c\");\r\n"
|
||||
+ "}\r\n"
|
||||
+ "}\r\n"
|
||||
+ "trace(\"after\");\r\n",
|
||||
false);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "swfNamesProvider")
|
||||
public void testTryCatchLoopBreak5(String swfUsed) {
|
||||
decompileMethod(swfUsed, "testTryCatchLoopBreak5", "var a:int = 0;\r\n"
|
||||
+ "a = 0;\r\n"
|
||||
+ "trace(\"before loop\");\r\n"
|
||||
+ "while(true)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "try\r\n"
|
||||
+ "{\r\n"
|
||||
+ "trace(\"in try\");\r\n"
|
||||
+ "}\r\n"
|
||||
+ "catch(e:Error)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "trace(\"in catch1\");\r\n"
|
||||
+ "while(true)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "if(a > 5)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "break;\r\n"
|
||||
+ "}\r\n"
|
||||
+ "}\r\n"
|
||||
+ "trace(\"in catch1c\");\r\n"
|
||||
+ "}\r\n"
|
||||
+ "}\r\n"
|
||||
+ "trace(\"after\");\r\n",
|
||||
false);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "swfNamesProvider")
|
||||
public void testTryCatchTry(String swfUsed) {
|
||||
decompileMethod(swfUsed, "testTryCatchTry", "trace(\"before try\");\r\n"
|
||||
|
||||
@@ -350,6 +350,76 @@ public class ActionScript3CrossCompileSwfToolsDecompileTest extends ActionScript
|
||||
false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTryCatchLoopBreak4() {
|
||||
decompileMethod("swftools", "testTryCatchLoopBreak4", "var _loc1_:int = 0;\r\n"
|
||||
+ "_loc1_ = 0;\r\n"
|
||||
+ "trace(\"before loop\");\r\n"
|
||||
+ "while(true)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "try\r\n"
|
||||
+ "{\r\n"
|
||||
+ "trace(\"in try\");\r\n"
|
||||
+ "}\r\n"
|
||||
+ "catch(e:Error)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "trace(\"in catch1\");\r\n"
|
||||
+ "if(_loc1_ > 5)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "trace(\"a\");\r\n"
|
||||
+ "if(_loc1_ > 6)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "trace(\"b\");\r\n"
|
||||
+ "break;\r\n"
|
||||
+ "}\r\n"
|
||||
+ "trace(\"c\");\r\n"
|
||||
+ "}\r\n"
|
||||
+ "trace(\"in catch1b\");\r\n"
|
||||
+ "if(_loc1_ > 10)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "trace(\"d\");\r\n"
|
||||
+ "if(_loc1_ > 11)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "trace(\"e\");\r\n"
|
||||
+ "break;\r\n"
|
||||
+ "}\r\n"
|
||||
+ "trace(\"f\");\r\n"
|
||||
+ "}\r\n"
|
||||
+ "trace(\"in catch1c\");\r\n"
|
||||
+ "}\r\n"
|
||||
+ "}\r\n"
|
||||
+ "trace(\"after\");\r\n",
|
||||
false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTryCatchLoopBreak5() {
|
||||
decompileMethod("swftools", "testTryCatchLoopBreak5", "var _loc1_:int = 0;\r\n"
|
||||
+ "_loc1_ = 0;\r\n"
|
||||
+ "trace(\"before loop\");\r\n"
|
||||
+ "while(true)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "try\r\n"
|
||||
+ "{\r\n"
|
||||
+ "trace(\"in try\");\r\n"
|
||||
+ "}\r\n"
|
||||
+ "catch(e:Error)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "trace(\"in catch1\");\r\n"
|
||||
+ "while(true)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "if(_loc1_ > 5)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "break;\r\n"
|
||||
+ "}\r\n"
|
||||
+ "}\r\n"
|
||||
+ "trace(\"in catch1c\");\r\n"
|
||||
+ "}\r\n"
|
||||
+ "}\r\n"
|
||||
+ "trace(\"after\");\r\n",
|
||||
false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTryCatchTry() {
|
||||
decompileMethod("swftools", "testTryCatchTry", "trace(\"before try\");\r\n"
|
||||
|
||||
Binary file not shown.
@@ -22,5 +22,6 @@ program
|
||||
#include "tests/TestSwitchJoin.script.asasm"
|
||||
#include "tests/TestDeobfuscatorJumpsExceptionStart.script.asasm"
|
||||
#include "tests/TestUnnamedException.script.asasm"
|
||||
#include "tests/TestTryCatchLoopBreakLevel2.script.asasm"
|
||||
; place to add next
|
||||
end ; program
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
class
|
||||
refid "tests:TestTryCatchLoopBreakLevel2"
|
||||
instance QName(PackageNamespace("tests"), "TestTryCatchLoopBreakLevel2")
|
||||
extends QName(PackageNamespace(""), "Object")
|
||||
flag SEALED
|
||||
flag PROTECTEDNS
|
||||
protectedns ProtectedNamespace("tests:TestTryCatchLoopBreakLevel2")
|
||||
iinit
|
||||
refid "tests:TestTryCatchLoopBreakLevel2/instance/init"
|
||||
body
|
||||
maxstack 1
|
||||
localcount 1
|
||||
initscopedepth 4
|
||||
maxscopedepth 5
|
||||
code
|
||||
getlocal0
|
||||
pushscope
|
||||
|
||||
getlocal0
|
||||
constructsuper 0
|
||||
|
||||
returnvoid
|
||||
end ; code
|
||||
end ; body
|
||||
end ; method
|
||||
trait method QName(PackageNamespace(""), "run")
|
||||
method
|
||||
refid "tests:TestTryCatchLoopBreakLevel2/instance/run"
|
||||
returns QName(PackageNamespace(""), "void")
|
||||
body
|
||||
maxstack 4
|
||||
localcount 4
|
||||
initscopedepth 0
|
||||
maxscopedepth 2
|
||||
|
||||
code
|
||||
getlocal0
|
||||
pushscope
|
||||
debug 1, "a", 0, 0
|
||||
pushbyte 0
|
||||
setlocal1
|
||||
debugline 15
|
||||
pushbyte 0
|
||||
setlocal1
|
||||
getlex QName(PackageNamespace(""),"trace")
|
||||
getglobalscope
|
||||
debugline 16
|
||||
pushstring "before loop"
|
||||
call 1
|
||||
pop
|
||||
debugline 17
|
||||
label
|
||||
jump ofs007d
|
||||
ofs0023:
|
||||
label
|
||||
ofs0024:
|
||||
getlex QName(PackageNamespace(""),"trace")
|
||||
getglobalscope
|
||||
debugline 21
|
||||
pushstring "in try"
|
||||
call 1
|
||||
pop
|
||||
debugline 19
|
||||
ofs0030:
|
||||
jump ofs007d
|
||||
ofs0034:
|
||||
getlocal0
|
||||
pushscope
|
||||
newcatch 0
|
||||
dup
|
||||
setlocal3
|
||||
dup
|
||||
pushscope
|
||||
swap
|
||||
setslot 1
|
||||
getlex QName(PackageNamespace(""),"trace")
|
||||
getglobalscope
|
||||
debugline 25
|
||||
pushstring "in catch1"
|
||||
call 1
|
||||
pop
|
||||
label
|
||||
jump ofs006b
|
||||
ofs004f:
|
||||
label
|
||||
getlocal1
|
||||
debugline 27
|
||||
pushbyte 5
|
||||
ifgt ofs006f
|
||||
getlocal1
|
||||
debugline 30
|
||||
pushbyte 5
|
||||
ifngt ofs006b
|
||||
popscope
|
||||
kill 3
|
||||
jump ofs0081
|
||||
debugline 26
|
||||
ofs006b:
|
||||
jump ofs004f
|
||||
ofs006f:
|
||||
getlex QName(PackageNamespace(""),"trace")
|
||||
getglobalscope
|
||||
debugline 34
|
||||
pushstring "in catch1c"
|
||||
call 1
|
||||
pop
|
||||
popscope
|
||||
debugline 18
|
||||
ofs007d:
|
||||
jump ofs0023
|
||||
ofs0081:
|
||||
getlex QName(PackageNamespace(""),"trace")
|
||||
getglobalscope
|
||||
debugline 37
|
||||
pushstring "after"
|
||||
call 1
|
||||
returnvoid
|
||||
end ; code
|
||||
try from ofs0024 to ofs0030 target ofs0034 type QName(PackageNamespace(""),"Error") name QName(PackageInternalNs("tests"),"e") end
|
||||
end ; body
|
||||
end ; method
|
||||
end ; trait
|
||||
end ; instance
|
||||
cinit
|
||||
refid "tests:TestTryCatchLoopBreakLevel2/class/init"
|
||||
body
|
||||
maxstack 1
|
||||
localcount 1
|
||||
initscopedepth 3
|
||||
maxscopedepth 4
|
||||
code
|
||||
getlocal0
|
||||
pushscope
|
||||
|
||||
returnvoid
|
||||
end ; code
|
||||
end ; body
|
||||
end ; method
|
||||
end ; class
|
||||
@@ -0,0 +1,29 @@
|
||||
script
|
||||
sinit
|
||||
refid "tests:TestTryCatchLoopBreakLevel2/init"
|
||||
body
|
||||
maxstack 2
|
||||
localcount 1
|
||||
initscopedepth 1
|
||||
maxscopedepth 3
|
||||
code
|
||||
getlocal0
|
||||
pushscope
|
||||
|
||||
findpropstrict Multiname("TestTryCatchLoopBreakLevel2", [PackageNamespace("tests")])
|
||||
getlex QName(PackageNamespace(""), "Object")
|
||||
pushscope
|
||||
|
||||
getlex Multiname("Object", [PrivateNamespace(null, "tests:TestTryCatchLoopBreakLevel2"), PackageNamespace(""), PackageNamespace("tests"), PackageInternalNs("tests"), Namespace("http://adobe.com/AS3/2006/builtin")])
|
||||
newclass "tests:TestTryCatchLoopBreakLevel2"
|
||||
popscope
|
||||
initproperty QName(PackageNamespace("tests"), "TestTryCatchLoopBreakLevel2")
|
||||
|
||||
returnvoid
|
||||
end ; code
|
||||
end ; body
|
||||
end ; method
|
||||
trait class QName(PackageNamespace("tests"), "TestTryCatchLoopBreakLevel2")
|
||||
#include "TestTryCatchLoopBreakLevel2.class.asasm"
|
||||
end ; trait
|
||||
end ; script
|
||||
Binary file not shown.
@@ -12,6 +12,7 @@
|
||||
<movie minorVersion="0" />
|
||||
<movie platform="Flash Player" />
|
||||
<movie background="#FFFFFF" />
|
||||
<movie preferredSDK="Flex 4.6.0, AIR 3.1;4.6.0, 3.1;" />
|
||||
</output>
|
||||
<!-- Other classes to be compiled into your SWF -->
|
||||
<classpaths>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,4 +1,6 @@
|
||||
@echo off
|
||||
set COMPILERKIND=air
|
||||
set SWFNAME=as3_cross_compile
|
||||
call c:\air\bin\mxmlc.bat -warnings=false -debug=true -output bin/%SWFNAME%.%COMPILERKIND%.swf src/Main.as 1> buildlog.%COMPILERKIND%.txt 2>&1
|
||||
call c:\air\bin\mxmlc.bat -warnings=false -debug=true -output bin/%SWFNAME%.%COMPILERKIND%.swf src/Main.as 1> buildlog.%COMPILERKIND%.txt 2>&1
|
||||
IF NOT ERRORLEVEL 0 echo "FAILED"
|
||||
exit /b 0
|
||||
@@ -1,4 +1,6 @@
|
||||
@echo off
|
||||
set COMPILERKIND=flex_apache
|
||||
set SWFNAME=as3_cross_compile
|
||||
call c:\flex_apache\bin\mxmlc.bat -warnings=false -debug=true -output bin/%SWFNAME%.%COMPILERKIND%.swf src/Main.as 1> buildlog.%COMPILERKIND%.txt 2>&1
|
||||
call c:\flex_apache\bin\mxmlc.bat -warnings=false -debug=true -output bin/%SWFNAME%.%COMPILERKIND%.swf src/Main.as 1> buildlog.%COMPILERKIND%.txt 2>&1
|
||||
IF NOT ERRORLEVEL 0 echo "FAILED"
|
||||
exit /b 0
|
||||
@@ -1,4 +1,6 @@
|
||||
@echo off
|
||||
set COMPILERKIND=flex
|
||||
set SWFNAME=as3_cross_compile
|
||||
c:\flex\bin\mxmlc.exe -warnings=false -debug=true -output bin/%SWFNAME%.%COMPILERKIND%.swf src/Main.as 1> buildlog.%COMPILERKIND%.txt 2>&1
|
||||
c:\flex\bin\mxmlc.exe -warnings=false -debug=true -output bin/%SWFNAME%.%COMPILERKIND%.swf src/Main.as 1> buildlog.%COMPILERKIND%.txt 2>&1
|
||||
IF NOT ERRORLEVEL 0 echo "FAILED"
|
||||
exit /b 0
|
||||
@@ -2,4 +2,6 @@
|
||||
set COMPILERKIND=swftools
|
||||
set SWFNAME=as3_cross_compile
|
||||
cd src
|
||||
c:\swftools\as3compile.exe Main.as -o ..\bin\%SWFNAME%.%COMPILERKIND%.swf 1> ../buildlog.%COMPILERKIND%.txt 2>&1
|
||||
c:\swftools\as3compile.exe Main.as -o ..\bin\%SWFNAME%.%COMPILERKIND%.swf 1> ../buildlog.%COMPILERKIND%.txt 2>&1
|
||||
IF NOT ERRORLEVEL 0 echo "FAILED"
|
||||
exit /b 0
|
||||
@@ -3,8 +3,6 @@
|
||||
<!--Any modifications you make may be lost.-->
|
||||
<flex-config>
|
||||
<target-player>25.0</target-player>
|
||||
<benchmark>false</benchmark>
|
||||
<static-link-runtime-shared-libraries>true</static-link-runtime-shared-libraries>
|
||||
<compiler>
|
||||
<define append="true">
|
||||
<name>CONFIG::debug</name>
|
||||
@@ -16,7 +14,7 @@
|
||||
</define>
|
||||
<define append="true">
|
||||
<name>CONFIG::timeStamp</name>
|
||||
<value>'08.02.2021'</value>
|
||||
<value>'09.02.2021'</value>
|
||||
</define>
|
||||
<define append="true">
|
||||
<name>CONFIG::air</name>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
</define>
|
||||
<define append="true">
|
||||
<name>CONFIG::timeStamp</name>
|
||||
<value>'08.02.2021'</value>
|
||||
<value>'09.02.2021'</value>
|
||||
</define>
|
||||
<define append="true">
|
||||
<name>CONFIG::air</name>
|
||||
|
||||
@@ -21,6 +21,10 @@ package
|
||||
TestTryCatchInWhile5;
|
||||
TestTryCatchLoop;
|
||||
TestTryCatchLoopBreak;
|
||||
TestTryCatchLoopBreak2;
|
||||
TestTryCatchLoopBreak3;
|
||||
TestTryCatchLoopBreak4;
|
||||
TestTryCatchLoopBreak5;
|
||||
TestTryCatchExceptionUsage
|
||||
TestTryFinally;
|
||||
TestTryFinallyDirectReturnInFinally;
|
||||
|
||||
51
libsrc/ffdec_lib/testdata/as3_cross_compile/src/tests/TestTryCatchLoopBreak4.as
vendored
Normal file
51
libsrc/ffdec_lib/testdata/as3_cross_compile/src/tests/TestTryCatchLoopBreak4.as
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
package tests
|
||||
{
|
||||
import flash.errors.EOFError;
|
||||
/**
|
||||
* ...
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class TestTryCatchLoopBreak4
|
||||
{
|
||||
|
||||
|
||||
public function run() : void
|
||||
{
|
||||
var a:int;
|
||||
a = 0;
|
||||
trace("before loop");
|
||||
while (true) {
|
||||
try
|
||||
{
|
||||
trace("in try");
|
||||
}
|
||||
catch(e:Error)
|
||||
{
|
||||
trace("in catch1");
|
||||
if (a > 5){
|
||||
trace("a");
|
||||
if (a > 6){
|
||||
trace("b");
|
||||
break;
|
||||
}
|
||||
trace("c");
|
||||
}
|
||||
trace("in catch1b");
|
||||
if (a > 10){
|
||||
trace("d");
|
||||
if (a > 11){
|
||||
trace("e");
|
||||
break;
|
||||
}
|
||||
trace("f");
|
||||
}
|
||||
trace("in catch1c");
|
||||
}
|
||||
}
|
||||
trace("after");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
39
libsrc/ffdec_lib/testdata/as3_cross_compile/src/tests/TestTryCatchLoopBreak5.as
vendored
Normal file
39
libsrc/ffdec_lib/testdata/as3_cross_compile/src/tests/TestTryCatchLoopBreak5.as
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
package tests
|
||||
{
|
||||
import flash.errors.EOFError;
|
||||
/**
|
||||
* ...
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class TestTryCatchLoopBreak5
|
||||
{
|
||||
|
||||
|
||||
public function run() : void
|
||||
{
|
||||
var a:int;
|
||||
a = 0;
|
||||
trace("before loop");
|
||||
while (true) {
|
||||
try
|
||||
{
|
||||
trace("in try");
|
||||
}
|
||||
catch(e:Error)
|
||||
{
|
||||
trace("in catch1");
|
||||
while (true){
|
||||
if (a > 5){
|
||||
break;
|
||||
}
|
||||
}
|
||||
trace("in catch1c");
|
||||
}
|
||||
}
|
||||
trace("after");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user