Simplify nonif expressions while deobfuscation too

Regexp deobfuscation.
Implicit coercion handling.
#1145 double not (!!) fix
This commit is contained in:
Jindra Petřík
2016-02-07 17:13:59 +01:00
parent f9bdb8a35a
commit ef739fbfd9
110 changed files with 1261 additions and 133 deletions

View File

@@ -1507,6 +1507,9 @@ public class AVM2Code implements Cloneable {
break;
}
if (Configuration.autoDeobfuscate.get()) {
stack.simplify();
}
visited[ip] = true;
AVM2Instruction ins = code.get(ip);
if (stack.isEmpty()) {

View File

@@ -52,10 +52,13 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.GreaterThanIn
import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.LessEqualsIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.LessThanIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.StrictEqualsIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewArrayIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewFunctionIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewObjectIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.JumpIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocalTypeIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocalTypeIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetPropertyIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.DupIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PopIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushByteIns;
@@ -255,6 +258,9 @@ public class AVM2DeobfuscatorSimple extends SWFDecompilerAdapter {
|| def instanceof GetLocalTypeIns
|| def instanceof SetLocalTypeIns
|| def instanceof NewFunctionIns
|| def instanceof NewArrayIns
|| def instanceof NewObjectIns
|| def instanceof GetPropertyIns
|| def instanceof CoerceOrConvertTypeIns) {
ok = true;
}

View File

@@ -42,6 +42,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.NotIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.SubtractIIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.SubtractIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise.BitAndIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise.BitNotIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise.BitOrIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise.BitXorIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.bitwise.LShiftIns;
@@ -53,10 +54,15 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.GreaterThanIn
import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.LessEqualsIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.LessThanIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.comparison.StrictEqualsIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.ConstructIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewArrayIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewFunctionIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewObjectIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.executing.CallIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.JumpIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocalTypeIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocalTypeIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetPropertyIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.DupIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PopIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushByteIns;
@@ -71,7 +77,9 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushUndefinedIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.SwapIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceOrConvertTypeIns;
import com.jpexs.decompiler.flash.abc.avm2.model.FloatValueAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.GetPropertyAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.IntegerValueAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.NewArrayAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.NullAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.StringAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.UndefinedAVM2Item;
@@ -314,14 +322,32 @@ public class AVM2DeobfuscatorSimpleOld extends SWFDecompilerAdapter {
|| def instanceof GreaterEqualsIns
|| def instanceof GreaterThanIns
|| def instanceof LessThanIns
|| def instanceof BitNotIns
|| def instanceof StrictEqualsIns
|| def instanceof PopIns
|| def instanceof GetLocalTypeIns
|| def instanceof NewFunctionIns
|| def instanceof CoerceOrConvertTypeIns) {
|| def instanceof NewArrayIns
|| def instanceof NewObjectIns
|| def instanceof GetPropertyIns
|| def instanceof CoerceOrConvertTypeIns
|| def instanceof ConstructIns
|| def instanceof CallIns) {
ok = true;
}
if (def instanceof GetPropertyIns) {
GetPropertyAVM2Item avi = (GetPropertyAVM2Item) stack.peek();
ok = false;
if (avi.object instanceof NewArrayAVM2Item) {
if (((NewArrayAVM2Item) avi.object).values.isEmpty()) {
stack.pop();
stack.push(new UndefinedAVM2Item(null, null));
ok = true;
}
}
}
if (!ok) {
break;
}

View File

@@ -19,10 +19,14 @@ package com.jpexs.decompiler.flash.abc.avm2.instructions.construction;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.AVM2LocalData;
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea;
import com.jpexs.decompiler.flash.abc.avm2.exceptions.AVM2ExecutionException;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
import com.jpexs.decompiler.flash.abc.avm2.model.NewArrayAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.NullAVM2Item;
import com.jpexs.decompiler.flash.ecma.ArrayType;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateStack;
import com.jpexs.decompiler.graph.model.PopItem;
@@ -39,6 +43,16 @@ public class NewArrayIns extends InstructionDefinition {
super(0x56, "newarray", new int[]{AVM2Code.DAT_ARG_COUNT}, true);
}
@Override
public boolean execute(LocalDataArea lda, AVM2ConstantPool constants, AVM2Instruction ins) throws AVM2ExecutionException {
//TODO: moar
if (ins.operands[0] == 0) {
lda.operandStack.push(ArrayType.EMPTY_ARRAY);
return true;
}
return false;
}
@Override
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
int argCount = ins.operands[0];

View File

@@ -19,11 +19,16 @@ package com.jpexs.decompiler.flash.abc.avm2.instructions.construction;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.AVM2LocalData;
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea;
import com.jpexs.decompiler.flash.abc.avm2.exceptions.AVM2ExecutionException;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
import com.jpexs.decompiler.flash.abc.avm2.model.NameValuePair;
import com.jpexs.decompiler.flash.abc.avm2.model.NewObjectAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.NullAVM2Item;
import com.jpexs.decompiler.flash.ecma.ArrayType;
import com.jpexs.decompiler.flash.ecma.ObjectType;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateStack;
import com.jpexs.decompiler.graph.model.PopItem;
@@ -40,6 +45,16 @@ public class NewObjectIns extends InstructionDefinition {
super(0x55, "newobject", new int[]{AVM2Code.DAT_ARG_COUNT}, true);
}
@Override
public boolean execute(LocalDataArea lda, AVM2ConstantPool constants, AVM2Instruction ins) throws AVM2ExecutionException {
//TODO: moar
if (ins.operands[0] == 0) {
lda.operandStack.push(ObjectType.EMPTY_OBJECT);
return true;
}
return false;
}
@Override
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) throws InterruptedException {
int argCount = ins.operands[0];

View File

@@ -26,10 +26,15 @@ import com.jpexs.decompiler.flash.abc.avm2.model.ClassAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.ScriptAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.ThisAVM2Item;
import com.jpexs.decompiler.flash.abc.types.Multiname;
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter;
import com.jpexs.decompiler.flash.ecma.Undefined;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.NotCompileTimeItem;
import com.jpexs.decompiler.graph.TranslateStack;
import java.util.ArrayList;
import java.util.List;
/**
@@ -62,7 +67,26 @@ public abstract class GetLocalTypeIns extends InstructionDefinition {
if (localData.isStatic) {
stack.push(new ClassAVM2Item(localData.getInstanceInfo().get(localData.classIndex).getName(localData.getConstants())));
} else {
stack.push(new ThisAVM2Item(ins, localData.lineStartInstruction, localData.getInstanceInfo().get(localData.classIndex).getName(localData.getConstants())));
List<Trait> ts = localData.getInstanceInfo().get(localData.classIndex).instance_traits.traits;
boolean isBasicObject = true;
if (!"Object".equals(localData.getConstants().getMultiname(localData.getInstanceInfo().get(localData.classIndex).super_index).getNameWithNamespace(localData.getConstants()).toRawString())) {
//TODO: check for toString and valueOf in parent object
isBasicObject = false;
} else {
for (Trait t : ts) {
if (t instanceof TraitMethodGetterSetter) {
if ("toString".equals(t.getName(localData.abc).getName(localData.getConstants(), new ArrayList<>(), true))) {
isBasicObject = false;
}
if ("valueOf".equals(t.getName(localData.abc).getName(localData.getConstants(), new ArrayList<>(), true))) {
isBasicObject = false;
}
}
}
}
Multiname m = localData.getInstanceInfo().get(localData.classIndex).getName(localData.getConstants());
stack.push(new ThisAVM2Item(ins, localData.lineStartInstruction, m, m.getNameWithNamespace(localData.getConstants()), isBasicObject));
}
return;
}

View File

@@ -41,7 +41,7 @@ public class GetLexIns extends InstructionDefinition {
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
int multinameIndex = ins.operands[0];
Multiname multiname = localData.getConstants().getMultiname(multinameIndex);
stack.push(new GetLexAVM2Item(ins, localData.lineStartInstruction, multiname));
stack.push(new GetLexAVM2Item(ins, localData.lineStartInstruction, multiname, localData.getConstants()));
}
@Override

View File

@@ -19,10 +19,18 @@ package com.jpexs.decompiler.flash.abc.avm2.instructions.other;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.AVM2LocalData;
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea;
import com.jpexs.decompiler.flash.abc.avm2.exceptions.AVM2ExecutionException;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.GetPropertyAVM2Item;
import com.jpexs.decompiler.flash.abc.types.Multiname;
import com.jpexs.decompiler.flash.ecma.ArrayType;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.ecma.ObjectType;
import com.jpexs.decompiler.flash.ecma.Undefined;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateStack;
import java.util.List;
@@ -37,6 +45,28 @@ public class GetPropertyIns extends InstructionDefinition {
super(0x66, "getproperty", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true);
}
@Override
public boolean execute(LocalDataArea lda, AVM2ConstantPool constants, AVM2Instruction ins) throws AVM2ExecutionException {
if (constants.getMultiname(ins.operands[0]).kind == Multiname.MULTINAMEL) {
String name = EcmaScript.toString(lda.operandStack.pop());
Object obj = lda.operandStack.pop();
if (obj == ArrayType.EMPTY_ARRAY) {
if ("length".equals(name)) {
lda.operandStack.push(0L);
} else {
lda.operandStack.push(Undefined.INSTANCE);
}
return true;
}
if (obj == ObjectType.EMPTY_OBJECT) {
lda.operandStack.push(Undefined.INSTANCE);
return true;
}
return true;
}
return false;
}
@Override
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
int multinameIndex = ins.operands[0];

View File

@@ -56,7 +56,7 @@ public class GetSlotIns extends InstructionDefinition {
} else if (obj instanceof ClassAVM2Item) {
slotname = ((ClassAVM2Item) obj).className;
} else if (obj instanceof ThisAVM2Item) {
slotname = ((ThisAVM2Item) obj).className;
slotname = ((ThisAVM2Item) obj).classMultiname;
} else if (obj instanceof ScriptAVM2Item) {
List<Trait> traits = localData.getScriptInfo().get(((ScriptAVM2Item) obj).scriptIndex).traits.traits;
for (int t = 0; t < traits.size(); t++) {

View File

@@ -76,7 +76,7 @@ public class SetSlotIns extends InstructionDefinition implements SetTypeIns {
} else if (obj instanceof ClassAVM2Item) {
slotname = ((ClassAVM2Item) obj).className;
} else if (obj instanceof ThisAVM2Item) {
slotname = ((ThisAVM2Item) obj).className;
slotname = ((ThisAVM2Item) obj).classMultiname;
} else if (obj instanceof ScriptAVM2Item) {
List<Trait> traits = localData.getScriptInfo().get(((ScriptAVM2Item) obj).scriptIndex).traits.traits;
for (int t = 0; t < traits.size(); t++) {

View File

@@ -16,12 +16,23 @@
*/
package com.jpexs.decompiler.flash.abc.avm2.model;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TypeItem;
import com.jpexs.decompiler.graph.model.LocalData;
import com.jpexs.helpers.utf8.Utf8Helper;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
@@ -35,6 +46,101 @@ public class CallAVM2Item extends AVM2Item {
public List<GraphTargetItem> arguments;
private static abstract class Func implements Callable {
@Override
public Object call(String methodName, List<Object> args) {
return call(args);
}
}
private static Map<String, Func> bundledFunctions = new HashMap<>();
static {
bundledFunctions.put("parseInt", new Func() {
@Override
public Object call(List<Object> args) {
Object v = args.get(0);
Object r = args.size() > 1 ? args.get(0) : 0L;
return EcmaScript.parseInt(v, r);
}
});
bundledFunctions.put("parseFloat", new Func() {
@Override
public Object call(List<Object> args) {
return EcmaScript.parseFloat(args.get(0));
}
});
bundledFunctions.put("Number", new Func() {
@Override
public Object call(List<Object> args) {
return EcmaScript.toNumber(args.get(0));
}
});
bundledFunctions.put("isNaN", new Func() {
@Override
public Object call(List<Object> args) {
return EcmaScript.isNaN(args.get(0));
}
});
bundledFunctions.put("int", new Func() {
@Override
public Object call(List<Object> args) {
return EcmaScript.toInt32(args.get(0));
}
});
bundledFunctions.put("uint", new Func() {
@Override
public Object call(List<Object> args) {
return EcmaScript.toUint32(args.get(0));
}
});
bundledFunctions.put("encodeURI", new Func() {
@Override
public Object call(List<Object> args) {
return EcmaScript.encodeUri(args.get(0));
}
});
bundledFunctions.put("decodeURI", new Func() {
@Override
public Object call(List<Object> args) {
return EcmaScript.decodeUri(args.get(0));
}
});
bundledFunctions.put("encodeURIComponent", new Func() {
@Override
public Object call(List<Object> args) {
return EcmaScript.encodeUriComponent(args.get(0));
}
});
bundledFunctions.put("decodeURIComponent", new Func() {
@Override
public Object call(List<Object> args) {
return EcmaScript.decodeUriComponent(args.get(0));
}
});
bundledFunctions.put("escape", new Func() {
@Override
public Object call(List<Object> args) {
return EcmaScript.escape(args.get(0));
}
});
bundledFunctions.put("unescape", new Func() {
@Override
public Object call(List<Object> args) {
return EcmaScript.unescape(args.get(0));
}
});
}
public CallAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem receiver, GraphTargetItem function, List<GraphTargetItem> arguments) {
super(instruction, lineStartIns, PRECEDENCE_PRIMARY);
this.receiver = receiver;
@@ -42,6 +148,51 @@ public class CallAVM2Item extends AVM2Item {
this.arguments = arguments;
}
@Override
public Object getResult() {
if (!isCompileTime()) {
return null;
}
List<Object> oargs = new ArrayList<>();
for (GraphTargetItem ot : arguments) {
Object r = ot.getResult();
if (r == null) {
return false;
}
oargs.add(r);
}
if (function instanceof GetLexAVM2Item) {
String propName = ((GetLexAVM2Item) function).getRawPropertyName();
if (bundledFunctions.containsKey(propName)) {
return bundledFunctions.get(propName).call(oargs);
}
} else if (function instanceof Callable) {
return ((Callable) function).call(oargs);
}
return null;
}
@Override
public boolean isCompileTime(Set<GraphTargetItem> dependencies) {
for (GraphTargetItem a : arguments) {
if (!a.isCompileTime(dependencies)) {
return false;
}
}
//TODO: receiver?
if ((function instanceof Callable) && (function.isCompileTime())) {
return true;
} else if (function instanceof GetLexAVM2Item) {
String propName = ((GetLexAVM2Item) function).getRawPropertyName();
if (bundledFunctions.containsKey(propName)) {
return true;
}
}
return false;
}
@Override
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
/*String recPart = ""; receiver.toString(constants, localRegNames) + writer.append(".");

View File

@@ -0,0 +1,30 @@
/*
* Copyright (C) 2010-2016 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.flash.abc.avm2.model;
import java.util.List;
/**
*
* @author JPEXS
*/
public interface Callable {
public Object call(String methodName, List<Object> args);
public Object call(List<Object> args);
}

View File

@@ -81,6 +81,9 @@ public class CoerceAVM2Item extends AVM2Item {
if (ret == Undefined.INSTANCE) {
return Null.INSTANCE;
}
if (ret == null) {
return null;
}
return ret.toString();
case "*":
break;

View File

@@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions;
import com.jpexs.decompiler.flash.abc.avm2.parser.script.AVM2SourceGenerator;
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;
@@ -45,7 +46,7 @@ public class FloatValueAVM2Item extends NumberValueAVM2Item {
@Override
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) {
return writer.append(value);
return writer.append(EcmaScript.toString(value));
}
@Override

View File

@@ -106,7 +106,11 @@ public class FullMultinameAVM2Item extends AVM2Item {
}
if (name != null) {
writer.append("[");
name.toString(writer, localData);
if (name instanceof IntegerValueAVM2Item) {
name.toString(writer, localData);
} else {
name.toStringString(writer, localData);
}
writer.append("]");
} else {
AVM2ConstantPool constants = localData.constantsAvm2;

View File

@@ -16,12 +16,15 @@
*/
package com.jpexs.decompiler.flash.abc.avm2.model;
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
import com.jpexs.decompiler.flash.abc.types.Multiname;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TypeItem;
import com.jpexs.decompiler.graph.model.LocalData;
import java.util.ArrayList;
/**
*
@@ -30,10 +33,16 @@ import com.jpexs.decompiler.graph.model.LocalData;
public class GetLexAVM2Item extends AVM2Item {
public Multiname propertyName;
private DottedChain fullPropertyName;
public GetLexAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, Multiname propertyName) {
public GetLexAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, Multiname propertyName, AVM2ConstantPool constants) {
super(instruction, lineStartIns, PRECEDENCE_PRIMARY);
this.propertyName = propertyName;
this.fullPropertyName = propertyName.getNameWithNamespace(constants);
}
public String getRawPropertyName() {
return fullPropertyName.toRawString();
}
@Override

View File

@@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions;
import com.jpexs.decompiler.flash.abc.avm2.parser.script.AVM2SourceGenerator;
import com.jpexs.decompiler.flash.ecma.Undefined;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.graph.CompilationException;
import com.jpexs.decompiler.graph.GraphSourceItem;
@@ -28,6 +29,7 @@ import com.jpexs.decompiler.graph.SourceGenerator;
import com.jpexs.decompiler.graph.TypeItem;
import com.jpexs.decompiler.graph.model.LocalData;
import java.util.List;
import java.util.Set;
/**
*
@@ -39,6 +41,36 @@ public class GetPropertyAVM2Item extends AVM2Item {
public GraphTargetItem propertyName;
@Override
public boolean isCompileTime(Set<GraphTargetItem> dependencies) {
if (object instanceof NewArrayAVM2Item) {
if (((NewArrayAVM2Item) object).values.isEmpty()) {
return true;
}
}
if (object instanceof NewObjectAVM2Item) {
if (((NewObjectAVM2Item) object).pairs.isEmpty()) {
return true;
}
}
return false;
}
@Override
public Object getResult() {
if (object instanceof NewArrayAVM2Item) {
if (((NewArrayAVM2Item) object).values.isEmpty()) {
return Undefined.INSTANCE;
}
}
if (object instanceof NewObjectAVM2Item) {
if (((NewObjectAVM2Item) object).pairs.isEmpty()) {
return Undefined.INSTANCE;
}
}
return null;
}
public GetPropertyAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem object, GraphTargetItem propertyName) {
super(instruction, lineStartIns, PRECEDENCE_PRIMARY);
this.object = object;

View File

@@ -58,13 +58,13 @@ public class HasNextAVM2Item extends AVM2Item {
writer.append("§§hasnext(");
if (obj != null) {
obj.appendTo(writer, localData);
obj.appendTry(writer, localData);
} else {
writer.append("null");
}
writer.append(",");
if (index != null) {
index.appendTo(writer, localData);
index.appendTry(writer, localData);
} else {
writer.append("null");
}
@@ -74,7 +74,7 @@ public class HasNextAVM2Item extends AVM2Item {
@Override
public GraphTargetItem returnType() {
return TypeItem.UNBOUNDED;
return TypeItem.BOOLEAN;
}
@Override

View File

@@ -80,14 +80,14 @@ public class InitVectorAVM2Item extends AVM2Item {
@Override
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
writer.append("<");
subtype.appendTo(writer, localData);
subtype.appendTry(writer, localData);
writer.append(">");
writer.append("[");
for (int i = 0; i < arguments.size(); i++) {
if (i > 0) {
writer.append(",");
}
arguments.get(i).appendTo(writer, localData);
arguments.get(i).appendTry(writer, localData);
}
writer.append("]");
return writer;

View File

@@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions;
import com.jpexs.decompiler.flash.abc.avm2.parser.script.AVM2SourceGenerator;
import com.jpexs.decompiler.flash.configuration.Configuration;
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.DottedChain;
@@ -117,7 +118,7 @@ public class IntegerValueAVM2Item extends NumberValueAVM2Item implements Integer
}
}
return writer.append(value);
return writer.append(EcmaScript.toString(value));
}
@Override

View File

@@ -27,6 +27,7 @@ import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.SourceGenerator;
import com.jpexs.decompiler.graph.TypeItem;
import com.jpexs.decompiler.graph.model.LocalData;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -49,13 +50,11 @@ public class LocalRegAVM2Item extends AVM2Item {
this.regIndex = regIndex;
if (computedValue == null) {
computedResult = null;
} else if (computedValue.isCompileTime()) {
computedResult = computedValue.getResult();
isCT = true;
} else {
if (computedValue.isCompileTime()) {
computedResult = computedValue.getResult();
isCT = true;
} else {
computedResult = null;
}
computedResult = null;
}
this.computedValue = computedValue;
}
@@ -81,17 +80,31 @@ public class LocalRegAVM2Item extends AVM2Item {
@Override
public Object getResult() {
if (computedValue == null) {
return null;
}
return computedValue.getResult();
}
@Override
public Double getResultAsNumber() {
if (computedValue == null) {
return null;
}
return computedValue.getResultAsNumber();
}
@Override
public boolean isCompileTime(Set<GraphTargetItem> dependencies) {
return computedValue instanceof UndefinedAVM2Item;
return (computedValue instanceof UndefinedAVM2Item);
}
@Override
public boolean isConvertedCompileTime(Set<GraphTargetItem> dependencies) {
if (computedValue == null) {
return false;
}
return ((computedValue instanceof ThisAVM2Item) && computedValue.isConvertedCompileTime(dependencies));
}
@Override

View File

@@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.abc.avm2.model;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions;
import com.jpexs.decompiler.flash.ecma.ArrayType;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.graph.CompilationException;
import com.jpexs.decompiler.graph.GraphSourceItem;
@@ -26,7 +27,9 @@ import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.SourceGenerator;
import com.jpexs.decompiler.graph.TypeItem;
import com.jpexs.decompiler.graph.model.LocalData;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
*
@@ -58,6 +61,37 @@ public class NewArrayAVM2Item extends AVM2Item {
return TypeItem.ARRAY;
}
@Override
public Object getResult() {
List<Object> ovalues = new ArrayList<>();
for (GraphTargetItem it : values) {
Object o = it.getResult();
if (o == null) {
return null;
}
ovalues.add(o);
}
return new ArrayType(ovalues);
}
@Override
public GraphTargetItem simplify(String implicitCoerce) {
if (implicitCoerce.isEmpty()) {
return this;
}
return super.simplify(implicitCoerce);
}
@Override
public boolean isCompileTime(Set<GraphTargetItem> dependencies) {
for (GraphTargetItem v : values) {
if (!v.isCompileTime()) {
return false;
}
}
return true;
}
@Override
public boolean hasReturnValue() {
return true;

View File

@@ -19,6 +19,8 @@ package com.jpexs.decompiler.flash.abc.avm2.model;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.ecma.ObjectType;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.graph.CompilationException;
import com.jpexs.decompiler.graph.DottedChain;
@@ -28,7 +30,10 @@ import com.jpexs.decompiler.graph.SourceGenerator;
import com.jpexs.decompiler.graph.TypeItem;
import com.jpexs.decompiler.graph.model.LocalData;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
*
@@ -87,4 +92,32 @@ public class NewObjectAVM2Item extends AVM2Item {
new AVM2Instruction(0, AVM2Instructions.NewObject, new int[]{pairs.size()})
);
}
@Override
public Object getResult() {
Map<String, Object> props = new HashMap<>();
for (NameValuePair v : pairs) {
props.put(EcmaScript.toString(v.name.getResult()), v.value.getResult());
}
return new ObjectType(props);
}
@Override
public GraphTargetItem simplify(String implicitCoerce) {
if (implicitCoerce.isEmpty()) {
return this;
} else {
return super.simplify(implicitCoerce);
}
}
@Override
public boolean isCompileTime(Set<GraphTargetItem> dependencies) {
for (NameValuePair v : pairs) {
if (!v.name.isCompileTime() || !v.value.isCompileTime()) {
return false;
}
}
return true;
}
}

View File

@@ -7,6 +7,9 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions;
import com.jpexs.decompiler.flash.abc.avm2.parser.script.AVM2SourceGenerator;
import com.jpexs.decompiler.flash.abc.types.Namespace;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.ecma.ArrayType;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.ecma.Undefined;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.graph.CompilationException;
import com.jpexs.decompiler.graph.GraphSourceItem;
@@ -15,13 +18,16 @@ import com.jpexs.decompiler.graph.SourceGenerator;
import com.jpexs.decompiler.graph.TypeItem;
import com.jpexs.decompiler.graph.model.LocalData;
import com.jpexs.helpers.Helper;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
*
* @author JPEXS
*/
public class RegExpAvm2Item extends AVM2Item {
public class RegExpAvm2Item extends AVM2Item implements Callable {
public String pattern;
@@ -33,6 +39,11 @@ public class RegExpAvm2Item extends AVM2Item {
this.modifier = modifier;
}
@Override
public boolean isCompileTime() {
return true;
}
public static String escapeRegExpString(String s) {
StringBuilder ret = new StringBuilder(s.length());
for (int i = 0; i < s.length(); i++) {
@@ -101,4 +112,55 @@ public class RegExpAvm2Item extends AVM2Item {
ins(AVM2Instructions.Construct, hasModifier ? 2 : 1)
);
}
@Override
public Object call(String methodName, List<Object> args) {
int flags = 0;
for (char c : modifier.toCharArray()) {
switch (c) {
case 'g':
//global (??)
break;
case 'i':
flags |= Pattern.CASE_INSENSITIVE;
break;
case 's':
flags |= Pattern.DOTALL;
break;
case 'm':
flags |= Pattern.MULTILINE;
break;
case 'x':
flags |= Pattern.COMMENTS; //?
break;
default:
//?
break;
}
}
Pattern p = Pattern.compile(pattern, flags);
switch (methodName) {
case "exec":
String estr = EcmaScript.toString(args.get(0));
Matcher m = p.matcher(estr);
m.find();
List<Object> avals = new ArrayList<>();
for (int i = 0; i <= m.groupCount(); i++) {
avals.add(m.group(i));
}
ArrayType a = new ArrayType(avals);
a.setAttribute("input", estr);
a.setAttribute("index", m.start());
return a;
case "test":
String tstr = EcmaScript.toString(args.get(0));
return p.matcher(tstr).find(); //boolean
}
return Undefined.INSTANCE; //?
}
@Override
public Object call(List<Object> args) {
return call("exec", args);
}
}

View File

@@ -17,17 +17,22 @@
package com.jpexs.decompiler.flash.abc.avm2.model;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions;
import com.jpexs.decompiler.flash.abc.types.Multiname;
import com.jpexs.decompiler.flash.ecma.ObjectType;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.graph.CompilationException;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.SourceGenerator;
import com.jpexs.decompiler.graph.TypeItem;
import com.jpexs.decompiler.graph.model.LocalData;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
/**
*
@@ -35,14 +40,41 @@ import java.util.List;
*/
public class ThisAVM2Item extends AVM2Item {
public Multiname className;
public DottedChain className;
public boolean basicObject;
public Multiname classMultiname;
public ThisAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, Multiname className) {
public ThisAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, Multiname classMultiname, DottedChain className, boolean basicObject) {
super(instruction, lineStartIns, PRECEDENCE_PRIMARY);
this.className = className;
this.classMultiname = classMultiname;
this.basicObject = basicObject;
getSrcData().localName = "this";
}
public boolean isBasicObject() {
return basicObject;
}
@Override
public boolean isConvertedCompileTime(Set<GraphTargetItem> dependencies) {
return isBasicObject();
}
@Override
public Object getResult() {
if (basicObject) {
return new ObjectType(new HashMap<>()) {
@Override
public String toString() {
return "[object " + className.getLast() + "]";
}
};
}
return null;
}
@Override
public String toString() {
return "this";

View File

@@ -96,7 +96,7 @@ public class DeclarationAVM2Item extends AVM2Item {
writer.append("var ");
writer.append(localName);
writer.append(":");
coerType.appendTo(writer, localData);
coerType.appendTry(writer, localData);
writer.append(" = ");
return lti.value.toString(writer, localData);
}
@@ -110,7 +110,7 @@ public class DeclarationAVM2Item extends AVM2Item {
ssti.getName(writer, localData);
writer.append(":");
type.appendTo(writer, localData);
type.appendTry(writer, localData);
writer.append(" = ");
return ssti.value.toString(writer, localData);
}

View File

@@ -43,7 +43,7 @@ public class FilterAVM2Item extends AVM2Item {
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
collection.toString(writer, localData);
writer.append(".(");
expression.toString(writer, localData);
expression.toStringBoolean(writer, localData);
return writer.append(")");
}

View File

@@ -39,7 +39,7 @@ import java.util.List;
public class AddAVM2Item extends BinaryOpItem {
public AddAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_ADDITIVE, leftSide, rightSide, "+");
super(instruction, lineStartIns, PRECEDENCE_ADDITIVE, leftSide, rightSide, "+", "", ""); //?
}
@Override

View File

@@ -33,7 +33,7 @@ import java.util.List;
public class AsTypeAVM2Item extends BinaryOpItem {
public AsTypeAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem value, GraphTargetItem type) {
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, value, type, "as");
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, value, type, "as", "", "");
}
@Override

View File

@@ -34,7 +34,7 @@ import java.util.List;
public class BitAndAVM2Item extends BinaryOpItem {
public BitAndAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_BITWISEAND, leftSide, rightSide, "&");
super(instruction, lineStartIns, PRECEDENCE_BITWISEAND, leftSide, rightSide, "&", "Number", "Number");
}
@Override

View File

@@ -34,7 +34,7 @@ import java.util.List;
public class BitNotAVM2Item extends UnaryOpItem {
public BitNotAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem value) {
super(instruction, lineStartIns, PRECEDENCE_UNARY, value, "~");
super(instruction, lineStartIns, PRECEDENCE_UNARY, value, "~", "int");
}
@Override

View File

@@ -34,7 +34,7 @@ import java.util.List;
public class BitOrAVM2Item extends BinaryOpItem {
public BitOrAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_BITWISEOR, leftSide, rightSide, "|");
super(instruction, lineStartIns, PRECEDENCE_BITWISEOR, leftSide, rightSide, "|", "Number", "Number");
}
@Override

View File

@@ -34,7 +34,7 @@ import java.util.List;
public class BitXorAVM2Item extends BinaryOpItem {
public BitXorAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_BITWISEXOR, leftSide, rightSide, "^");
super(instruction, lineStartIns, PRECEDENCE_BITWISEXOR, leftSide, rightSide, "^", "Number", "Number");
}
@Override

View File

@@ -36,7 +36,7 @@ import java.util.List;
public class DivideAVM2Item extends BinaryOpItem {
public DivideAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_MULTIPLICATIVE, leftSide, rightSide, "/");
super(instruction, lineStartIns, PRECEDENCE_MULTIPLICATIVE, leftSide, rightSide, "/", "Number", "Number");
}
@Override

