From 3b6cee4dfb6ebca15bbdd53239c3a2e5351a6b59 Mon Sep 17 00:00:00 2001 From: honfika Date: Tue, 19 Aug 2014 15:39:10 +0200 Subject: [PATCH] do not use getBytesLength because it "generates" the action bytes to get the length (slow) use instead getTotalActionLength --- src/com/jpexs/decompiler/flash/SWF.java | 9 +- .../jpexs/decompiler/flash/action/Action.java | 58 ++- .../decompiler/flash/action/ActionList.java | 24 ++ .../flash/action/ActionListReader.java | 31 +- .../flash/action/parser/pcode/ASMParser.java | 18 +- .../parser/script/ActionSourceGenerator.java | 10 +- .../flash/action/swf3/ActionWaitForFrame.java | 2 +- .../flash/action/swf4/ActionIf.java | 7 +- .../flash/action/swf4/ActionJump.java | 4 +- .../flash/action/swf4/ActionPush.java | 2 +- .../action/swf4/ActionWaitForFrame2.java | 2 +- .../action/swf5/ActionDefineFunction.java | 6 +- .../flash/action/swf5/ActionWith.java | 2 +- .../action/swf7/ActionDefineFunction2.java | 6 +- .../flash/action/swf7/ActionTry.java | 2 +- .../flash/tags/DefineButtonTag.java | 7 +- .../decompiler/flash/tags/DoActionTag.java | 7 +- .../flash/tags/DoInitActionTag.java | 7 +- .../decompiler/flash/tags/base/ASMSource.java | 3 +- .../decompiler/flash/treenodes/TagNode.java | 384 +++++++++--------- .../flash/types/BUTTONCONDACTION.java | 7 +- .../flash/types/CLIPACTIONRECORD.java | 7 +- 22 files changed, 316 insertions(+), 289 deletions(-) diff --git a/src/com/jpexs/decompiler/flash/SWF.java b/src/com/jpexs/decompiler/flash/SWF.java index daa4e3a54..f7f0c231d 100644 --- a/src/com/jpexs/decompiler/flash/SWF.java +++ b/src/com/jpexs/decompiler/flash/SWF.java @@ -26,6 +26,7 @@ import com.jpexs.decompiler.flash.abc.ScriptPack; import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.ActionDeobfuscation; import com.jpexs.decompiler.flash.action.ActionGraphSource; +import com.jpexs.decompiler.flash.action.ActionList; import com.jpexs.decompiler.flash.action.ActionLocalData; import com.jpexs.decompiler.flash.action.model.ConstantPool; import com.jpexs.decompiler.flash.action.model.DirectValueActionItem; @@ -1682,7 +1683,7 @@ public final class SWF implements TreeItem, Timelined { GraphSourceItem ins = code.get(ip); if (debugMode) { - System.err.println("Visit " + ip + ": ofs" + Helper.formatAddress(((Action) ins).getAddress()) + ":" + ((Action) ins).getASMSource(new ArrayList(), new ArrayList(), new ArrayList(), code.version, ScriptExportMode.PCODE) + " stack:" + Helper.stackToString(stack, LocalData.create(new ConstantPool()))); + System.err.println("Visit " + ip + ": ofs" + Helper.formatAddress(((Action) ins).getAddress()) + ":" + ((Action) ins).getASMSource(new ArrayList(), new ArrayList(), new ArrayList(), ScriptExportMode.PCODE) + " stack:" + Helper.stackToString(stack, LocalData.create(new ConstantPool()))); } if (ins.isExit()) { break; @@ -1844,12 +1845,12 @@ public final class SWF implements TreeItem, Timelined { private List> getVariables(List> variables, List functions, HashMap strings, HashMap usageType, ASMSource src, String path) throws InterruptedException { List> ret = new ArrayList<>(); - List actions = src.getActions(); + ActionList actions = src.getActions(); actionsMap.put(src, actions); getVariables(variables, functions, strings, usageType, new ActionGraphSource(actions, version, new HashMap(), new HashMap(), new HashMap()), 0, path); return ret; } - private HashMap> actionsMap = new HashMap<>(); + private HashMap actionsMap = new HashMap<>(); private void getVariables(List objs, String path) throws InterruptedException { List processed = new ArrayList<>(); @@ -2155,7 +2156,7 @@ public final class SWF implements TreeItem, Timelined { } } for (ASMSource src : actionsMap.keySet()) { - actionsMap.put(src, Action.removeNops(0, actionsMap.get(src), version, ""/*FIXME path*/)); + actionsMap.get(src).removeNops(); src.setActions(actionsMap.get(src)); src.setModified(); } diff --git a/src/com/jpexs/decompiler/flash/action/Action.java b/src/com/jpexs/decompiler/flash/action/Action.java index 3f9cbffb7..ffb46cd9d 100644 --- a/src/com/jpexs/decompiler/flash/action/Action.java +++ b/src/com/jpexs/decompiler/flash/action/Action.java @@ -323,6 +323,16 @@ public class Action implements GraphSourceItem { return getBytes(version).length; } + /** + * Uptates the action length to the length calculated from action bytes + * + * @param version SWF version + */ + public void updateLength(int version) { + int length = getBytes(version).length; + actionLength = length - 1 - ((actionCode >= 0x80) ? 2 : 0); + } + /** * Surrounds byte array with Action header * @@ -374,13 +384,12 @@ public class Action implements GraphSourceItem { * * @param list List of actions * @param baseAddress Address of first action in the list - * @param version SWF version */ - public static void setActionsAddresses(List list, long baseAddress, int version) { + public static void setActionsAddresses(List list, long baseAddress) { long offset = baseAddress; for (Action a : list) { a.setAddress(offset); - offset += a.getBytesLength(version); + offset += a.getTotalActionLength(); } } @@ -493,7 +502,7 @@ public class Action implements GraphSourceItem { if (pos + 1 < list.size()) { len = (int) (((Action) (list.get(pos + 1))).getAddress() - a.getAddress()); } else { - len = a.getBytesLength(version); + len = a.getTotalActionLength(); } if (!(a instanceof ActionEnd)) { for (int i = 0; i < len; i++) { @@ -538,12 +547,12 @@ public class Action implements GraphSourceItem { writer.appendNoHilight("FFDec_DeobfuscatePop").newLine(); if (fixBranch == 0) { //jump writer.appendNoHilight("Jump loc"); - writer.appendNoHilight(Helper.formatAddress(a.getAddress() + a.getBytesLength(version) + ((ActionIf) a).getJumpOffset())); + writer.appendNoHilight(Helper.formatAddress(a.getAddress() + a.getTotalActionLength() + ((ActionIf) a).getJumpOffset())); } else { //nojump, ignore } } else { - a.getASMSourceReplaced(list, importantOffsets, constantPool, version, exportMode, writer); + a.getASMSourceReplaced(list, importantOffsets, constantPool, exportMode, writer); } writer.appendNoHilight(a.isIgnored() ? "; ignored" : ""); writer.appendNoHilight(add); @@ -593,7 +602,7 @@ public class Action implements GraphSourceItem { * @param exportMode PCode or hex? * @return String of P-code source */ - public String getASMSource(List container, List knownAddreses, List constantPool, int version, ScriptExportMode exportMode) { + public String getASMSource(List container, List knownAddreses, List constantPool, ScriptExportMode exportMode) { return toString(); } @@ -633,10 +642,9 @@ public class Action implements GraphSourceItem { * * @param actions List of actions * @param ip Action index - * @param version SWF version * @return address */ - public static long ip2adr(List actions, int ip, int version) { + public static long ip2adr(List actions, int ip) { /* List actions=new ArrayList(); for(GraphSourceItem s:sources){ if(s instanceof Action){ @@ -647,7 +655,7 @@ public class Action implements GraphSourceItem { if (actions.isEmpty()) { return 0; } - return actions.get(actions.size() - 1).getAddress() + actions.get(actions.size() - 1).getBytesLength(version); + return actions.get(actions.size() - 1).getAddress() + actions.get(actions.size() - 1).getTotalActionLength(); } if (ip == -1) { return 0; @@ -660,17 +668,16 @@ public class Action implements GraphSourceItem { * * @param actions List of actions * @param addr Address - * @param version SWF version * @return action index */ - public static int adr2ip(List actions, long addr, int version) { + public static int adr2ip(List actions, long addr) { for (int ip = 0; ip < actions.size(); ip++) { if (actions.get(ip).getAddress() == addr) { return ip; } } if (actions.size() > 0) { - long outpos = actions.get(actions.size() - 1).getAddress() + actions.get(actions.size() - 1).getBytesLength(version); + long outpos = actions.get(actions.size() - 1).getAddress() + actions.get(actions.size() - 1).getTotalActionLength(); if (addr == outpos) { return actions.size(); } @@ -824,7 +831,7 @@ public class Action implements GraphSourceItem { loopip: while (ip <= end) { - long addr = ip2adr(actions, ip, version); + long addr = ip2adr(actions, ip); if (ip > end) { break; } @@ -858,7 +865,7 @@ public class Action implements GraphSourceItem { } List out; try { - out = ActionGraph.translateViaGraph(cnt.getRegNames(), variables2, functions, actions.subList(adr2ip(actions, endAddr, version), adr2ip(actions, endAddr + size, version)), version, staticOperation, path + (cntName == null ? "" : "/" + cntName)); + out = ActionGraph.translateViaGraph(cnt.getRegNames(), variables2, functions, actions.subList(adr2ip(actions, endAddr), adr2ip(actions, endAddr + size)), version, staticOperation, path + (cntName == null ? "" : "/" + cntName)); } catch (OutOfMemoryError | TranslateException | StackOverflowError ex2) { Logger.getLogger(Action.class.getName()).log(Level.SEVERE, "Decompilation error in: " + path, ex2); if (ex2 instanceof OutOfMemoryError) { @@ -877,7 +884,7 @@ public class Action implements GraphSourceItem { endAddr += size; } ((GraphSourceItemContainer) action).translateContainer(outs, stack, output, registerNames, variables, functions); - ip = adr2ip(actions, endAddr, version); + ip = adr2ip(actions, endAddr); continue; } @@ -888,7 +895,7 @@ public class Action implements GraphSourceItem { if (actions.get(ip + 2) instanceof ActionNot) { if (actions.get(ip + 3) instanceof ActionIf) { ActionIf aif = (ActionIf) actions.get(ip + 3); - if (adr2ip(actions, ip2adr(actions, ip + 4, version) + aif.getJumpOffset(), version) == ip) { + if (adr2ip(actions, ip2adr(actions, ip + 4) + aif.getJumpOffset()) == ip) { ip += 4; continue; } @@ -1188,19 +1195,6 @@ public class Action implements GraphSourceItem { return false; } - public static List removeNops(long address, List actions, int version, String path) { - List ret = actions; - try { - HilightedTextWriter writer = new HilightedTextWriter(Configuration.getCodeFormatting(), false); - Action.actionsToString(new ArrayList(), address, ret, version, ScriptExportMode.PCODE, writer, path); - String s = writer.toString(); - ret = ASMParser.parse(address, true, s, SWF.DEFAULT_VERSION, false); - } catch (IOException | ParseException ex) { - Logger.getLogger(SWFInputStream.class.getName()).log(Level.SEVERE, "parsing error. path: " + path, ex); - } - return ret; - } - public static void setConstantPool(List actions, ConstantPool cpool) { for (GraphSourceItem a : actions) { if (a instanceof ActionPush) { @@ -1221,8 +1215,8 @@ public class Action implements GraphSourceItem { } } - public GraphTextWriter getASMSourceReplaced(List container, List knownAddreses, List constantPool, int version, ScriptExportMode exportMode, GraphTextWriter writer) { - writer.appendNoHilight(getASMSource(container, knownAddreses, constantPool, version, exportMode)); + public GraphTextWriter getASMSourceReplaced(List container, List knownAddreses, List constantPool, ScriptExportMode exportMode, GraphTextWriter writer) { + writer.appendNoHilight(getASMSource(container, knownAddreses, constantPool, exportMode)); return writer; } diff --git a/src/com/jpexs/decompiler/flash/action/ActionList.java b/src/com/jpexs/decompiler/flash/action/ActionList.java index 506a1d8c3..e8f751a17 100644 --- a/src/com/jpexs/decompiler/flash/action/ActionList.java +++ b/src/com/jpexs/decompiler/flash/action/ActionList.java @@ -17,6 +17,7 @@ package com.jpexs.decompiler.flash.action; import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.action.special.ActionNop; import java.util.ArrayList; /** @@ -29,6 +30,29 @@ public class ActionList extends ArrayList { ActionListReader.removeAction(this, index, SWF.DEFAULT_VERSION, true); } + public void removeAction(int index, int count) { + if (size() <= index + count - 1) { + // Can't remove count elements, only size - index is available + count = size() - index; + } + + for (int i = 0; i < count; i++) { + ActionListReader.removeAction(this, index, SWF.DEFAULT_VERSION, true); + } + } + + public void addAction(int index, Action action) { + ActionListReader.removeAction(this, index, SWF.DEFAULT_VERSION, true); + } + + public void removeNops() { + for (int i = 0; i < size(); i++) { + if (get(i) instanceof ActionNop) { + removeAction(i); + } + } + } + public Action getByAddress(long address) { for (Action action : this) { if (action.getAddress() == address) { diff --git a/src/com/jpexs/decompiler/flash/action/ActionListReader.java b/src/com/jpexs/decompiler/flash/action/ActionListReader.java index 81d43b48f..2713d8895 100644 --- a/src/com/jpexs/decompiler/flash/action/ActionListReader.java +++ b/src/com/jpexs/decompiler/flash/action/ActionListReader.java @@ -90,7 +90,7 @@ public class ActionListReader { * @throws java.lang.InterruptedException * @throws java.util.concurrent.TimeoutException */ - public static List readActionListTimeout(final List listeners, final SWFInputStream sis, final int version, final int ip, final int endIp, final String path) throws IOException, InterruptedException, TimeoutException { + public static ActionList readActionListTimeout(final List listeners, final SWFInputStream sis, final int version, final int ip, final int endIp, final String path) throws IOException, InterruptedException, TimeoutException { try { ActionList actions = CancellableWorker.call(new Callable() { @@ -111,7 +111,7 @@ public class ActionListReader { Logger.getLogger(ActionListReader.class.getName()).log(Level.SEVERE, null, ex); } } - return new ArrayList<>(); + return new ActionList(); } /** @@ -180,7 +180,8 @@ public class ActionListReader { Map jumps = new HashMap<>(); getJumps(actions, jumps); - long endAddress = updateAddresses(actions, 0, version); + updateActionLengths(actions, version); + long endAddress = updateAddresses(actions, 0); // add end action Action lastAction = actions.get(actions.size() - 1); @@ -194,17 +195,16 @@ public class ActionListReader { updateJumps(actions, jumps, containerLastActions, endAddress); updateActionStores(actions, jumps); - updateActionLengths(actions, version); updateContainerSizes(actions, containerLastActions); if (SWFDecompilerPlugin.listener != null) { try { SWFDecompilerPlugin.listener.actionListParsed(actions); - updateAddresses(actions, 0, version); + updateActionLengths(actions, version); + updateAddresses(actions, 0); updateJumps(actions, jumps, containerLastActions, endAddress); updateActionStores(actions, jumps); - updateActionLengths(actions, version); updateContainerSizes(actions, containerLastActions); } catch (Throwable e) { View.showMessageDialog(null, "Failed to call plugin method actionListParsed. Exception: " + e.getMessage()); @@ -297,7 +297,7 @@ public class ActionListReader { new HashMap>(), version, 0, maxRecursionLevel); - List ret = new ArrayList<>(); + ActionList ret = new ActionList(); Action last = null; for (Action a : retdups) { if (a != last) { @@ -305,7 +305,7 @@ public class ActionListReader { } last = a; } - ret = Action.removeNops(0, ret, version, path); + ret.removeNops(); ActionList reta = new ActionList(); for (Object o : ret) { if (o instanceof Action) { @@ -403,11 +403,11 @@ public class ActionListReader { } } - private static long updateAddresses(List actions, long address, int version) { + private static long updateAddresses(List actions, long address) { for (int i = 0; i < actions.size(); i++) { Action a = actions.get(i); a.setAddress(address); - int length = a.getBytesLength(version); + int length = a.getTotalActionLength(); if ((i != actions.size() - 1) && (a instanceof ActionEnd)) { // placeholder for jump action length = new ActionDeobfuscateJump(0).getTotalActionLength(); @@ -419,9 +419,7 @@ public class ActionListReader { private static void updateActionLengths(List actions, int version) { for (int i = 0; i < actions.size(); i++) { - Action a = actions.get(i); - int length = a.getBytesLength(version); - a.actionLength = length - 1 - ((a.actionCode >= 0x80) ? 2 : 0); + actions.get(i).updateLength(version); } } @@ -538,6 +536,7 @@ public class ActionListReader { /** * Removes an action from the action list, and updates all references + * This method will keep the inner actions of the container when you remove the container * * @param actions * @param index @@ -596,10 +595,10 @@ public class ActionListReader { actions.remove(index); - updateAddresses(actions, startIp, version); + updateActionLengths(actions, version); + updateAddresses(actions, startIp); updateJumps(actions, jumps, containerLastActions, endAddress); updateActionStores(actions, jumps); - updateActionLengths(actions, version); updateContainerSizes(actions, containerLastActions); return true; @@ -745,7 +744,7 @@ public class ActionListReader { } if (debugMode) { - String atos = a.getASMSource(new ArrayList(), new ArrayList(), cpool.constants, version, ScriptExportMode.PCODE); + String atos = a.getASMSource(new ArrayList(), new ArrayList(), cpool.constants, ScriptExportMode.PCODE); if (a instanceof GraphSourceItemContainer) { atos = a.toString(); } diff --git a/src/com/jpexs/decompiler/flash/action/parser/pcode/ASMParser.java b/src/com/jpexs/decompiler/flash/action/parser/pcode/ASMParser.java index f8f983d85..1244b08b0 100644 --- a/src/com/jpexs/decompiler/flash/action/parser/pcode/ASMParser.java +++ b/src/com/jpexs/decompiler/flash/action/parser/pcode/ASMParser.java @@ -141,7 +141,7 @@ public class ASMParser { ActionConstantPool cpool = new ActionConstantPool(constantPool); cpool.setAddress(address); - address += cpool.getBytesLength(version); + address += cpool.getTotalActionLength(); list.add(cpool); while (true) { @@ -185,7 +185,7 @@ public class ASMParser { address += 1; } else if (a != null) { a.setAddress(address); - address += a.getBytesLength(version); + address += a.getTotalActionLength(); } if (a instanceof GraphSourceItemContainer) { containers.push((GraphSourceItemContainer) a); @@ -415,6 +415,8 @@ public class ASMParser { } else { throw new ParseException("Unknown instruction name :" + instructionName, lexer.yyline()); } + + a.updateLength(version); return a; } @@ -473,19 +475,21 @@ public class ASMParser { identifier = ((ActionJump) link).identifier; for (Label label : labels) { + ActionJump actionJump = (ActionJump) link; - if (((ActionJump) link).identifier.equals(label.name)) { - ((ActionJump) link).setJumpOffset((int) (label.address - (((ActionJump) link).getAddress() + ((ActionJump) link).getBytesLength(version)))); + if (actionJump.identifier.equals(label.name)) { + actionJump.setJumpOffset((int) (label.address - (actionJump.getAddress() + actionJump.getTotalActionLength()))); found = true; break; } } } else if (link instanceof ActionIf) { - identifier = ((ActionIf) link).identifier; + ActionIf actionIf = (ActionIf) link; + identifier = actionIf.identifier; for (Label label : labels) { - if (((ActionIf) link).identifier.equals(label.name)) { - ((ActionIf) link).setJumpOffset((int) (label.address - (((ActionIf) link).getAddress() + ((ActionIf) link).getBytesLength(version)))); + if (actionIf.identifier.equals(label.name)) { + actionIf.setJumpOffset((int) (label.address - (actionIf.getAddress() + actionIf.getTotalActionLength()))); found = true; break; } diff --git a/src/com/jpexs/decompiler/flash/action/parser/script/ActionSourceGenerator.java b/src/com/jpexs/decompiler/flash/action/parser/script/ActionSourceGenerator.java index aaeb30197..94dc517d4 100644 --- a/src/com/jpexs/decompiler/flash/action/parser/script/ActionSourceGenerator.java +++ b/src/com/jpexs/decompiler/flash/action/parser/script/ActionSourceGenerator.java @@ -157,7 +157,7 @@ public class ActionSourceGenerator implements SourceGenerator { || (((ActionJump) onTrue.get(onTrue.size() - 1)).isBreak)))) { ajmp = new ActionJump(0); ret.add(ajmp); - onTrueLen += ajmp.getBytesLength(SWF.DEFAULT_VERSION); + onTrueLen += ajmp.getTotalActionLength(); } ifaif.setJumpOffset(onTrueLen); byte[] onFalseBytes = Action.actionsToBytes(onFalse, false, SWF.DEFAULT_VERSION); @@ -182,7 +182,7 @@ public class ActionSourceGenerator implements SourceGenerator { private void fixLoop(List code, int breakOffset, int continueOffset) { int pos = 0; for (Action a : code) { - pos += a.getBytesLength(SWF.DEFAULT_VERSION); + pos += a.getTotalActionLength(); if (a instanceof ActionJump) { ActionJump aj = (ActionJump) a; if (aj.isContinue && (continueOffset != Integer.MAX_VALUE)) { @@ -248,7 +248,7 @@ public class ActionSourceGenerator implements SourceGenerator { ret.addAll(doExpr); ActionIf doif = new ActionIf(0); ret.add(doif); - int offset = doBodyLen + doExprLen + doif.getBytesLength(SWF.DEFAULT_VERSION); + int offset = doBodyLen + doExprLen + doif.getTotalActionLength(); doif.setJumpOffset(-offset); fixLoop(doBody, offset, doBodyLen); return ret; @@ -265,7 +265,7 @@ public class ActionSourceGenerator implements SourceGenerator { ActionIf foraif = new ActionIf(0); forExpr.add(foraif); ActionJump forajmp = new ActionJump(0); - int forajmpLen = forajmp.getBytesLength(SWF.DEFAULT_VERSION); + int forajmpLen = forajmp.getTotalActionLength(); int forExprLen = Action.actionsToBytes(forExpr, false, SWF.DEFAULT_VERSION).length; int forBodyLen = Action.actionsToBytes(forBody, false, SWF.DEFAULT_VERSION).length; int forFinalLen = Action.actionsToBytes(forFinalCommands, false, SWF.DEFAULT_VERSION).length; @@ -373,7 +373,7 @@ public class ActionSourceGenerator implements SourceGenerator { jmpPos += exprLengths.get(k).get(m); } } - jmpPos += defJump.getBytesLength(SWF.DEFAULT_VERSION); + jmpPos += defJump.getTotalActionLength(); for (int n = 0; n < i; n++) { jmpPos += caseLengths.get(n); } diff --git a/src/com/jpexs/decompiler/flash/action/swf3/ActionWaitForFrame.java b/src/com/jpexs/decompiler/flash/action/swf3/ActionWaitForFrame.java index 4fe1c6804..b7fa0dcbc 100644 --- a/src/com/jpexs/decompiler/flash/action/swf3/ActionWaitForFrame.java +++ b/src/com/jpexs/decompiler/flash/action/swf3/ActionWaitForFrame.java @@ -56,7 +56,7 @@ public class ActionWaitForFrame extends Action implements ActionStore { } @Override - public String getASMSource(List container, List knownAddreses, List constantPool, int version, ScriptExportMode exportMode) { + public String getASMSource(List container, List knownAddreses, List constantPool, ScriptExportMode exportMode) { String ret = "WaitForFrame " + frame + " " + skipCount; return ret; } diff --git a/src/com/jpexs/decompiler/flash/action/swf4/ActionIf.java b/src/com/jpexs/decompiler/flash/action/swf4/ActionIf.java index 11e18d784..b5e3bd2d9 100644 --- a/src/com/jpexs/decompiler/flash/action/swf4/ActionIf.java +++ b/src/com/jpexs/decompiler/flash/action/swf4/ActionIf.java @@ -75,8 +75,8 @@ public class ActionIf extends Action { } @Override - public String getASMSource(List container, List knownAddreses, List constantPool, int version, ScriptExportMode exportMode) { - String ofsStr = Helper.formatAddress(getAddress() + getBytesLength(version) + offset); + public String getASMSource(List container, List knownAddreses, List constantPool, ScriptExportMode exportMode) { + String ofsStr = Helper.formatAddress(getAddress() + getTotalActionLength() + offset); return "If loc" + ofsStr + (!jumpUsed ? " ;compileTimeIgnore" : (!ignoreUsed ? " ;compileTimeJump" : "")); } @@ -98,8 +98,7 @@ public class ActionIf extends Action { @Override public List getBranches(GraphSource code) { List ret = super.getBranches(code); - int version = ((ActionGraphSource) code).version; - int length = getBytesLength(version); + int length = getTotalActionLength(); int jmp = code.adr2pos(getAddress() + length + offset); int after = code.adr2pos(getAddress() + length); if (jmp == -1) { diff --git a/src/com/jpexs/decompiler/flash/action/swf4/ActionJump.java b/src/com/jpexs/decompiler/flash/action/swf4/ActionJump.java index d423d24ec..2e1487a51 100644 --- a/src/com/jpexs/decompiler/flash/action/swf4/ActionJump.java +++ b/src/com/jpexs/decompiler/flash/action/swf4/ActionJump.java @@ -75,8 +75,8 @@ public class ActionJump extends Action { } @Override - public String getASMSource(List container, List knownAddreses, List constantPool, int version, ScriptExportMode exportMode) { - String ofsStr = Helper.formatAddress(getAddress() + getBytesLength(version) + offset); + public String getASMSource(List container, List knownAddreses, List constantPool, ScriptExportMode exportMode) { + String ofsStr = Helper.formatAddress(getAddress() + getTotalActionLength() + offset); return "Jump loc" + ofsStr; } diff --git a/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java b/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java index 4b9072779..c8c528692 100644 --- a/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java +++ b/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java @@ -231,7 +231,7 @@ public class ActionPush extends Action { } @Override - public GraphTextWriter getASMSourceReplaced(List container, List knownAddreses, List constantPool, int version, ScriptExportMode exportMode, GraphTextWriter writer) { + public GraphTextWriter getASMSourceReplaced(List container, List knownAddreses, List constantPool, ScriptExportMode exportMode, GraphTextWriter writer) { if (replacement == null || replacement.size() < values.size()) { return toString(writer); } diff --git a/src/com/jpexs/decompiler/flash/action/swf4/ActionWaitForFrame2.java b/src/com/jpexs/decompiler/flash/action/swf4/ActionWaitForFrame2.java index 33f6958fe..ae2d093d5 100644 --- a/src/com/jpexs/decompiler/flash/action/swf4/ActionWaitForFrame2.java +++ b/src/com/jpexs/decompiler/flash/action/swf4/ActionWaitForFrame2.java @@ -116,7 +116,7 @@ public class ActionWaitForFrame2 extends Action implements ActionStore { } @Override - public String getASMSource(List container, List knownAddreses, List constantPool, int version, ScriptExportMode exportMode) { + public String getASMSource(List container, List knownAddreses, List constantPool, ScriptExportMode exportMode) { String ret = "WaitForFrame2 " + skipCount; /*for (int i = 0; i < skipped.size(); i++) { if (skipped.get(i) instanceof ActionEnd) { diff --git a/src/com/jpexs/decompiler/flash/action/swf5/ActionDefineFunction.java b/src/com/jpexs/decompiler/flash/action/swf5/ActionDefineFunction.java index c620391b0..a6a255baa 100644 --- a/src/com/jpexs/decompiler/flash/action/swf5/ActionDefineFunction.java +++ b/src/com/jpexs/decompiler/flash/action/swf5/ActionDefineFunction.java @@ -146,7 +146,7 @@ public class ActionDefineFunction extends Action implements GraphSourceItemConta } @Override - public String getASMSource(List container, List knownAddreses, List constantPool, int version, ScriptExportMode exportMode) { + public String getASMSource(List container, List knownAddreses, List constantPool, ScriptExportMode exportMode) { StringBuilder paramStr = new StringBuilder(); for (int i = 0; i < paramNames.size(); i++) { paramStr.append("\"").append(Helper.escapeString(paramNames.get(i))).append("\" "); @@ -156,7 +156,7 @@ public class ActionDefineFunction extends Action implements GraphSourceItemConta } @Override - public GraphTextWriter getASMSourceReplaced(List container, List knownAddreses, List constantPool, int version, ScriptExportMode exportMode, GraphTextWriter writer) { + public GraphTextWriter getASMSourceReplaced(List container, List knownAddreses, List constantPool, ScriptExportMode exportMode, GraphTextWriter writer) { List oldParamNames = paramNames; if (replacedParamNames != null) { paramNames = replacedParamNames; @@ -165,7 +165,7 @@ public class ActionDefineFunction extends Action implements GraphSourceItemConta if (replacedFunctionName != null) { functionName = replacedFunctionName; } - String ret = getASMSource(container, knownAddreses, constantPool, version, exportMode); + String ret = getASMSource(container, knownAddreses, constantPool, exportMode); paramNames = oldParamNames; functionName = oldFunctionName; writer.appendNoHilight(ret); diff --git a/src/com/jpexs/decompiler/flash/action/swf5/ActionWith.java b/src/com/jpexs/decompiler/flash/action/swf5/ActionWith.java index ab0aebf0e..325987e55 100644 --- a/src/com/jpexs/decompiler/flash/action/swf5/ActionWith.java +++ b/src/com/jpexs/decompiler/flash/action/swf5/ActionWith.java @@ -75,7 +75,7 @@ public class ActionWith extends Action implements GraphSourceItemContainer { } @Override - public String getASMSource(List container, List knownAddreses, List constantPool, int version, ScriptExportMode exportMode) { + public String getASMSource(List container, List knownAddreses, List constantPool, ScriptExportMode exportMode) { return "With {"; } diff --git a/src/com/jpexs/decompiler/flash/action/swf7/ActionDefineFunction2.java b/src/com/jpexs/decompiler/flash/action/swf7/ActionDefineFunction2.java index 44c594038..331869632 100644 --- a/src/com/jpexs/decompiler/flash/action/swf7/ActionDefineFunction2.java +++ b/src/com/jpexs/decompiler/flash/action/swf7/ActionDefineFunction2.java @@ -226,7 +226,7 @@ public class ActionDefineFunction2 extends Action implements GraphSourceItemCont } @Override - public GraphTextWriter getASMSourceReplaced(List container, List knownAddreses, List constantPool, int version, ScriptExportMode exportMode, GraphTextWriter writer) { + public GraphTextWriter getASMSourceReplaced(List container, List knownAddreses, List constantPool, ScriptExportMode exportMode, GraphTextWriter writer) { List oldParamNames = paramNames; if (replacedParamNames != null) { paramNames = replacedParamNames; @@ -235,7 +235,7 @@ public class ActionDefineFunction2 extends Action implements GraphSourceItemCont if (replacedFunctionName != null) { functionName = replacedFunctionName; } - String ret = getASMSource(container, knownAddreses, constantPool, version, exportMode); + String ret = getASMSource(container, knownAddreses, constantPool, exportMode); paramNames = oldParamNames; functionName = oldFunctionName; writer.appendNoHilight(ret); @@ -244,7 +244,7 @@ public class ActionDefineFunction2 extends Action implements GraphSourceItemCont } @Override - public String getASMSource(List container, List knownAddreses, List constantPool, int version, ScriptExportMode exportMode) { + public String getASMSource(List container, List knownAddreses, List constantPool, ScriptExportMode exportMode) { StringBuilder paramStr = new StringBuilder(); for (int i = 0; i < paramNames.size(); i++) { paramStr.append(paramRegisters.get(i)).append(" \"").append(Helper.escapeString(paramNames.get(i))).append("\" "); diff --git a/src/com/jpexs/decompiler/flash/action/swf7/ActionTry.java b/src/com/jpexs/decompiler/flash/action/swf7/ActionTry.java index b98d214de..35abd8be9 100644 --- a/src/com/jpexs/decompiler/flash/action/swf7/ActionTry.java +++ b/src/com/jpexs/decompiler/flash/action/swf7/ActionTry.java @@ -148,7 +148,7 @@ public class ActionTry extends Action implements GraphSourceItemContainer { } @Override - public String getASMSource(List container, List knownAddreses, List constantPool, int version, ScriptExportMode exportMode) { + public String getASMSource(List container, List knownAddreses, List constantPool, ScriptExportMode exportMode) { String ret = ""; ret += "Try "; if (catchBlockFlag) { diff --git a/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java b/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java index 1921eb2e8..a4aaa88fa 100644 --- a/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java @@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.abc.CopyOutputStream; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.ActionList; import com.jpexs.decompiler.flash.action.ActionListReader; import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; @@ -165,20 +166,20 @@ public class DefineButtonTag extends ButtonTag implements ASMSource { * @throws java.lang.InterruptedException */ @Override - public List getActions() throws InterruptedException { + public ActionList getActions() throws InterruptedException { try { int prevLength = actionBytes.pos; SWFInputStream rri = new SWFInputStream(swf, actionBytes.array); if (prevLength != 0) { rri.seek(prevLength); } - List list = ActionListReader.readActionListTimeout(listeners, rri, getVersion(), prevLength, prevLength + actionBytes.length, toString()/*FIXME?*/); + ActionList list = ActionListReader.readActionListTimeout(listeners, rri, getVersion(), prevLength, prevLength + actionBytes.length, toString()/*FIXME?*/); return list; } catch (InterruptedException ex) { throw ex; } catch (Exception ex) { Logger.getLogger(DoActionTag.class.getName()).log(Level.SEVERE, null, ex); - return new ArrayList<>(); + return new ActionList(); } } diff --git a/src/com/jpexs/decompiler/flash/tags/DoActionTag.java b/src/com/jpexs/decompiler/flash/tags/DoActionTag.java index 5f124c036..a2c92adb4 100644 --- a/src/com/jpexs/decompiler/flash/tags/DoActionTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DoActionTag.java @@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.DisassemblyListener; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.ActionList; import com.jpexs.decompiler.flash.action.ActionListReader; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; @@ -119,20 +120,20 @@ public class DoActionTag extends Tag implements ASMSource { } @Override - public List getActions() throws InterruptedException { + public ActionList getActions() throws InterruptedException { try { int prevLength = actionBytes.pos; SWFInputStream rri = new SWFInputStream(swf, actionBytes.array); if (prevLength != 0) { rri.seek(prevLength); } - List list = ActionListReader.readActionListTimeout(listeners, rri, getVersion(), prevLength, prevLength + actionBytes.length, toString()/*FIXME?*/); + ActionList list = ActionListReader.readActionListTimeout(listeners, rri, getVersion(), prevLength, prevLength + actionBytes.length, toString()/*FIXME?*/); return list; } catch (InterruptedException ex) { throw ex; } catch (Exception ex) { Logger.getLogger(DoActionTag.class.getName()).log(Level.SEVERE, null, ex); - return new ArrayList<>(); + return new ActionList(); } } diff --git a/src/com/jpexs/decompiler/flash/tags/DoInitActionTag.java b/src/com/jpexs/decompiler/flash/tags/DoInitActionTag.java index 52177af43..090e6baac 100644 --- a/src/com/jpexs/decompiler/flash/tags/DoInitActionTag.java +++ b/src/com/jpexs/decompiler/flash/tags/DoInitActionTag.java @@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.DisassemblyListener; import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.ActionList; import com.jpexs.decompiler.flash.action.ActionListReader; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; @@ -113,20 +114,20 @@ public class DoInitActionTag extends CharacterIdTag implements ASMSource { } @Override - public List getActions() throws InterruptedException { + public ActionList getActions() throws InterruptedException { try { int prevLength = actionBytes.pos; SWFInputStream rri = new SWFInputStream(swf, actionBytes.array); if (prevLength != 0) { rri.seek(prevLength); } - List list = ActionListReader.readActionListTimeout(listeners, rri, getVersion(), prevLength, prevLength + actionBytes.length, toString()/*FIXME?*/); + ActionList list = ActionListReader.readActionListTimeout(listeners, rri, getVersion(), prevLength, prevLength + actionBytes.length, toString()/*FIXME?*/); return list; } catch (InterruptedException ex) { throw ex; } catch (Exception ex) { Logger.getLogger(DoActionTag.class.getName()).log(Level.SEVERE, null, ex); - return new ArrayList<>(); + return new ActionList(); } } diff --git a/src/com/jpexs/decompiler/flash/tags/base/ASMSource.java b/src/com/jpexs/decompiler/flash/tags/base/ASMSource.java index 6f42059be..527df3523 100644 --- a/src/com/jpexs/decompiler/flash/tags/base/ASMSource.java +++ b/src/com/jpexs/decompiler/flash/tags/base/ASMSource.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.tags.base; import com.jpexs.decompiler.flash.DisassemblyListener; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.ActionList; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.flash.tags.Tag; @@ -55,7 +56,7 @@ public interface ASMSource extends TreeItem { * @return List of actions * @throws java.lang.InterruptedException */ - public List getActions() throws InterruptedException; + public ActionList getActions() throws InterruptedException; /** * Sets actions associated with this object diff --git a/src/com/jpexs/decompiler/flash/treenodes/TagNode.java b/src/com/jpexs/decompiler/flash/treenodes/TagNode.java index 577ec55cb..b993580cd 100644 --- a/src/com/jpexs/decompiler/flash/treenodes/TagNode.java +++ b/src/com/jpexs/decompiler/flash/treenodes/TagNode.java @@ -1,192 +1,192 @@ -/* - * Copyright (C) 2010-2014 JPEXS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.decompiler.flash.treenodes; - -import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler; -import com.jpexs.decompiler.flash.EventListener; -import com.jpexs.decompiler.flash.action.Action; -import com.jpexs.decompiler.flash.configuration.Configuration; -import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; -import com.jpexs.decompiler.flash.helpers.FileTextWriter; -import com.jpexs.decompiler.flash.tags.Tag; -import com.jpexs.decompiler.flash.tags.base.ASMSource; -import com.jpexs.decompiler.flash.tags.base.Exportable; -import com.jpexs.decompiler.graph.TranslateException; -import com.jpexs.helpers.CancellableWorker; -import com.jpexs.helpers.Helper; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.logging.Level; -import java.util.logging.Logger; - -public class TagNode extends ContainerNode { - - public TagNode(Tag tag) { - super(tag); - } - - @Override - public Tag getItem() { - return (Tag) item; - } - - public static void setExport(List nodeList, boolean export) { - for (TreeNode node : nodeList) { - node.export = export; - setExport(node.subNodes, export); - } - } - - public static int getTagCountRecursive(List nodeList) { - int count = 0; - - for (TreeNode node : nodeList) { - if (node.subNodes.isEmpty()) { - if ((node.item instanceof ASMSource) && (node.export)) { - count += 1; - } - } else { - count += getTagCountRecursive(node.subNodes); - } - - } - - return count; - } - - public static List exportNodeAS(final AbortRetryIgnoreHandler handler, final List nodeList, final String outdir, final ScriptExportMode exportMode, final EventListener ev) throws IOException { - try { - List result = CancellableWorker.call(new Callable>() { - - @Override - public List call() throws Exception { - AtomicInteger cnt = new AtomicInteger(1); - int totalCount = TagNode.getTagCountRecursive(nodeList); - return exportNodeAS(handler, nodeList, outdir, exportMode, cnt, totalCount, ev); - } - }, Configuration.exportTimeout.get(), TimeUnit.SECONDS); - return result; - } catch (ExecutionException | InterruptedException | TimeoutException ex) { - } - return new ArrayList<>(); - } - - private static List exportNodeAS(AbortRetryIgnoreHandler handler, List nodeList, String outdir, ScriptExportMode exportMode, AtomicInteger index, int count, EventListener ev) throws IOException { - File dir = new File(outdir); - List ret = new ArrayList<>(); - if (!outdir.endsWith(File.separator)) { - outdir += File.separator; - } - List existingNames = new ArrayList<>(); - for (TreeNode node : nodeList) { - String name = ""; - if (node.item instanceof Exportable) { - name = Helper.makeFileName(((Exportable) node.item).getExportFileName()); - } else { - name = Helper.makeFileName(node.item.toString()); - } - int i = 1; - String baseName = name; - while (existingNames.contains(name)) { - i++; - name = baseName + "_" + i; - } - existingNames.add(name); - if (node.subNodes.isEmpty()) { - if ((node.item instanceof ASMSource) && (node.export)) { - boolean retry; - do { - retry = false; - try { - int currentIndex = index.getAndIncrement(); - - if (!dir.exists()) { - if (!dir.mkdirs()) { - if (!dir.exists()) { - throw new IOException("Cannot create directory " + outdir); - } - } - } - - String f = outdir + name + ".as"; - if (ev != null) { - ev.handleEvent("exporting", "Exporting " + currentIndex + "/" + count + " " + f); - } - - long startTime = System.currentTimeMillis(); - - File file = new File(f); - ASMSource asm = ((ASMSource) node.item); - try (FileTextWriter writer = new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(f))) { - if (exportMode == ScriptExportMode.HEX) { - asm.getActionSourcePrefix(writer); - asm.getActionBytesAsHex(writer); - asm.getActionSourceSuffix(writer); - } else if (exportMode != ScriptExportMode.AS) { - asm.getActionSourcePrefix(writer); - asm.getASMSource(exportMode, writer, null); - asm.getActionSourceSuffix(writer); - } else { - List as = asm.getActions(); - Action.setActionsAddresses(as, 0, asm.getSwf().version); - Action.actionsToSource(asm, as, ""/*FIXME*/, writer); - } - } - - long stopTime = System.currentTimeMillis(); - - if (ev != null) { - long time = stopTime - startTime; - ev.handleEvent("exported", "Exported " + currentIndex + "/" + count + " " + f + ", " + Helper.formatTimeSec(time)); - } - - ret.add(file); - } catch (InterruptedException ex) { - } catch (IOException | OutOfMemoryError | TranslateException | StackOverflowError ex) { - Logger.getLogger(TagNode.class.getName()).log(Level.SEVERE, "Decompilation error in file: " + name + ".as", ex); - if (handler != null) { - int action = handler.getNewInstance().handle(ex); - switch (action) { - case AbortRetryIgnoreHandler.ABORT: - throw ex; - case AbortRetryIgnoreHandler.RETRY: - retry = true; - break; - case AbortRetryIgnoreHandler.IGNORE: - retry = false; - break; - } - } - } - } while (retry); - } - } else { - ret.addAll(exportNodeAS(handler, node.subNodes, outdir + name, exportMode, index, count, ev)); - } - - } - return ret; - } -} +/* + * Copyright (C) 2010-2014 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.decompiler.flash.treenodes; + +import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler; +import com.jpexs.decompiler.flash.EventListener; +import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; +import com.jpexs.decompiler.flash.helpers.FileTextWriter; +import com.jpexs.decompiler.flash.tags.Tag; +import com.jpexs.decompiler.flash.tags.base.ASMSource; +import com.jpexs.decompiler.flash.tags.base.Exportable; +import com.jpexs.decompiler.graph.TranslateException; +import com.jpexs.helpers.CancellableWorker; +import com.jpexs.helpers.Helper; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class TagNode extends ContainerNode { + + public TagNode(Tag tag) { + super(tag); + } + + @Override + public Tag getItem() { + return (Tag) item; + } + + public static void setExport(List nodeList, boolean export) { + for (TreeNode node : nodeList) { + node.export = export; + setExport(node.subNodes, export); + } + } + + public static int getTagCountRecursive(List nodeList) { + int count = 0; + + for (TreeNode node : nodeList) { + if (node.subNodes.isEmpty()) { + if ((node.item instanceof ASMSource) && (node.export)) { + count += 1; + } + } else { + count += getTagCountRecursive(node.subNodes); + } + + } + + return count; + } + + public static List exportNodeAS(final AbortRetryIgnoreHandler handler, final List nodeList, final String outdir, final ScriptExportMode exportMode, final EventListener ev) throws IOException { + try { + List result = CancellableWorker.call(new Callable>() { + + @Override + public List call() throws Exception { + AtomicInteger cnt = new AtomicInteger(1); + int totalCount = TagNode.getTagCountRecursive(nodeList); + return exportNodeAS(handler, nodeList, outdir, exportMode, cnt, totalCount, ev); + } + }, Configuration.exportTimeout.get(), TimeUnit.SECONDS); + return result; + } catch (ExecutionException | InterruptedException | TimeoutException ex) { + } + return new ArrayList<>(); + } + + private static List exportNodeAS(AbortRetryIgnoreHandler handler, List nodeList, String outdir, ScriptExportMode exportMode, AtomicInteger index, int count, EventListener ev) throws IOException { + File dir = new File(outdir); + List ret = new ArrayList<>(); + if (!outdir.endsWith(File.separator)) { + outdir += File.separator; + } + List existingNames = new ArrayList<>(); + for (TreeNode node : nodeList) { + String name = ""; + if (node.item instanceof Exportable) { + name = Helper.makeFileName(((Exportable) node.item).getExportFileName()); + } else { + name = Helper.makeFileName(node.item.toString()); + } + int i = 1; + String baseName = name; + while (existingNames.contains(name)) { + i++; + name = baseName + "_" + i; + } + existingNames.add(name); + if (node.subNodes.isEmpty()) { + if ((node.item instanceof ASMSource) && (node.export)) { + boolean retry; + do { + retry = false; + try { + int currentIndex = index.getAndIncrement(); + + if (!dir.exists()) { + if (!dir.mkdirs()) { + if (!dir.exists()) { + throw new IOException("Cannot create directory " + outdir); + } + } + } + + String f = outdir + name + ".as"; + if (ev != null) { + ev.handleEvent("exporting", "Exporting " + currentIndex + "/" + count + " " + f); + } + + long startTime = System.currentTimeMillis(); + + File file = new File(f); + ASMSource asm = ((ASMSource) node.item); + try (FileTextWriter writer = new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(f))) { + if (exportMode == ScriptExportMode.HEX) { + asm.getActionSourcePrefix(writer); + asm.getActionBytesAsHex(writer); + asm.getActionSourceSuffix(writer); + } else if (exportMode != ScriptExportMode.AS) { + asm.getActionSourcePrefix(writer); + asm.getASMSource(exportMode, writer, null); + asm.getActionSourceSuffix(writer); + } else { + List as = asm.getActions(); + Action.setActionsAddresses(as, 0); + Action.actionsToSource(asm, as, ""/*FIXME*/, writer); + } + } + + long stopTime = System.currentTimeMillis(); + + if (ev != null) { + long time = stopTime - startTime; + ev.handleEvent("exported", "Exported " + currentIndex + "/" + count + " " + f + ", " + Helper.formatTimeSec(time)); + } + + ret.add(file); + } catch (InterruptedException ex) { + } catch (IOException | OutOfMemoryError | TranslateException | StackOverflowError ex) { + Logger.getLogger(TagNode.class.getName()).log(Level.SEVERE, "Decompilation error in file: " + name + ".as", ex); + if (handler != null) { + int action = handler.getNewInstance().handle(ex); + switch (action) { + case AbortRetryIgnoreHandler.ABORT: + throw ex; + case AbortRetryIgnoreHandler.RETRY: + retry = true; + break; + case AbortRetryIgnoreHandler.IGNORE: + retry = false; + break; + } + } + } + } while (retry); + } + } else { + ret.addAll(exportNodeAS(handler, node.subNodes, outdir + name, exportMode, index, count, ev)); + } + + } + return ret; + } +} diff --git a/src/com/jpexs/decompiler/flash/types/BUTTONCONDACTION.java b/src/com/jpexs/decompiler/flash/types/BUTTONCONDACTION.java index 6be68c779..d08dcbe0a 100644 --- a/src/com/jpexs/decompiler/flash/types/BUTTONCONDACTION.java +++ b/src/com/jpexs/decompiler/flash/types/BUTTONCONDACTION.java @@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.DisassemblyListener; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.ActionList; import com.jpexs.decompiler.flash.action.ActionListReader; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; @@ -184,16 +185,16 @@ public class BUTTONCONDACTION implements ASMSource, Exportable, ContainerItem, S * @throws java.lang.InterruptedException */ @Override - public List getActions() throws InterruptedException { + public ActionList getActions() throws InterruptedException { try { - List list = ActionListReader.readActionListTimeout(listeners, new SWFInputStream(swf, actionBytes), swf.version, 0, -1, toString()/*FIXME?*/); + ActionList list = ActionListReader.readActionListTimeout(listeners, new SWFInputStream(swf, actionBytes), swf.version, 0, -1, toString()/*FIXME?*/); return list; } catch (InterruptedException ex) { throw ex; } catch (Exception ex) { Logger.getLogger(BUTTONCONDACTION.class.getName()).log(Level.SEVERE, null, ex); - return new ArrayList<>(); + return new ActionList(); } } diff --git a/src/com/jpexs/decompiler/flash/types/CLIPACTIONRECORD.java b/src/com/jpexs/decompiler/flash/types/CLIPACTIONRECORD.java index e039810bf..2c29b1168 100644 --- a/src/com/jpexs/decompiler/flash/types/CLIPACTIONRECORD.java +++ b/src/com/jpexs/decompiler/flash/types/CLIPACTIONRECORD.java @@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.DisassemblyListener; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.ActionList; import com.jpexs.decompiler.flash.action.ActionListReader; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; @@ -194,15 +195,15 @@ public class CLIPACTIONRECORD implements ASMSource, Exportable, ContainerItem, S } @Override - public List getActions() throws InterruptedException { + public ActionList getActions() throws InterruptedException { try { - List list = ActionListReader.readActionListTimeout(listeners, new SWFInputStream(swf, actionBytes), swf.version, 0, -1, toString()/*FIXME?*/); + ActionList list = ActionListReader.readActionListTimeout(listeners, new SWFInputStream(swf, actionBytes), swf.version, 0, -1, toString()/*FIXME?*/); return list; } catch (InterruptedException ex) { throw ex; } catch (Exception ex) { Logger.getLogger(BUTTONCONDACTION.class.getName()).log(Level.SEVERE, null, ex); - return new ArrayList<>(); + return new ActionList(); } }