diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/Action.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/Action.java index ee138f876..764400620 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/Action.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/Action.java @@ -55,6 +55,7 @@ import com.jpexs.decompiler.flash.action.swf5.ActionEquals2; import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2; import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.ecma.Null; +import com.jpexs.decompiler.flash.ecma.Undefined; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import com.jpexs.decompiler.flash.helpers.CodeFormatting; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; @@ -925,34 +926,9 @@ public abstract class Action implements GraphSourceItem { this.ignored = ignored; } - private static class Loop { - - public long loopContinue; - - public long loopBreak; - - public int continueCount = 0; - - public int breakCount = 0; - - public Loop(long loopContinue, long loopBreak) { - this.loopContinue = loopContinue; - this.loopBreak = loopBreak; - } - - @Override - public String toString() { - return "[Loop continue:" + loopContinue + ", break:" + loopBreak + "]"; - } - } - - private static void log(String s) { - logger.fine(s); - } - public static List actionsPartToTree(HashMap registerNames, HashMap variables, HashMap functions, TranslateStack stack, List actions, int start, int end, int version, int staticOperation, String path) throws InterruptedException { if (start < actions.size() && (end > 0) && (start > 0)) { - log("Entering " + start + "-" + end + (actions.size() > 0 ? (" (" + actions.get(start).toString() + " - " + actions.get(end == actions.size() ? end - 1 : end) + ")") : "")); + logger.log(Level.FINE, "Entering {0}-{1}{2}", new Object[]{start, end, actions.size() > 0 ? (" (" + actions.get(start).toString() + " - " + actions.get(end == actions.size() ? end - 1 : end) + ")") : ""}); } ActionLocalData localData = new ActionLocalData(registerNames, variables, functions); List output = new ArrayList<>(); @@ -1136,7 +1112,7 @@ public abstract class Action implements GraphSourceItem { ip++; } //output = checkClass(output); - log("Leaving " + start + "-" + end); + logger.log(Level.FINE, "Leaving {0}-{1}", new Object[]{start, end}); return output; } @@ -1357,11 +1333,20 @@ public abstract class Action implements GraphSourceItem { if (o instanceof Long) { return (Long) o; } + if (o instanceof Null) { + return Double.NaN; + } + if (o instanceof Undefined) { + return Double.NaN; + } + if (o instanceof Boolean) { + return (Boolean) o ? 1.0 : 0.0; + } if (o instanceof String) { try { return Double.parseDouble((String) o); } catch (NumberFormatException nfe) { - return 0; + return Double.NaN; } } return 0; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionList.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionList.java index 2e2e277e5..71d48a44a 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionList.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionList.java @@ -79,6 +79,10 @@ public class ActionList extends ArrayList { ActionListReader.addAction(this, index, action, SWF.DEFAULT_VERSION, false, false); } + public void addActions(int index, List actions) { + ActionListReader.addActions(this, index, actions, SWF.DEFAULT_VERSION); + } + public void fixActionList() { ActionListReader.fixActionList(this, null, SWF.DEFAULT_VERSION); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionListReader.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionListReader.java index f0703f3e7..de1b3fea9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionListReader.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionListReader.java @@ -730,6 +730,52 @@ public class ActionListReader { return true; } + /** + * Adds an action to the action list to the specified location, and updates + * all references + * + * @param actions + * @param index + * @param newActions + * @param version + * @return + */ + public static boolean addActions(ActionList actions, int index, List newActions, int version) { + + if (index < 0 || actions.size() < index) { + return false; + } + + long startIp = actions.get(0).getAddress(); + Action lastAction = actions.get(actions.size() - 1); + if (!(lastAction instanceof ActionEnd)) { + Action aEnd = new ActionEnd(); + aEnd.setAddress(lastAction.getAddress() + lastAction.getTotalActionLength()); + actions.add(aEnd); + lastAction = aEnd; + } + + long endAddress = lastAction.getAddress(); + + Map> containerLastActions = new HashMap<>(); + getContainerLastActions(actions, containerLastActions); + + Map jumps = new HashMap<>(); + List tempActions = new ArrayList<>(actions); + tempActions.addAll(newActions); + getJumps(tempActions, jumps); + + actions.addAll(index, newActions); + + updateActionLengths(actions, version); + updateAddresses(actions, startIp); + updateJumps(actions, jumps, containerLastActions, endAddress); + updateActionStores(actions, jumps); + updateContainerSizes(actions, containerLastActions); + + return true; + } + private static Action readActionListAtPos(List listeners, ConstantPool cpool, SWFInputStream sis, Map actions, Map nextOffsets, long ip, long startIp, long endIp, String path, boolean indeterminate, List visitedContainers) throws IOException { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/AsciiToCharActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/AsciiToCharActionItem.java index 345b946d2..664434d64 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/AsciiToCharActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/AsciiToCharActionItem.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.model; import com.jpexs.decompiler.flash.SourceGeneratorLocalData; import com.jpexs.decompiler.flash.action.swf4.ActionAsciiToChar; +import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.CompilationException; import com.jpexs.decompiler.graph.GraphSourceItem; @@ -49,6 +50,16 @@ public class AsciiToCharActionItem extends ActionItem { return ret; } + @Override + public Object getResult() { + Double res = EcmaScript.toNumber(value.getResult()); + if (Double.isNaN(res) || Double.compare(res, 0) == 0) { + return ""; + } + + return ((Character) (char) res.intValue()).toString(); + } + @Override public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { return toSourceMerge(localData, generator, value, new ActionAsciiToChar()); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/DirectValueActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/DirectValueActionItem.java index 0872391cc..d1b63b180 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/DirectValueActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/DirectValueActionItem.java @@ -80,13 +80,12 @@ public class DirectValueActionItem extends ActionItem implements SimpleValue { if (value instanceof Float) { return (double) (Float) value; } - if (value instanceof Long) { - return (double) (Long) value; + if (value instanceof Long || value instanceof Integer || value instanceof Short || value instanceof Byte) { + return ((Number) value).doubleValue(); } if (value instanceof Boolean) { return value; } - if (value instanceof String) { return value; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/MBAsciiToCharActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/MBAsciiToCharActionItem.java index 2a8e1ee13..87ac0e30b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/MBAsciiToCharActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/MBAsciiToCharActionItem.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.model; import com.jpexs.decompiler.flash.SourceGeneratorLocalData; import com.jpexs.decompiler.flash.action.swf4.ActionMBAsciiToChar; +import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.CompilationException; import com.jpexs.decompiler.graph.GraphSourceItem; @@ -49,6 +50,16 @@ public class MBAsciiToCharActionItem extends ActionItem { return ret; } + @Override + public Object getResult() { + Double res = EcmaScript.toNumber(value.getResult()); + if (Double.isNaN(res) || Double.compare(res, 0) == 0) { + return ""; + } + + return ((Character) (char) res.intValue()).toString(); + } + @Override public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { return toSourceMerge(localData, generator, value, new ActionMBAsciiToChar()); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/MBStringLengthActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/MBStringLengthActionItem.java index 42788bc2f..974d9ccba 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/MBStringLengthActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/MBStringLengthActionItem.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.model; import com.jpexs.decompiler.flash.SourceGeneratorLocalData; import com.jpexs.decompiler.flash.action.swf4.ActionMBStringLength; +import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.CompilationException; import com.jpexs.decompiler.graph.GraphSourceItem; @@ -56,6 +57,11 @@ public class MBStringLengthActionItem extends ActionItem { return ret; } + @Override + public Object getResult() { + return EcmaScript.toNumber(EcmaScript.toString(value.getResult()).length()); + } + @Override public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { return toSourceMerge(localData, generator, value, new ActionMBStringLength()); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/StringLengthActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/StringLengthActionItem.java index 006c06fb8..9a9b98b2b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/StringLengthActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/StringLengthActionItem.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.model; import com.jpexs.decompiler.flash.SourceGeneratorLocalData; import com.jpexs.decompiler.flash.action.swf4.ActionStringLength; +import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.CompilationException; import com.jpexs.decompiler.graph.GraphSourceItem; @@ -48,6 +49,11 @@ public class StringLengthActionItem extends ActionItem { return false; } + @Override + public Object getResult() { + return EcmaScript.toNumber(EcmaScript.toString(value.getResult()).length()); + } + @Override public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { return toSourceMerge(localData, generator, value, new ActionStringLength()); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/ToIntegerActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/ToIntegerActionItem.java index 11e24d9c7..66929a8ac 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/ToIntegerActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/ToIntegerActionItem.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.model; import com.jpexs.decompiler.flash.SourceGeneratorLocalData; import com.jpexs.decompiler.flash.action.swf4.ActionToInteger; +import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.CompilationException; import com.jpexs.decompiler.graph.GraphSourceItem; @@ -49,6 +50,11 @@ public class ToIntegerActionItem extends ActionItem { return ret; } + @Override + public Object getResult() { + return Math.round(EcmaScript.toNumber(value.getResult())); + } + @Override public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { return toSourceMerge(localData, generator, value, new ActionToInteger()); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/ToNumberActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/ToNumberActionItem.java index 862b526bd..5a06d8904 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/ToNumberActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/ToNumberActionItem.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.model; import com.jpexs.decompiler.flash.SourceGeneratorLocalData; import com.jpexs.decompiler.flash.action.swf5.ActionToNumber; +import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.CompilationException; import com.jpexs.decompiler.graph.GraphSourceItem; @@ -49,6 +50,11 @@ public class ToNumberActionItem extends ActionItem { return ret; } + @Override + public Object getResult() { + return EcmaScript.toNumber(value.getResult()); + } + @Override public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { return toSourceMerge(localData, generator, value, new ActionToNumber()); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/ToStringActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/ToStringActionItem.java index 459549a06..2ab1a02ee 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/ToStringActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/ToStringActionItem.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.model; import com.jpexs.decompiler.flash.SourceGeneratorLocalData; import com.jpexs.decompiler.flash.action.swf5.ActionToString; +import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.CompilationException; import com.jpexs.decompiler.graph.GraphSourceItem; @@ -49,6 +50,11 @@ public class ToStringActionItem extends ActionItem { return ret; } + @Override + public Object getResult() { + return EcmaScript.toString(value.getResult()); + } + @Override public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { return toSourceMerge(localData, generator, value, new ActionToString()); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/AddActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/AddActionItem.java index 421ee35af..fb74d9eaf 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/AddActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/AddActionItem.java @@ -67,7 +67,7 @@ public class AddActionItem extends BinaryOpItem { Object leftResult = leftSide.getResult(); Object rightResult = rightSide.getResult(); if (EcmaScript.type(leftResult) == EcmaType.STRING || EcmaScript.type(rightResult) == EcmaType.STRING) { - return "" + leftResult + rightResult; + return EcmaScript.toString(leftResult) + EcmaScript.toString(rightResult); } return EcmaScript.toNumber(leftResult) + EcmaScript.toNumber(rightResult); } else { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/DivideActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/DivideActionItem.java index 5a9901da2..1905188d5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/DivideActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/DivideActionItem.java @@ -35,11 +35,13 @@ public class DivideActionItem extends BinaryOpItem { @Override public Object getResult() { - Object rightResult = rightSide.getResult(); - if (Double.compare(EcmaScript.toNumber(rightResult), 0) == 0) { - return Double.NaN; + Double leftResult = EcmaScript.toNumber(leftSide.getResult()); + Double rightResult = EcmaScript.toNumber(rightSide.getResult()); + if (Double.compare(rightResult, 0) == 0) { + return leftResult < 0 ? Double.NEGATIVE_INFINITY + : leftResult > 0 ? Double.POSITIVE_INFINITY : Double.NaN; } - return (EcmaScript.toNumber(leftSide.getResult())) / (EcmaScript.toNumber(rightResult)); + return leftResult / rightResult; } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/ModuloActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/ModuloActionItem.java index fb8fc0b17..50397792e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/ModuloActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/ModuloActionItem.java @@ -35,11 +35,11 @@ public class ModuloActionItem extends BinaryOpItem { @Override public Object getResult() { - Object rightResult = rightSide.getResult(); - if (Double.compare(EcmaScript.toNumber(rightResult), 0) == 0) { + Double rightResult = EcmaScript.toNumber(rightSide.getResult()); + if (Double.isNaN(rightResult) || Double.compare(rightResult, 0) == 0) { return Double.NaN; } - return ((long) (double) EcmaScript.toNumber(leftSide.getResult())) % ((long) (double) EcmaScript.toNumber(rightResult)); + return ((long) (double) EcmaScript.toNumber(leftSide.getResult())) % ((long) (double) rightResult); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/RShiftActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/RShiftActionItem.java index 69f368b1b..3d5512c75 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/RShiftActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/RShiftActionItem.java @@ -1,18 +1,19 @@ /* * Copyright (C) 2010-2015 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. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.action.model.operations; import com.jpexs.decompiler.flash.SourceGeneratorLocalData; @@ -34,7 +35,8 @@ public class RShiftActionItem extends BinaryOpItem { @Override public Object getResult() { - return ((long) (double) EcmaScript.toNumber(leftSide.getResult())) >> ((long) (double) EcmaScript.toNumber(rightSide.getResult())); + long rightResult = ((long) (double) EcmaScript.toNumber(rightSide.getResult())) & 0x1f; + return ((long) (double) EcmaScript.toNumber(leftSide.getResult())) >> rightResult; } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringAddActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringAddActionItem.java index 773d9b9d7..35394e840 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringAddActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringAddActionItem.java @@ -1,22 +1,24 @@ /* * Copyright (C) 2010-2015 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. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.action.model.operations; import com.jpexs.decompiler.flash.SourceGeneratorLocalData; import com.jpexs.decompiler.flash.action.swf4.ActionStringAdd; +import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.graph.CompilationException; import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphTargetItem; @@ -37,6 +39,11 @@ public class StringAddActionItem extends BinaryOpItem { return false; } + @Override + public Object getResult() { + return EcmaScript.toString(leftSide.getResult()) + EcmaScript.toString(rightSide.getResult()); + } + @Override public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { return toSourceMerge(localData, generator, leftSide, rightSide, new ActionStringAdd()); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringEqActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringEqActionItem.java index 9f597212e..2383bc1d2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringEqActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringEqActionItem.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.model.operations; import com.jpexs.decompiler.flash.SourceGeneratorLocalData; import com.jpexs.decompiler.flash.action.swf4.ActionStringEquals; +import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.graph.CompilationException; import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphTargetItem; @@ -38,6 +39,11 @@ public class StringEqActionItem extends BinaryOpItem implements Inverted { return false; } + @Override + public Object getResult() { + return EcmaScript.toString(leftSide.getResult()).equals(EcmaScript.toString(rightSide.getResult())); + } + @Override public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { return toSourceMerge(localData, generator, leftSide, rightSide, new ActionStringEquals()); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringGeActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringGeActionItem.java index db75106be..d0385bb41 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringGeActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringGeActionItem.java @@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.action.model.operations; import com.jpexs.decompiler.flash.SourceGeneratorLocalData; import com.jpexs.decompiler.flash.action.swf4.ActionNot; import com.jpexs.decompiler.flash.action.swf4.ActionStringLess; +import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.graph.CompilationException; import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphTargetItem; @@ -39,6 +40,11 @@ public class StringGeActionItem extends BinaryOpItem implements Inverted { return false; } + @Override + public Object getResult() { + return EcmaScript.toString(leftSide.getResult()).compareTo(EcmaScript.toString(rightSide.getResult())) >= 0; + } + @Override public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { return toSourceMerge(localData, generator, leftSide, rightSide, new ActionStringLess(), new ActionNot()); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringGtActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringGtActionItem.java index 0adda02c5..2b9124abf 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringGtActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringGtActionItem.java @@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.SourceGeneratorLocalData; import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator; import com.jpexs.decompiler.flash.action.swf4.ActionStringLess; import com.jpexs.decompiler.flash.action.swf6.ActionStringGreater; +import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.graph.CompilationException; import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphTargetItem; @@ -40,6 +41,11 @@ public class StringGtActionItem extends BinaryOpItem implements Inverted { return false; } + @Override + public Object getResult() { + return EcmaScript.toString(leftSide.getResult()).compareTo(EcmaScript.toString(rightSide.getResult())) > 0; + } + @Override public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { ActionSourceGenerator g = (ActionSourceGenerator) generator; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringLeActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringLeActionItem.java index 265c537de..d038be643 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringLeActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringLeActionItem.java @@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.action.parser.script.ActionSourceGenerator; import com.jpexs.decompiler.flash.action.swf4.ActionNot; import com.jpexs.decompiler.flash.action.swf4.ActionStringLess; import com.jpexs.decompiler.flash.action.swf6.ActionStringGreater; +import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.graph.CompilationException; import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphTargetItem; @@ -41,6 +42,11 @@ public class StringLeActionItem extends BinaryOpItem implements Inverted { return false; } + @Override + public Object getResult() { + return EcmaScript.toString(leftSide.getResult()).compareTo(EcmaScript.toString(rightSide.getResult())) <= 0; + } + @Override public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringLtActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringLtActionItem.java index 7049b5837..cf1abc409 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringLtActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/StringLtActionItem.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.action.model.operations; import com.jpexs.decompiler.flash.SourceGeneratorLocalData; import com.jpexs.decompiler.flash.action.swf4.ActionStringLess; +import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.graph.CompilationException; import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphTargetItem; @@ -38,6 +39,11 @@ public class StringLtActionItem extends BinaryOpItem implements Inverted { return false; } + @Override + public Object getResult() { + return EcmaScript.toString(leftSide.getResult()).compareTo(EcmaScript.toString(rightSide.getResult())) < 0; + } + @Override public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { return toSourceMerge(localData, generator, leftSide, rightSide, new ActionStringLess()); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/URShiftActionItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/URShiftActionItem.java index 1745edddc..b0ae31e4a 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/URShiftActionItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/model/operations/URShiftActionItem.java @@ -1,18 +1,19 @@ /* * Copyright (C) 2010-2015 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. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.action.model.operations; import com.jpexs.decompiler.flash.SourceGeneratorLocalData; @@ -34,7 +35,9 @@ public class URShiftActionItem extends BinaryOpItem { @Override public Object getResult() { - return ((long) (double) EcmaScript.toNumber(leftSide.getResult())) >>> ((long) (double) EcmaScript.toNumber(rightSide.getResult())); + long leftResult = ((long) (double) EcmaScript.toNumber(leftSide.getResult())) & 0xffffffffL; + long rightResult = ((long) (double) EcmaScript.toNumber(rightSide.getResult())) & 0x1f; + return leftResult >>> rightResult; } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java index c29232c5f..a537c36f6 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java @@ -154,19 +154,19 @@ public class ActionPush extends Action { } else if (o instanceof Boolean) { sos.writeUI8(5); sos.writeUI8((Boolean) o ? 1 : 0); - } else if (o instanceof Double || o instanceof Long) { + } else if (o instanceof Number) { if (o instanceof Long) { long l = (Long) o; if (l < -0x80000000 || l > 0x7fffffff) { o = (double) l; } } - if (o instanceof Double) { + if (o instanceof Double || o instanceof Float) { sos.writeUI8(6); - sos.writeDOUBLE((Double) o); - } else if (o instanceof Long) { + sos.writeDOUBLE(((Number) o).doubleValue()); + } else if (o instanceof Long || o instanceof Integer || o instanceof Short || o instanceof Byte) { sos.writeUI8(7); - sos.writeSI32((Long) o); + sos.writeSI32(((Number) o).longValue()); } } else if (o instanceof ConstantIndex) { int cIndex = ((ConstantIndex) o).index; @@ -202,16 +202,16 @@ public class ActionPush extends Action { res += 2; } else if (o instanceof Boolean) { res += 2; - } else if (o instanceof Double || o instanceof Long) { + } else if (o instanceof Number) { if (o instanceof Long) { long l = (Long) o; if (l < -0x80000000 || l > 0x7fffffff) { o = (double) l; } } - if (o instanceof Double) { + if (o instanceof Double || o instanceof Float) { res += 9; - } else if (o instanceof Long) { + } else if (o instanceof Long || o instanceof Integer || o instanceof Short || o instanceof Byte) { res += 5; } } else if (o instanceof ConstantIndex) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/ecma/EcmaFloatingDecimal.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/ecma/EcmaFloatingDecimal.java index 28d6336a9..608cccbfe 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/ecma/EcmaFloatingDecimal.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/ecma/EcmaFloatingDecimal.java @@ -13,8 +13,9 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library. - */ -/* + * + * ----------------- Original copyright -------------------------- + * * Copyright 1996-2004 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -134,8 +135,7 @@ public class EcmaFloatingDecimal { * count number of bits from high-order 1 bit to low-order 1 bit, * inclusive. */ - private static int - countBits(long v) { + private static int countBits(long v) { // // the strategy is to shift until we get a non-zero sign bit // then shift until we have no bits left, counting the difference. @@ -213,8 +213,7 @@ public class EcmaFloatingDecimal { // // a common operation // - private static FDBigInt - multPow52(FDBigInt v, int p5, int p2) { + private static FDBigInt multPow52(FDBigInt v, int p5, int p2) { if (p5 != 0) { if (p5 < small5pow.length) { v = v.mult(small5pow[p5]); @@ -249,8 +248,7 @@ public class EcmaFloatingDecimal { * bigIntExp and bigIntNBits * */ - private FDBigInt - doubleToBigInt(double dval) { + private FDBigInt doubleToBigInt(double dval) { long lbits = Double.doubleToLongBits(dval) & ~signMask; int binexp = (int) (lbits >>> expShift); lbits &= fractMask; @@ -926,6 +924,17 @@ public class EcmaFloatingDecimal { roundup(); } } + + if (nDigits > 15) { + nDigits = 15; + if (digits[15] >= '5') { + roundup(); + } + + while (nDigits > 0 && digits[nDigits - 1] == '0') { + nDigits--; + } + } } public String toString() { @@ -954,7 +963,7 @@ public class EcmaFloatingDecimal { private int getChars(char[] result) { assert nDigits <= 19 : nDigits; // generous bound on size of nDigits int i = 0; - if (isNegative) { + if (isNegative && (decExponent != 0 || digits != zero)) { result[0] = '-'; i = 1; } @@ -1253,8 +1262,7 @@ class FDBigInt { * Left shift by c bits. * Shifts this in place. */ - public void - lshiftMe(int c) throws IllegalArgumentException { + public void lshiftMe(int c) throws IllegalArgumentException { if (c <= 0) { if (c == 0) { return; // silly. @@ -1307,8 +1315,7 @@ class FDBigInt { * the dividend not span up into another word of precision. * (This needs to be explained more clearly!) */ - public int - normalizeMe() throws IllegalArgumentException { + public int normalizeMe() throws IllegalArgumentException { int src; int wordcount = 0; int bitcount = 0; @@ -1359,8 +1366,7 @@ class FDBigInt { * Multiply a FDBigInt by an int. * Result is a new FDBigInt. */ - public FDBigInt - mult(int iv) { + public FDBigInt mult(int iv) { long v = iv; int r[]; long p; @@ -1386,8 +1392,7 @@ class FDBigInt { * Result is computed in place. * Hope it fits! */ - public void - multaddMe(int iv, int addend) { + public void multaddMe(int iv, int addend) { long v = iv; long p; @@ -1410,8 +1415,7 @@ class FDBigInt { * Multiply a FDBigInt by another FDBigInt. * Result is a new FDBigInt. */ - public FDBigInt - mult(FDBigInt other) { + public FDBigInt mult(FDBigInt other) { // crudely guess adequate size for r int r[] = new int[nWords + other.nWords]; int i; @@ -1440,8 +1444,7 @@ class FDBigInt { /* * Add one FDBigInt to another. Return a FDBigInt */ - public FDBigInt - add(FDBigInt other) { + public FDBigInt add(FDBigInt other) { int i; int a[], b[]; int n, m; @@ -1482,8 +1485,7 @@ class FDBigInt { * Subtract one FDBigInt from another. Return a FDBigInt * Assert that the result is positive. */ - public FDBigInt - sub(FDBigInt other) { + public FDBigInt sub(FDBigInt other) { int r[] = new int[this.nWords]; int i; int n = this.nWords; @@ -1522,8 +1524,7 @@ class FDBigInt { * 0: this == other * <0: this < other */ - public int - cmp(FDBigInt other) { + public int cmp(FDBigInt other) { int i; if (this.nWords > other.nWords) { // if any of my high-order words is non-zero, @@ -1584,8 +1585,7 @@ class FDBigInt { * Also assume, of course, that the result, q, can be expressed * as an integer, 0 <= q < 10. */ - public int - quoRemIteration(FDBigInt S) throws IllegalArgumentException { + public int quoRemIteration(FDBigInt S) throws IllegalArgumentException { // ensure that this and S have the same number of // digits. If S is properly normalized and q < 10 then // this must be so. @@ -1641,8 +1641,7 @@ class FDBigInt { return (int) q; } - public long - longValue() { + public long longValue() { // if this can be represented as a long, return the value assert this.nWords > 0 : this.nWords; // longValue confused @@ -1655,8 +1654,7 @@ class FDBigInt { return ((long) (data[1]) << 32) | ((long) data[0] & 0xffffffffL); } - public String - toString() { + public String toString() { StringBuffer r = new StringBuffer(30); r.append('['); int i = Math.min(nWords - 1, data.length - 1); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/ecma/EcmaScript.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/ecma/EcmaScript.java index 71bfc8c70..0855d9415 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/ecma/EcmaScript.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/ecma/EcmaScript.java @@ -30,7 +30,7 @@ public class EcmaScript { return Double.NaN; } if (o instanceof Null) { - return 0.0; + return Double.NaN; } if (o instanceof Boolean) { return (Boolean) o ? 1.0 : 0.0; diff --git a/test/com/jpexs/decompiler/flash/gui/FlashPlayerTest.java b/test/com/jpexs/decompiler/flash/gui/FlashPlayerTest.java index 90780a452..4dd59df7e 100644 --- a/test/com/jpexs/decompiler/flash/gui/FlashPlayerTest.java +++ b/test/com/jpexs/decompiler/flash/gui/FlashPlayerTest.java @@ -19,15 +19,75 @@ package com.jpexs.decompiler.flash.gui; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.action.Action; +import com.jpexs.decompiler.flash.action.ActionList; +import com.jpexs.decompiler.flash.action.ActionLocalData; +import com.jpexs.decompiler.flash.action.deobfuscation.FixItemCounterTranslateStack; +import com.jpexs.decompiler.flash.action.swf4.ActionAdd; +import com.jpexs.decompiler.flash.action.swf4.ActionAnd; +import com.jpexs.decompiler.flash.action.swf4.ActionAsciiToChar; +import com.jpexs.decompiler.flash.action.swf4.ActionCharToAscii; +import com.jpexs.decompiler.flash.action.swf4.ActionDivide; +import com.jpexs.decompiler.flash.action.swf4.ActionEquals; +import com.jpexs.decompiler.flash.action.swf4.ActionLess; +import com.jpexs.decompiler.flash.action.swf4.ActionMBAsciiToChar; +import com.jpexs.decompiler.flash.action.swf4.ActionMBStringExtract; +import com.jpexs.decompiler.flash.action.swf4.ActionMBStringLength; +import com.jpexs.decompiler.flash.action.swf4.ActionMultiply; +import com.jpexs.decompiler.flash.action.swf4.ActionNot; +import com.jpexs.decompiler.flash.action.swf4.ActionOr; +import com.jpexs.decompiler.flash.action.swf4.ActionPush; +import com.jpexs.decompiler.flash.action.swf4.ActionStringAdd; +import com.jpexs.decompiler.flash.action.swf4.ActionStringExtract; +import com.jpexs.decompiler.flash.action.swf4.ActionStringLength; +import com.jpexs.decompiler.flash.action.swf4.ActionStringLess; +import com.jpexs.decompiler.flash.action.swf4.ActionToInteger; +import com.jpexs.decompiler.flash.action.swf5.ActionAdd2; +import com.jpexs.decompiler.flash.action.swf5.ActionBitAnd; +import com.jpexs.decompiler.flash.action.swf5.ActionBitLShift; +import com.jpexs.decompiler.flash.action.swf5.ActionBitOr; +import com.jpexs.decompiler.flash.action.swf5.ActionBitRShift; +import com.jpexs.decompiler.flash.action.swf5.ActionBitURShift; +import com.jpexs.decompiler.flash.action.swf5.ActionBitXor; +import com.jpexs.decompiler.flash.action.swf5.ActionDecrement; +import com.jpexs.decompiler.flash.action.swf5.ActionEquals2; +import com.jpexs.decompiler.flash.action.swf5.ActionIncrement; +import com.jpexs.decompiler.flash.action.swf5.ActionLess2; +import com.jpexs.decompiler.flash.action.swf5.ActionModulo; +import com.jpexs.decompiler.flash.action.swf5.ActionPushDuplicate; +import com.jpexs.decompiler.flash.action.swf5.ActionToNumber; +import com.jpexs.decompiler.flash.action.swf5.ActionToString; +import com.jpexs.decompiler.flash.action.swf5.ActionTypeOf; +import com.jpexs.decompiler.flash.action.swf6.ActionGreater; +import com.jpexs.decompiler.flash.action.swf6.ActionStrictEquals; +import com.jpexs.decompiler.flash.action.swf6.ActionStringGreater; +import com.jpexs.decompiler.flash.ecma.Null; +import com.jpexs.decompiler.flash.ecma.Undefined; import com.jpexs.decompiler.flash.tags.DoABC2Tag; import com.jpexs.decompiler.flash.tags.Tag; +import com.jpexs.decompiler.flash.tags.base.ASMSource; +import com.jpexs.decompiler.graph.Graph; +import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.javactivex.ActiveX; +import com.jpexs.javactivex.ActiveXEvent; +import com.jpexs.javactivex.ActiveXEventListener; +import com.jpexs.javactivex.Reference; import com.jpexs.javactivex.example.controls.flash.ShockwaveFlash; import java.awt.Panel; import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Random; import org.testng.Assert; +import org.testng.annotations.Test; /** * @@ -35,10 +95,15 @@ import org.testng.Assert; */ public class FlashPlayerTest { + private Object lockObj = new Object(); + + private Random random = new Random(); + //@Test public void test1() throws IOException, InterruptedException { ShockwaveFlash flash = ActiveX.createObject(ShockwaveFlash.class, new Panel()); - SWF swf = new SWF(new BufferedInputStream(new FileInputStream("libsrc/ffdec_lib/testdata/run_as3/run.swf")), false); + File f = new File("libsrc/ffdec_lib/testdata/run_as3/run.swf"); + SWF swf = new SWF(new BufferedInputStream(new FileInputStream(f)), false); DoABC2Tag abcTag = null; for (Tag t : swf.tags) { if (t instanceof DoABC2Tag) { @@ -49,7 +114,7 @@ public class FlashPlayerTest { ABC abc = abcTag.getABC(); MethodBody body = abc.findBodyByClassAndName("Run", "run"); - flash.setMovie("libsrc/ffdec_lib/testdata/run_as3/run2.swf"); + flash.setMovie(f.getAbsolutePath()); int cnt = 0; while (flash.getReadyState() != 4) { @@ -63,10 +128,230 @@ public class FlashPlayerTest { flash.setAllowScriptAccess("always"); try { - String res = flash.CallFunction("testFunc"); + String res = flash.CallFunction("something"); + //String str = flash.GetVariable("_root.myText.text"); throw new Error(res + " " + body.getCode().toString() + ""); } catch (Exception ex) { int a = 1; } } + + @Test + public void testAs2() throws IOException, InterruptedException { + final Reference resultRef = new Reference<>(null); + + ShockwaveFlash flash = ActiveX.createObject(ShockwaveFlash.class, new Panel()); + flash.setAllowScriptAccess("always"); + flash.setAllowNetworking("all"); + flash.addFSCommandListener(new ActiveXEventListener() { + + @Override + public void onEvent(ActiveXEvent axe) { + resultRef.setVal((String) axe.args.get("args")); + System.out.println("Flash event"); + synchronized (lockObj) { + lockObj.notify(); + } + } + }); + + for (int i = 0; i < 15; i++) { + for (int j = 0; j < 12 + 22; j++) { + + File f = new File("libsrc/ffdec_lib/testdata/run_as2/run_as2.swf"); + File f2 = new File("run_test_" + new Date().getTime() + "_" + i + ".swf"); + f2.deleteOnExit(); + + SWF swf = new SWF(new BufferedInputStream(new FileInputStream(f)), false); + Map asms = swf.getASMs(true); + ASMSource asm = asms.get("\\frame_1\\DoAction"); + ActionList actions = asm.getActions(); + actions.removeAction(2, 4); + + List newActions = new ArrayList<>(); + int r1 = random.nextInt(500) - 255; + int r2 = random.nextInt(100); + + /*i = 9; + j = 21; + r1 = 212; + r2 = 3;*/ + Action opAction = getOpAction(j); + + if (j >= 12) { + newActions.add(new ActionPush(r1)); + } + + if (i == 0) { + newActions.add(new ActionPush(Undefined.INSTANCE)); + } else if (i == 1) { + newActions.add(new ActionPush(Null.INSTANCE)); + } else if (i == 2) { + newActions.add(new ActionPush(false)); + } else if (i == 3) { + newActions.add(new ActionPush(true)); + } else if (i == 4) { + newActions.add(new ActionPush("test")); + } else if (i == 5) { + newActions.add(new ActionPush("0")); + } else if (i == 6) { + newActions.add(new ActionPush("0.0")); + } else if (i == 7) { + newActions.add(new ActionPush("1.0")); + } else if (i == 8) { + newActions.add(new ActionPush("-1.0")); + } else if (i == 9) { + newActions.add(new ActionPush(0)); + } else if (i == 10) { + newActions.add(new ActionPush(-100)); + } else if (i == 11) { + newActions.add(new ActionPush(100)); + } else { + newActions.add(new ActionPush(r2)); + } + + System.out.println(i + " " + j + " " + opAction.toString() + " r1:" + r1 + " r2:" + r2); + newActions.add(opAction); + newActions.add(new ActionPushDuplicate()); + newActions.add(new ActionTypeOf()); + newActions.add(new ActionStringAdd()); + actions.addActions(2, newActions); + + List output = new ArrayList<>(); + ActionLocalData localData = new ActionLocalData(); + FixItemCounterTranslateStack stack = new FixItemCounterTranslateStack(""); + for (Action a : newActions) { + a.translate(localData, stack, output, Graph.SOP_USE_STATIC, ""); + } + + Object ffdecResult = stack.pop().getResult(); + System.out.println("FFDec result: " + ffdecResult); + + asm.setActions(actions); + asm.setModified(); + try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(f2))) { + swf.saveTo(fos); + } + flash.setMovie(f2.getAbsolutePath()); + + synchronized (lockObj) { + lockObj.wait(); + } + + String str = flash.GetVariable("myText.text"); + String flashResult = resultRef.getVal(); + Assert.assertEquals(ffdecResult, flashResult); + + f2.delete(); + } + } + } + + private Action getOpAction(int idx) { + Action result; + if (idx < 12) { + result = getUnaryOpAction(idx); + Assert.assertEquals(1, result.getStackPopCount(null, null)); + Assert.assertEquals(1, result.getStackPushCount(null, null)); + } else { + result = getBinaryOpAction(idx - 12); + Assert.assertEquals(2, result.getStackPopCount(null, null)); + Assert.assertEquals(1, result.getStackPushCount(null, null)); + } + + return result; + } + + private Action getUnaryOpAction(int idx) { + switch (idx) { + case 0: + return new ActionAsciiToChar(); + case 1: + return new ActionCharToAscii(); + case 2: + return new ActionDecrement(); + case 3: + return new ActionIncrement(); + case 4: + return new ActionNot(); + case 5: + return new ActionToInteger(); + case 6: + return new ActionToNumber(); + case 7: + return new ActionToString(); + case 8: + return new ActionTypeOf(); + case 9: + return new ActionStringLength(); + case 10: + return new ActionMBAsciiToChar(); + case 11: + return new ActionMBStringLength(); + } + + throw new Error("Invalid index"); + } + + private Action getBinaryOpAction(int idx) { + switch (idx) { + case 0: + return new ActionAnd(); + case 1: + return new ActionAdd(); + case 2: + return new ActionAdd2(); + case 3: + return new ActionBitAnd(); + case 4: + return new ActionBitLShift(); + case 5: + return new ActionBitOr(); + case 6: + return new ActionBitRShift(); + case 7: + return new ActionBitURShift(); + case 8: + return new ActionBitXor(); + case 9: + return new ActionDivide(); + case 10: + return new ActionEquals(); + case 11: + return new ActionEquals2(); + case 12: + return new ActionGreater(); + case 13: + return new ActionLess(); + case 14: + return new ActionLess2(); + case 15: + return new ActionModulo(); + case 16: + return new ActionMultiply(); + case 17: + return new ActionOr(); + case 18: + return new ActionStringAdd(); + case 19: + return new ActionStrictEquals(); + case 20: + return new ActionStringGreater(); + case 21: + return new ActionStringLess(); + } + + throw new Error("Invalid index"); + } + + private Action getTernaryOpAction(int idx) { + switch (idx) { + case 0: + return new ActionStringExtract(); + case 1: + return new ActionMBStringExtract(); + } + + throw new Error("Invalid index"); + } }