View File

@@ -38,7 +38,7 @@ import java.util.List;
public class EqAVM2Item extends BinaryOpItem implements LogicalOpItem, IfCondition, EqualsTypeItem {
public EqAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_EQUALITY, leftSide, rightSide, "==");
super(instruction, lineStartIns, PRECEDENCE_EQUALITY, leftSide, rightSide, "==", "", "");
}
@Override

View File

@@ -38,7 +38,7 @@ import java.util.List;
public class GeAVM2Item extends BinaryOpItem implements LogicalOpItem, IfCondition {
public GeAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, leftSide, rightSide, ">=");
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, leftSide, rightSide, ">=", "", "");
}
@Override

View File

@@ -38,7 +38,7 @@ import java.util.List;
public class GtAVM2Item extends BinaryOpItem implements LogicalOpItem, IfCondition {
public GtAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, leftSide, rightSide, ">");
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, leftSide, rightSide, ">", "", "");
}
@Override

View File

@@ -35,7 +35,7 @@ import java.util.List;
public class InAVM2Item extends BinaryOpItem {
public InAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem name, GraphTargetItem object) {
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, name, object, "in");
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, name, object, "in", "", "");
}
@Override

View File

@@ -35,7 +35,7 @@ import java.util.List;
public class InstanceOfAVM2Item extends BinaryOpItem {
public InstanceOfAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem value, GraphTargetItem type) {
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, value, type, "instanceof");
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, value, type, "instanceof", "", "");
}
@Override

View File

@@ -35,7 +35,7 @@ import java.util.List;
public class IsTypeAVM2Item extends BinaryOpItem {
public IsTypeAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem value, GraphTargetItem type) {
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, value, type, "is");
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, value, type, "is", "", "");
}
@Override

View File

@@ -19,11 +19,13 @@ package com.jpexs.decompiler.flash.abc.avm2.model.operations;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.graph.CompilationException;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.SourceGenerator;
import com.jpexs.decompiler.graph.model.BinaryOpItem;
import com.jpexs.decompiler.graph.model.LocalData;
import com.jpexs.decompiler.graph.model.UnboundedTypeItem;
import java.util.List;
@@ -34,7 +36,7 @@ import java.util.List;
public class LShiftAVM2Item extends BinaryOpItem {
public LShiftAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_BITWISESHIFT, leftSide, rightSide, "<<");
super(instruction, lineStartIns, PRECEDENCE_BITWISESHIFT, leftSide, rightSide, "<<", "Number", "Number");
}
@Override

View File

@@ -38,7 +38,7 @@ import java.util.List;
public class LeAVM2Item extends BinaryOpItem implements LogicalOpItem, IfCondition {
public LeAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, leftSide, rightSide, "<=");
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, leftSide, rightSide, "<=", "", "");
}
@Override
@@ -76,6 +76,6 @@ public class LeAVM2Item extends BinaryOpItem implements LogicalOpItem, IfConditi
@Override
public GraphTargetItem returnType() {
return new TypeItem(DottedChain.BOOLEAN);
return TypeItem.BOOLEAN;
}
}

View File

@@ -38,7 +38,7 @@ import java.util.List;
public class LtAVM2Item extends BinaryOpItem implements LogicalOpItem, IfCondition {
public LtAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, leftSide, rightSide, "<");
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, leftSide, rightSide, "<", "", "");
}
@Override

View File

@@ -36,7 +36,7 @@ import java.util.List;
public class ModuloAVM2Item extends BinaryOpItem {
public ModuloAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_MULTIPLICATIVE, leftSide, rightSide, "%");
super(instruction, lineStartIns, PRECEDENCE_MULTIPLICATIVE, leftSide, rightSide, "%", "Number", "Number");
}
@Override

View File

@@ -36,7 +36,7 @@ import java.util.List;
public class MultiplyAVM2Item extends BinaryOpItem {
public MultiplyAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_MULTIPLICATIVE, leftSide, rightSide, "*");
super(instruction, lineStartIns, PRECEDENCE_MULTIPLICATIVE, leftSide, rightSide, "*", "Number", "Number");
}
@Override

View File

@@ -34,7 +34,7 @@ import java.util.List;
public class NegAVM2Item extends UnaryOpItem {
public NegAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem value) {
super(instruction, lineStartIns, PRECEDENCE_UNARY, value, "-");
super(instruction, lineStartIns, PRECEDENCE_UNARY, value, "-", "Number");
}
@Override

View File

@@ -37,7 +37,7 @@ import java.util.List;
public class NeqAVM2Item extends BinaryOpItem implements LogicalOpItem, IfCondition {
public NeqAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_EQUALITY, leftSide, rightSide, "!=");
super(instruction, lineStartIns, PRECEDENCE_EQUALITY, leftSide, rightSide, "!=", "", "");
}
@Override

View File

@@ -34,7 +34,7 @@ import java.util.List;
public class PreDecrementAVM2Item extends UnaryOpItem implements AssignmentAVM2Item {
public PreDecrementAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem object) {
super(instruction, lineStartIns, PRECEDENCE_UNARY, object, "--");
super(instruction, lineStartIns, PRECEDENCE_UNARY, object, "--", "Number");
}
@Override

View File

@@ -33,7 +33,7 @@ import java.util.List;
public class PreIncrementAVM2Item extends UnaryOpItem {
public PreIncrementAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem object) {
super(instruction, lineStartIns, PRECEDENCE_UNARY, object, "++");
super(instruction, lineStartIns, PRECEDENCE_UNARY, object, "++", "Number");
}
@Override

View File

@@ -34,7 +34,7 @@ import java.util.List;
public class RShiftAVM2Item extends BinaryOpItem {
public RShiftAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_BITWISESHIFT, leftSide, rightSide, ">>");
super(instruction, lineStartIns, PRECEDENCE_BITWISESHIFT, leftSide, rightSide, ">>", "Number", "Number");
}
@Override

View File

@@ -38,7 +38,7 @@ import java.util.List;
public class StrictEqAVM2Item extends BinaryOpItem implements LogicalOpItem, IfCondition, EqualsTypeItem {
public StrictEqAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_EQUALITY, leftSide, rightSide, "===");
super(instruction, lineStartIns, PRECEDENCE_EQUALITY, leftSide, rightSide, "===", "", "");
}
@Override

View File

@@ -37,7 +37,7 @@ import java.util.List;
public class StrictNeqAVM2Item extends BinaryOpItem implements LogicalOpItem, IfCondition {
public StrictNeqAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_EQUALITY, leftSide, rightSide, "!==");
super(instruction, lineStartIns, PRECEDENCE_EQUALITY, leftSide, rightSide, "!==", "", "");
}
@Override

View File

@@ -37,7 +37,7 @@ import java.util.List;
public class SubtractAVM2Item extends BinaryOpItem {
public SubtractAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_ADDITIVE, leftSide, rightSide, "-");
super(instruction, lineStartIns, PRECEDENCE_ADDITIVE, leftSide, rightSide, "-", "Number", "Number");
}
@Override

View File

@@ -37,7 +37,7 @@ import java.util.Set;
public class TypeOfAVM2Item extends UnaryOpItem {
public TypeOfAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem value) {
super(instruction, lineStartIns, PRECEDENCE_UNARY, value, "typeof ");
super(instruction, lineStartIns, PRECEDENCE_UNARY, value, "typeof ", "");
}
@Override

View File

@@ -34,7 +34,7 @@ import java.util.List;
public class URShiftAVM2Item extends BinaryOpItem {
public URShiftAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_BITWISESHIFT, leftSide, rightSide, ">>>");
super(instruction, lineStartIns, PRECEDENCE_BITWISESHIFT, leftSide, rightSide, ">>>", "Number", "Number");
}
@Override

View File

@@ -44,7 +44,7 @@ public class XMLAVM2Item extends AVM2Item {
@Override
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
return value.appendTo(writer, localData);
return value.appendTry(writer, localData);
}
@Override

View File

@@ -63,7 +63,7 @@ public class CallFunctionActionItem extends ActionItem {
if (functionName instanceof DirectValueActionItem) {
writer.append(IdentifiersDeobfuscation.printIdentifier(false, (functionName).toStringNoQuotes(localData)));
} else {
functionName.appendTo(writer, localData);
functionName.appendTry(writer, localData);
}
writer.spaceBeforeCallParenthesies(arguments.size());
writer.append("(");

View File

@@ -86,7 +86,7 @@ public class CallMethodActionItem extends ActionItem {
}
} else {
writer.append("this[");
methodName.appendTo(writer, localData);
methodName.appendTry(writer, localData);
writer.append("].call");
}

View File

@@ -47,7 +47,7 @@ public class FSCommandActionItem extends ActionItem {
writer.append("fscommand");
writer.spaceBeforeCallParenthesies(1);
writer.append("(");
command.appendTo(writer, localData);
command.appendTry(writer, localData);
return writer.append(")");
}

View File

@@ -76,7 +76,7 @@ public class GetVariableActionItem extends ActionItem {
return IdentifiersDeobfuscation.appendObfuscatedIdentifier(((DirectValueActionItem) name).toStringNoQuotes(localData), writer);
} else if ((!(name instanceof DirectValueActionItem)) || (!((DirectValueActionItem) name).isString())) {
writer.append("eval(");
name.appendTo(writer, localData);
name.appendTry(writer, localData);
return writer.append(")");
}
HighlightData srcData = getSrcData();

View File

@@ -40,7 +40,7 @@ public class AddActionItem extends BinaryOpItem {
boolean version2;
public AddActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide, boolean version2) {
super(instruction, lineStartIns, PRECEDENCE_ADDITIVE, leftSide, rightSide, "+");
super(instruction, lineStartIns, PRECEDENCE_ADDITIVE, leftSide, rightSide, "+", "", "");
this.version2 = version2;
}

View File

@@ -34,7 +34,7 @@ import java.util.List;
public class AndActionItem extends BinaryOpItem {
public AndActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_LOGICALAND, leftSide, rightSide, "and");
super(instruction, lineStartIns, PRECEDENCE_LOGICALAND, leftSide, rightSide, "and", "Boolean", "Boolean");
}
@Override

View File

@@ -34,7 +34,7 @@ import java.util.List;
public class BitAndActionItem extends BinaryOpItem {
public BitAndActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_BITWISEAND, leftSide, rightSide, "&");
super(instruction, lineStartIns, PRECEDENCE_BITWISEAND, leftSide, rightSide, "&", "int", "int");
}
@Override

View File

@@ -34,7 +34,7 @@ import java.util.List;
public class BitOrActionItem extends BinaryOpItem {
public BitOrActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_BITWISEOR, leftSide, rightSide, "|");
super(instruction, lineStartIns, PRECEDENCE_BITWISEOR, leftSide, rightSide, "|", "int", "int");
}
@Override

View File

@@ -37,7 +37,7 @@ import java.util.List;
public class BitXorActionItem extends BinaryOpItem {
public BitXorActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_BITWISEXOR, leftSide, rightSide, "^");
super(instruction, lineStartIns, PRECEDENCE_BITWISEXOR, leftSide, rightSide, "^", "int", "int");
}
@Override
@@ -56,7 +56,7 @@ public class BitXorActionItem extends BinaryOpItem {
if (leftSide.getPrecedence() > PRECEDENCE_UNARY) {
writer.append("(");
}
leftSide.appendTo(writer, localData);
leftSide.appendTry(writer, localData);
if (leftSide.getPrecedence() > PRECEDENCE_UNARY) {
writer.append(")");
}

View File

@@ -33,7 +33,7 @@ import java.util.List;
public class DivideActionItem extends BinaryOpItem {
public DivideActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_MULTIPLICATIVE, leftSide, rightSide, "/");
super(instruction, lineStartIns, PRECEDENCE_MULTIPLICATIVE, leftSide, rightSide, "/", "Number", "Number");
}
@Override

View File

@@ -39,7 +39,7 @@ public class EqActionItem extends BinaryOpItem implements LogicalOpItem, EqualsT
boolean version2;
public EqActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide, boolean version2) {
super(instruction, lineStartIns, PRECEDENCE_EQUALITY, leftSide, rightSide, "==");
super(instruction, lineStartIns, PRECEDENCE_EQUALITY, leftSide, rightSide, "==", "", "");
this.version2 = version2;
}

View File

@@ -42,7 +42,7 @@ public class GeActionItem extends BinaryOpItem implements LogicalOpItem, Inverte
boolean version2;
public GeActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide, boolean version2) {
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, leftSide, rightSide, ">=");
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, leftSide, rightSide, ">=", "", "");
this.version2 = version2;
}

View File

@@ -39,7 +39,7 @@ import java.util.List;
public class GtActionItem extends BinaryOpItem implements LogicalOpItem {
public GtActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, leftSide, rightSide, ">");
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, leftSide, rightSide, ">", "", "");
}
@Override

View File

@@ -30,7 +30,7 @@ import java.util.Set;
public class InActionItem extends BinaryOpItem {
public InActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, ActionItem name, ActionItem object) {
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, name, object, "in");
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, name, object, "in", "", "");
}
@Override

View File

@@ -34,7 +34,7 @@ import java.util.Set;
public class InstanceOfActionItem extends BinaryOpItem {
public InstanceOfActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem value, GraphTargetItem type) {
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, value, type, "instanceof");
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, value, type, "instanceof", "", "");
}
@Override

View File

@@ -34,7 +34,7 @@ import java.util.List;
public class LShiftActionItem extends BinaryOpItem {
public LShiftActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_BITWISESHIFT, leftSide, rightSide, "<<");
super(instruction, lineStartIns, PRECEDENCE_BITWISESHIFT, leftSide, rightSide, "<<", "int", "int");
}
@Override

View File

@@ -40,7 +40,7 @@ import java.util.List;
public class LeActionItem extends BinaryOpItem implements LogicalOpItem, Inverted {
public LeActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, leftSide, rightSide, "<=");
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, leftSide, rightSide, "<=", "", "");
}
@Override

View File

@@ -41,7 +41,7 @@ public class LtActionItem extends BinaryOpItem implements LogicalOpItem {
boolean version2;
public LtActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide, boolean version2) {
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, leftSide, rightSide, "<");
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, leftSide, rightSide, "<", "", "");
this.version2 = version2;
}

View File

@@ -33,7 +33,7 @@ import java.util.List;
public class ModuloActionItem extends BinaryOpItem {
public ModuloActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_MULTIPLICATIVE, leftSide, rightSide, "%");
super(instruction, lineStartIns, PRECEDENCE_MULTIPLICATIVE, leftSide, rightSide, "%", "Number", "Number");
}
@Override

View File

@@ -33,7 +33,7 @@ import java.util.List;
public class MultiplyActionItem extends BinaryOpItem {
public MultiplyActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_MULTIPLICATIVE, leftSide, rightSide, "*");
super(instruction, lineStartIns, PRECEDENCE_MULTIPLICATIVE, leftSide, rightSide, "*", "Number", "Number");
}
@Override

View File

@@ -39,7 +39,7 @@ public class NeqActionItem extends BinaryOpItem implements LogicalOpItem, Invert
boolean version2;
public NeqActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide, boolean version2) {
super(instruction, lineStartIns, PRECEDENCE_EQUALITY, leftSide, rightSide, "!=");
super(instruction, lineStartIns, PRECEDENCE_EQUALITY, leftSide, rightSide, "!=", "", "");
this.version2 = version2;
}

View File

@@ -34,7 +34,7 @@ import java.util.List;
public class OrActionItem extends BinaryOpItem {
public OrActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_LOGICALOR, leftSide, rightSide, "or");
super(instruction, lineStartIns, PRECEDENCE_LOGICALOR, leftSide, rightSide, "or", "Boolean", "Boolean");
}
@Override

View File

@@ -45,7 +45,7 @@ import java.util.List;
public class PreDecrementActionItem extends UnaryOpItem {
public PreDecrementActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem object) {
super(instruction, lineStartIns, PRECEDENCE_UNARY, object, "--");
super(instruction, lineStartIns, PRECEDENCE_UNARY, object, "--", "Number");
}
@Override

View File

@@ -45,7 +45,7 @@ import java.util.List;
public class PreIncrementActionItem extends UnaryOpItem {
public PreIncrementActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem object) {
super(instruction, lineStartIns, PRECEDENCE_UNARY, object, "++");
super(instruction, lineStartIns, PRECEDENCE_UNARY, object, "++", "Number");
}
@Override

View File

@@ -34,7 +34,7 @@ import java.util.List;
public class RShiftActionItem extends BinaryOpItem {
public RShiftActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_BITWISESHIFT, leftSide, rightSide, ">>");
super(instruction, lineStartIns, PRECEDENCE_BITWISESHIFT, leftSide, rightSide, ">>", "int", "int");
}
@Override

View File

@@ -36,7 +36,7 @@ import java.util.List;
public class StrictEqActionItem extends BinaryOpItem implements LogicalOpItem, Inverted, EqualsTypeItem {
public StrictEqActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_EQUALITY, leftSide, rightSide, "===");
super(instruction, lineStartIns, PRECEDENCE_EQUALITY, leftSide, rightSide, "===", "", "");
}
@Override

View File

@@ -36,7 +36,7 @@ import java.util.List;
public class StrictNeqActionItem extends BinaryOpItem implements LogicalOpItem, Inverted {
public StrictNeqActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_EQUALITY, leftSide, rightSide, "!==");
super(instruction, lineStartIns, PRECEDENCE_EQUALITY, leftSide, rightSide, "!==", "", "");
}
@Override

View File

@@ -35,7 +35,7 @@ import java.util.Set;
public class StringAddActionItem extends BinaryOpItem {
public StringAddActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_ADDITIVE, leftSide, rightSide, "add");
super(instruction, lineStartIns, PRECEDENCE_ADDITIVE, leftSide, rightSide, "add", "String", "String");
}
@Override

View File

@@ -35,7 +35,7 @@ import java.util.Set;
public class StringEqActionItem extends BinaryOpItem implements Inverted {
public StringEqActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_EQUALITY, leftSide, rightSide, "eq");
super(instruction, lineStartIns, PRECEDENCE_EQUALITY, leftSide, rightSide, "eq", "String", "String");
}
@Override

View File

@@ -36,7 +36,7 @@ import java.util.Set;
public class StringGeActionItem extends BinaryOpItem implements Inverted {
public StringGeActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, leftSide, rightSide, "ge");
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, leftSide, rightSide, "ge", "String", "String");
}
@Override

View File

@@ -37,7 +37,7 @@ import java.util.Set;
public class StringGtActionItem extends BinaryOpItem implements Inverted {
public StringGtActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, leftSide, rightSide, "gt");
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, leftSide, rightSide, "gt", "String", "String");
}
@Override

View File

@@ -38,7 +38,7 @@ import java.util.Set;
public class StringLeActionItem extends BinaryOpItem implements Inverted {
public StringLeActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, leftSide, rightSide, "le");
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, leftSide, rightSide, "le", "String", "String");
}
@Override

View File

@@ -35,7 +35,7 @@ import java.util.Set;
public class StringLtActionItem extends BinaryOpItem implements Inverted {
public StringLtActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, leftSide, rightSide, "lt");
super(instruction, lineStartIns, PRECEDENCE_RELATIONAL, leftSide, rightSide, "lt", "String", "String");
}
@Override

View File

@@ -35,7 +35,7 @@ import java.util.Set;
public class StringNeActionItem extends BinaryOpItem implements Inverted {
public StringNeActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_EQUALITY, leftSide, rightSide, "ne");
super(instruction, lineStartIns, PRECEDENCE_EQUALITY, leftSide, rightSide, "ne", "String", "String");
}
@Override

View File

@@ -36,7 +36,7 @@ import java.util.List;
public class SubtractActionItem extends BinaryOpItem {
public SubtractActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_ADDITIVE, leftSide, rightSide, "-");
super(instruction, lineStartIns, PRECEDENCE_ADDITIVE, leftSide, rightSide, "-", "Number", "Number");
}
@Override
@@ -56,28 +56,26 @@ public class SubtractActionItem extends BinaryOpItem {
|| ((((DirectValueActionItem) leftSide).value instanceof Long) && (((Long) ((DirectValueActionItem) leftSide).value) == 0L)))) {
writer.append(operator);
writer.append(" ");
rightSide.appendTo(writer, localData);
rightSide.appendTry(writer, localData);
return writer;
} else {
if (rightSide.getPrecedence() >= precedence) { // >= add or subtract too
if (leftSide.getPrecedence() > precedence) {
writer.append("(");
leftSide.toString(writer, localData);
writer.append(")");
} else {
leftSide.toString(writer, localData);
}
writer.append(" ");
writer.append(operator);
writer.append(" ");
} else if (rightSide.getPrecedence() >= precedence) { // >= add or subtract too
if (leftSide.getPrecedence() > precedence) {
writer.append("(");
rightSide.toString(writer, localData);
return writer.append(")");
leftSide.toString(writer, localData);
writer.append(")");
} else {
return super.appendTo(writer, localData);
leftSide.toString(writer, localData);
}
writer.append(" ");
writer.append(operator);
writer.append(" ");
writer.append("(");
rightSide.toString(writer, localData);
return writer.append(")");
} else {
return super.appendTo(writer, localData);
}
}

View File

@@ -33,7 +33,7 @@ import java.util.List;
public class URShiftActionItem extends BinaryOpItem {
public URShiftActionItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(instruction, lineStartIns, PRECEDENCE_BITWISESHIFT, leftSide, rightSide, ">>>");
super(instruction, lineStartIns, PRECEDENCE_BITWISESHIFT, leftSide, rightSide, ">>>", "Number", "Number");
}
@Override

View File

@@ -83,7 +83,7 @@ public class VariableActionItem extends ActionItem {
if (it == null) {
return writer;
}
return it.appendTo(writer, localData);
return it.appendTry(writer, localData);
}
@Override

View File

@@ -0,0 +1,67 @@
/*
* Copyright (C) 2010-2016 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.flash.ecma;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author JPEXS
*/
public class ArrayType extends ObjectType {
public static final ObjectType EMPTY_ARRAY = new ArrayType();
public List<Object> values;
public ArrayType(List<Object> values) {
this.values = values;
}
private ArrayType() {
this.values = new ArrayList<>();
}
@Override
public String toString() {
StringBuilder s = new StringBuilder();
for (int i = 0; i < values.size(); i++) {
if (i > 0) {
s.append(",");
}
s.append(EcmaScript.toString(values.get(i)));
}
return s.toString();
}
@Override
public Object getAttribute(String name) {
if ("length".equals(name)) {
return (Long) (long) values.size();
}
if (name != null && name.matches("0|[1-9][0-9]*")) {
Long index = Long.parseLong(name);
int iindex = (int) (long) index;
if (iindex >= 0 && iindex < values.size()) {
return values.get(iindex);
}
}
return super.getAttribute(name);
}
}

View File

@@ -17,7 +17,14 @@
package com.jpexs.decompiler.flash.ecma;
import com.jpexs.decompiler.flash.action.swf4.ConstantIndex;
import com.jpexs.helpers.utf8.Utf8Helper;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
@@ -60,8 +67,56 @@ public class EcmaScript {
}
}
// todo: ToPrimitive
return 0.0;
return toNumber(toPrimitive(o, "Number"));
}
public static Object toPrimitive(Object o, String prefferedType) {
if (o == Undefined.INSTANCE) {
return o;
}
if (o == Null.INSTANCE) {
return o;
}
if (o == Boolean.TRUE || o == Boolean.FALSE) {
return o;
}
if (o instanceof Number) {
return o;
}
if (o instanceof String) {
return o;
}
if (o instanceof ObjectType) {
return object_defaultValue((ObjectType) o, prefferedType);
}
return Undefined.INSTANCE; //??
}
public static Object object_defaultValue(ObjectType o) {
return object_defaultValue(o, "Number");
}
public static Object object_get(ObjectType o, String p) {
//TODO: isDataDesciptor, etc. ECMA 8.12.3
return object_getProperty(o, p);
}
public static Object object_getProperty(ObjectType o, String p) {
//TODO: getownproperty, etc... ECMA 8.12.2
return o.getAttribute(p);
}
public static Object object_defaultValue(ObjectType o, String hint) {
switch (hint) {
case "String":
//TODO: logic similar to 8.12.8
return o.call("toString", new ArrayList<>());
case "Number":
default:
//TODO: logic similar to 8.12.8
return o.call("valueOf", new ArrayList<>());
}
}
public static Double toNumberAs2(Object o) {
@@ -408,4 +463,189 @@ public class EcmaScript {
return o.toString();
}
public static Double parseFloat(Object string) {
String inputString = toString(string);
int startPos = 0;
String trimmedString = "";
for (; startPos < inputString.length(); startPos++) {
char c = inputString.charAt(startPos);
if (!Character.isWhitespace(c)) {
trimmedString = inputString.substring(startPos);
break;
}
}
try {
return Double.parseDouble(trimmedString); //Is this the same?
} catch (NumberFormatException nfe) {
return Double.NaN;
}
}
public static Boolean isNaN(Object number) {
return Double.isNaN(toNumber(number));
}
public static Boolean isFinite(Object number) {
return Double.isFinite(toNumber(number));
}
public static Object parseInt(Object string, Object radix) {
String inputString = toString(string);
int startPos = 0;
String s = "";
for (; startPos < inputString.length(); startPos++) {
char c = inputString.charAt(startPos);
if (!Character.isWhitespace(c)) {
s = inputString.substring(startPos);
break;
}
}
int sign = 1;
if (!s.isEmpty() && s.charAt(0) == '-') {
sign = -1;
}
if (!s.isEmpty() && (s.charAt(0) == '+' || s.charAt(0) == '-')) {
s = s.substring(1);
}
int r = toInt32(radix);
boolean stripPrefix = true;
if (r != 0) {
if (r < 2 || r > 36) {
return Double.NaN;
}
if (r != 16) {
stripPrefix = false;
}
} else {
r = 10;
}
if (stripPrefix) {
if (s.length() >= 2) {
if (s.substring(0, 2).toLowerCase().equals("0x")) {
s = s.substring(2);
r = 16;
}
}
}
String allDigits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String allowedDigits = allDigits.substring(0, r);
String z = s;
for (int i = 0; i < s.length(); i++) {
if (("" + s.charAt(i)).matches("[" + allowedDigits + "]")) {
if (i == 0) {
z = "";
break;
}
z = s.substring(0, i);
break;
}
}
if (z.isEmpty()) {
return Double.NaN;
}
Long number = Long.parseLong(z, r);
return sign * number;
}
private static char toHex(int ch) {
return (char) (ch < 10 ? '0' + ch : 'A' + ch - 10);
}
private static String simpleCustomEncode(String input, String additionalValidChars) {
String alphas = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String num = "0123456789";
String alphaCases = alphas + alphas.toLowerCase();
String alphanum = alphaCases + num;
return customEncode(input, alphanum + additionalValidChars);
}
private static String simpleCustomDecode(String input, String additionalValidChars) {
String alphas = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String num = "0123456789";
String alphaCases = alphas + alphas.toLowerCase();
String alphanum = alphaCases + num;
return customDecode(input, alphanum + additionalValidChars);
}
private static String customEncode(String input, String validChars) {
StringBuilder resultStr = new StringBuilder();
for (char ch : input.toCharArray()) {
if (!validChars.contains("" + ch)) {
resultStr.append('%');
resultStr.append(toHex(ch / 16));
resultStr.append(toHex(ch % 16));
} else {
resultStr.append(ch);
}
}
return resultStr.toString();
}
private static String customDecode(String input, String reservedSet) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
for (int i = 0; i < input.length(); i++) {
char ch = input.charAt(i);
String s;
if (ch == '%' && i + 2 < input.length()) {
try {
int k = i;
int b = Integer.parseInt(input.substring(k + 1, k + 2 + 1), 16);
int msb = (b >> 15) & 1;
if (msb == 0) {
char c = (char) b;
if (!reservedSet.contains("" + c)) {
baos.write(c);
} else {
baos.write(Utf8Helper.getBytes(input.substring(k, k + 3)));
}
} else {
//here continues some multibyte character
//FIXME: is this working?
for (; msb == 1 && k < input.length() && input.charAt(k) == '%'; k += 3) {
b = Integer.parseInt(input.substring(k + 1, k + 2 + 1), 16);
msb = (b >> 15) & 1;
baos.write(b);
}
//throw error is msb=1
}
} catch (NumberFormatException nfe) {
//throw URIEx
} catch (IOException ex) {
}
}
}
try {
return baos.toString("UTF-8");
} catch (UnsupportedEncodingException ex) {
return null;
}
}
public static String encodeUriComponent(Object s) {
return simpleCustomEncode(toString(s), "-_.!~*'()");
}
public static String encodeUri(Object s) {
return simpleCustomEncode(toString(s), ";/?:@&=+$,#-_.!~*'()");
}
public static String escape(Object s) {
return simpleCustomEncode(toString(s), "@-_.*+/");
}
public static String decodeUriComponent(Object s) {
return simpleCustomDecode(toString(s), "-_.!~*'()");
}
public static String decodeUri(Object s) {
return simpleCustomDecode(toString(s), ";/?:@&=+$,#-_.!~*'()");
}
public static String unescape(Object s) {
return simpleCustomDecode(toString(s), "@-_.*+/");
}
}

View File

@@ -0,0 +1,84 @@
/*
* Copyright (C) 2010-2016 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.flash.ecma;
import com.jpexs.decompiler.flash.abc.avm2.model.Callable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
*
* @author JPEXS
*/
public class ObjectType implements Callable {
public static final ObjectType EMPTY_OBJECT = new ObjectType();
protected Map<String, Object> attributes;
public void setAttribute(String name, Object value) {
attributes.put(name, value);
}
public Set<String> getAttributeNames() {
return attributes.keySet();
}
protected ObjectType() {
this.attributes = new HashMap<>();
}
public ObjectType(Map<String, Object> attributes) {
this.attributes = attributes;
}
public Object getAttribute(String name) {
if (attributes.containsKey(name)) {
return attributes.get(name);
}
return Undefined.INSTANCE;
}
@Override
public String toString() {
return "[object Object]";
}
@Override
public Object call(String methodName, List<Object> args) {
switch (methodName) {
case "toString":
return toString();
case "valueOf":
return valueOf();
default:
return Undefined.INSTANCE; //?
}
}
public Object valueOf() {
return EcmaScript.toNumber(toString());
}
@Override
public Object call(List<Object> args) {
return Undefined.INSTANCE; //?
}
}

View File

@@ -17,15 +17,30 @@
package com.jpexs.decompiler.graph;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.abc.avm2.model.FloatValueAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.IntegerValueAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.NameValuePair;
import com.jpexs.decompiler.flash.abc.avm2.model.NewArrayAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.NewObjectAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.NullAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.StringAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.ThisAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.UndefinedAVM2Item;
import com.jpexs.decompiler.flash.action.model.DirectValueActionItem;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.ecma.ArrayType;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.flash.ecma.Null;
import com.jpexs.decompiler.flash.ecma.ObjectType;
import com.jpexs.decompiler.flash.ecma.Undefined;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.flash.helpers.HighlightedTextWriter;
import com.jpexs.decompiler.flash.helpers.hilight.HighlightData;
import com.jpexs.decompiler.graph.model.BinaryOp;
import com.jpexs.decompiler.graph.model.FalseItem;
import com.jpexs.decompiler.graph.model.LocalData;
import com.jpexs.decompiler.graph.model.NotItem;
import com.jpexs.decompiler.graph.model.TrueItem;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
@@ -90,6 +105,92 @@ public abstract class GraphTargetItem implements Serializable, Cloneable {
return lineStartItem;
}
protected static GraphTargetItem valToItem(Object r) {
if (r == null) {
return null;
}
if (r instanceof Boolean) {
if ((Boolean) r) {
return new TrueItem(null, null);
} else {
return new FalseItem(null, null);
}
}
if (r instanceof String) {
return new StringAVM2Item(null, null, (String) r);
}
if (r instanceof Long) {
return new IntegerValueAVM2Item(null, null, (Long) r);
}
if (r instanceof Integer) {
return new IntegerValueAVM2Item(null, null, (long) (int) (Integer) r);
}
if (r instanceof Double) {
return new FloatValueAVM2Item(null, null, (Double) r);
}
if (r instanceof Null) {
return new NullAVM2Item(null, null);
}
if (r instanceof Undefined) {
return new UndefinedAVM2Item(null, null);
}
if (r instanceof ArrayType) {
List<GraphTargetItem> vals = new ArrayList<>();
ArrayType at = (ArrayType) r;
for (Object v : at.values) {
vals.add(valToItem(v));
}
return new NewArrayAVM2Item(null, null, vals);
}
if (r instanceof ObjectType) {
List<NameValuePair> props = new ArrayList<>();
ObjectType ot = (ObjectType) r;
for (String k : ot.getAttributeNames()) {
props.add(new NameValuePair(valToItem(k), valToItem(ot.getAttribute(k))));
}
return new NewObjectAVM2Item(null, null, props);
}
return null;
}
public static GraphTargetItem simplifySomething(GraphTargetItem it, String implicitCoerce) {
if ((it instanceof SimpleValue) && implicitCoerce.isEmpty()) {
if (((SimpleValue) it).isSimpleValue()) {
return it;
}
}
if (!it.isCompileTime() && !(!implicitCoerce.isEmpty() && it.isConvertedCompileTime(new HashSet<>()))) {
return it;
}
Object r = it.getResult();
switch (implicitCoerce) {
case "String":
r = EcmaScript.toString(r);
break;
case "Number":
r = EcmaScript.toNumber(r);
break;
case "int":
r = EcmaScript.toInt32(r);
break;
case "Boolean":
r = EcmaScript.toBoolean(r);
break;
}
GraphTargetItem it2 = valToItem(r);
if (it2 == null) {
return it;
}
return it2;
}
public GraphTargetItem simplify(String implicitCoerce) {
return simplifySomething(this, implicitCoerce);
}
public int getLine() {
if (src != null) {
return src.getLine();
@@ -174,7 +275,7 @@ public abstract class GraphTargetItem implements Serializable, Cloneable {
}
writer.startOffset(src, getLineStartItem(), getPos(), srcData);
appendTo(writer, localData);
appendTry(writer, localData);
if (needsSemicolon()) {
writer.appendNoHilight(";");
}
@@ -191,19 +292,52 @@ public abstract class GraphTargetItem implements Serializable, Cloneable {
return getClass().getName();
}
public GraphTextWriter toString(GraphTextWriter writer, LocalData localData) throws InterruptedException {
public GraphTextWriter toStringBoolean(GraphTextWriter writer, LocalData localData) throws InterruptedException {
return toString(writer, localData, "Boolean");
}
public GraphTextWriter toStringString(GraphTextWriter writer, LocalData localData) throws InterruptedException {
return toString(writer, localData, "String");
}
public GraphTextWriter toStringInt(GraphTextWriter writer, LocalData localData) throws InterruptedException {
return toString(writer, localData, "int");
}
public GraphTextWriter toStringNumber(GraphTextWriter writer, LocalData localData) throws InterruptedException {
return toString(writer, localData, "Number");
}
public GraphTextWriter toString(GraphTextWriter writer, LocalData localData, String implicitCoerce) throws InterruptedException {
if (Thread.currentThread().isInterrupted()) {
throw new InterruptedException();
}
writer.startOffset(src, getLineStartItem(), getPos(), srcData);
appendTo(writer, localData);
appendTry(writer, localData, implicitCoerce);
writer.endOffset();
return writer;
}
public GraphTextWriter toString(GraphTextWriter writer, LocalData localData) throws InterruptedException {
return toString(writer, localData, "");
}
public abstract GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException;
public GraphTextWriter appendTry(GraphTextWriter writer, LocalData localData) throws InterruptedException {
return appendTry(writer, localData, "");
}
public GraphTextWriter appendTry(GraphTextWriter writer, LocalData localData, String implicitCoerce) throws InterruptedException {
GraphTargetItem t = this;
if (!implicitCoerce.isEmpty() && Configuration.autoDeobfuscate.get()) {
t = t.simplify(implicitCoerce);
}
return t.appendTo(writer, localData);
}
public String toString(LocalData localData) throws InterruptedException {
HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), false);
toString(writer, localData);
@@ -224,6 +358,10 @@ public abstract class GraphTargetItem implements Serializable, Cloneable {
return false;
}
public boolean isConvertedCompileTime(Set<GraphTargetItem> dependencies) {
return isCompileTime();
}
public boolean hasSideEffect() {
return false;
}
@@ -274,7 +412,7 @@ public abstract class GraphTargetItem implements Serializable, Cloneable {
public GraphTextWriter toStringNL(GraphTextWriter writer, LocalData localData) throws InterruptedException {
writer.startOffset(src, getLineStartItem(), getPos(), srcData);
appendTo(writer, localData);
appendTry(writer, localData);
if (needsNewLine()) {
writer.newLine();
}

View File

@@ -31,6 +31,12 @@ public class TranslateStack extends Stack<GraphTargetItem> {
private final String path;
public void simplify() {
for (int i = 0; i < size(); i++) {
set(i, get(i).simplify(""));
}
}
public TranslateStack(String path) {
this.path = path;
}

View File

@@ -40,7 +40,7 @@ public class AndItem extends BinaryOpItem {
}
public AndItem(GraphSourceItem src, GraphSourceItem lineStartIns, GraphTargetItem leftSide, GraphTargetItem rightSide) {
super(src, lineStartIns, PRECEDENCE_LOGICALAND, leftSide, rightSide, "&&");
super(src, lineStartIns, PRECEDENCE_LOGICALAND, leftSide, rightSide, "&&", "Boolean", "Boolean");
this.leftSide = leftSide;
this.rightSide = rightSide;
}

View File

@@ -38,6 +38,9 @@ public abstract class BinaryOpItem extends GraphTargetItem implements BinaryOp {
protected final String operator;
protected String coerceLeft;
protected String coerceRight;
@Override
public GraphPart getFirstPart() {
GraphPart fp = leftSide.getFirstPart();
@@ -47,11 +50,21 @@ public abstract class BinaryOpItem extends GraphTargetItem implements BinaryOp {
return fp;
}
public BinaryOpItem(GraphSourceItem instruction, GraphSourceItem lineStartItem, int precedence, GraphTargetItem leftSide, GraphTargetItem rightSide, String operator) {
public BinaryOpItem(GraphSourceItem instruction, GraphSourceItem lineStartItem, int precedence, GraphTargetItem leftSide, GraphTargetItem rightSide, String operator, String coerceLeft, String coerceRight) {
super(instruction, lineStartItem, precedence);
this.leftSide = leftSide;
this.rightSide = rightSide;
this.operator = operator;
this.coerceLeft = coerceLeft;
this.coerceRight = coerceRight;
}
@Override
public GraphTargetItem simplify(String implicitCoerce) {
BinaryOpItem r = (BinaryOpItem) clone();
r.leftSide = r.leftSide.simplify(coerceLeft);
r.rightSide = r.rightSide.simplify(coerceRight);
return simplifySomething(r, implicitCoerce);
}
@Override
@@ -98,7 +111,7 @@ public abstract class BinaryOpItem extends GraphTargetItem implements BinaryOp {
return false;
}
dependencies.add(rightSide);
return leftSide.isCompileTime(dependencies) && rightSide.isCompileTime(dependencies);
return leftSide.isConvertedCompileTime(dependencies) && rightSide.isConvertedCompileTime(dependencies);
}
@Override

Some files were not shown because too many files have changed in this diff Show More