xml import fixes

This commit is contained in:
honfika@gmail.com
2015-01-18 14:04:53 +01:00
parent 3ee9903bb3
commit 19256260d0
29 changed files with 284 additions and 75 deletions

View File

@@ -240,6 +240,7 @@ public final class SWF implements SWFContainerItem, Timelined {
/**
* Uncompressed size of the file
*/
@Internal
public long fileSize;
/**
* Used compression mode
@@ -248,6 +249,7 @@ public final class SWF implements SWFContainerItem, Timelined {
/**
* Compressed size of the file (LZMA)
*/
@Internal
public long compressedSize;
/**
* LZMA Properties

View File

@@ -12,7 +12,8 @@
* 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;
import com.jpexs.decompiler.flash.action.Action;
@@ -2361,7 +2362,7 @@ public class SWFInputStream implements AutoCloseable {
*/
public BUTTONCONDACTION readBUTTONCONDACTION(SWF swf, Tag tag, String name) throws IOException {
newDumpLevel(name, "BUTTONCONDACTION");
newDumpLevel(name, "BUTTONCONDACTION");
BUTTONCONDACTION ret = new BUTTONCONDACTION(swf, this, tag);
//ret.actions = readActionList();
endDumpLevel();
return ret;

View File

@@ -57,8 +57,8 @@ import com.jpexs.decompiler.flash.abc.usages.TypeNameMultinameUsage;
import com.jpexs.decompiler.flash.helpers.SWFDecompilerPlugin;
import com.jpexs.decompiler.flash.helpers.collections.MyEntry;
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
import com.jpexs.decompiler.flash.tags.SymbolClassTag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.types.annotations.Internal;
import com.jpexs.decompiler.graph.CompilationException;
import com.jpexs.helpers.utf8.Utf8PrintWriter;
import java.io.IOException;
@@ -83,15 +83,20 @@ public class ABC {
public List<ClassInfo> class_info = new ArrayList<>();
public List<ScriptInfo> script_info = new ArrayList<>();
public List<MethodBody> bodies = new ArrayList<>();
private List<Integer> bodyIdxFromMethodIdx = new ArrayList<>();
public long[] stringOffsets;
private Map<Integer, Integer> bodyIdxFromMethodIdx;
private long[] stringOffsets;
public static final int MINORwithDECIMAL = 17;
protected Set<EventListener> listeners = new HashSet<>();
private static final Logger logger = Logger.getLogger(ABC.class.getName());
private final AVM2Deobfuscation deobfuscation;
private AVM2Deobfuscation deobfuscation;
@Internal
public SWF swf;
@Internal
public ABCContainerTag parentTag;
/* Map from multiname index of namespace value to namespace name**/
private Map<String, String> namespaceMap;
public ABC(SWF swf) {
this.deobfuscation = null;
this.swf = swf;
@@ -106,14 +111,7 @@ public class ABC {
public int addMethodBody(MethodBody body) {
bodies.add(body);
if (body.method_info >= bodyIdxFromMethodIdx.size()) {
int newlen = body.method_info + 1;
int oldlen = bodyIdxFromMethodIdx.size();
for (int i = oldlen; i < newlen; i++) {
bodyIdxFromMethodIdx.add(-1);
}
bodyIdxFromMethodIdx.set(body.method_info, bodies.size() - 1);
}
bodyIdxFromMethodIdx = null;
return bodies.size() - 1;
}
@@ -268,6 +266,7 @@ public class ABC {
Map<Integer, String> stringUsageTypes = new HashMap<>();
informListeners("deobfuscate", "Getting usage types...");
getStringUsageTypes(stringUsageTypes, classesOnly);
AVM2Deobfuscation deobfuscation = getDeobfuscation();
for (int i = 0; i < instance_info.size(); i++) {
informListeners("deobfuscate", "class " + i + "/" + instance_info.size());
InstanceInfo insti = instance_info.get(i);
@@ -347,7 +346,6 @@ public class ABC {
logger.log(Level.FINE, "ABC minor_version: {0}, major_version: {1}", new Object[]{minor_version, major_version});
constants = new AVM2ConstantPool();
deobfuscation = new AVM2Deobfuscation(constants);
ais.newDumpLevel("constant_pool", "cpool_info");
// constant integers
@@ -481,10 +479,8 @@ public class ABC {
// method info
int methods_count = ais.readU30("methods_count");
method_info = new ArrayList<>(methods_count); // MethodInfo[methods_count];
bodyIdxFromMethodIdx = new ArrayList<>(methods_count);
for (int i = 0; i < methods_count; i++) {
method_info.add(ais.readMethodInfo("method"));
bodyIdxFromMethodIdx.add(-1);
}
// metadata info
@@ -555,12 +551,11 @@ public class ABC {
mb.traits = ais.readTraits("traits");
bodies.add(mb);
method_info.get(mb.method_info).setBody(mb);
bodyIdxFromMethodIdx.set(mb.method_info, i);
ais.endDumpLevel();
SWFDecompilerPlugin.fireMethodBodyParsed(mb, swf);
}
loadNamespaceMap();
/*for(int i=0;i<script_count;i++){
MethodBody bod=bodies.get(bodyIdxFromMethodIdx.get(script_info.get(i).init_index));
GraphTextWriter t=new HighlightedTextWriter(Configuration.getCodeFormatting(),false);
@@ -689,7 +684,7 @@ public class ABC {
if (methodInfo == -1) {
return -1;
}
return bodyIdxFromMethodIdx.get(methodInfo);
return getBodyIdxFromMethodIdx().get(methodInfo);
}
public MethodBody findBodyByClassAndName(String className, String methodName) {
@@ -791,30 +786,55 @@ public class ABC {
}
}
}
/* Map from multiname index of namespace value to namespace name**/
private HashMap<String, String> namespaceMap;
private void loadNamespaceMap() {
namespaceMap = new HashMap<>();
for (ScriptInfo si : script_info) {
for (Trait t : si.traits.traits) {
if (t instanceof TraitSlotConst) {
TraitSlotConst s = ((TraitSlotConst) t);
if (s.isNamespace()) {
String key = constants.getNamespace(s.value_index).getName(constants, true); // assume not null
String val = constants.getMultiname(s.name_index).getNameWithNamespace(constants, true);
namespaceMap.put(key, val);
private Map<String, String> getNamespaceMap() {
if (namespaceMap == null) {
Map<String, String> map = new HashMap<>();
for (ScriptInfo si : script_info) {
for (Trait t : si.traits.traits) {
if (t instanceof TraitSlotConst) {
TraitSlotConst s = ((TraitSlotConst) t);
if (s.isNamespace()) {
String key = constants.getNamespace(s.value_index).getName(constants, true); // assume not null
String val = constants.getMultiname(s.name_index).getNameWithNamespace(constants, true);
map.put(key, val);
}
}
}
}
namespaceMap = map;
}
return namespaceMap;
}
private AVM2Deobfuscation getDeobfuscation() {
if (deobfuscation == null) {
deobfuscation = new AVM2Deobfuscation(constants);
}
return deobfuscation;
}
private Map<Integer, Integer> getBodyIdxFromMethodIdx() {
if (bodyIdxFromMethodIdx == null) {
Map<Integer, Integer> map = new HashMap<>(bodies.size());
for (int i = 0; i < bodies.size(); i++) {
MethodBody mb = bodies.get(i);
map.put(mb.method_info, i);
}
bodyIdxFromMethodIdx = map;
}
return bodyIdxFromMethodIdx;
}
public String nsValueToName(String value) {
if (namespaceMap.containsKey(value)) {
return namespaceMap.get(value);
if (getNamespaceMap().containsKey(value)) {
return getNamespaceMap().get(value);
} else {
String ns = deobfuscation.builtInNs(value);
String ns = getDeobfuscation().builtInNs(value);
if (ns == null) {
return "";
} else {
@@ -1178,14 +1198,7 @@ public class ABC {
removeMethodFromTraits(si.traits, index);
}
if (bindex > -1) {
for (int mi = 0; mi < bodyIdxFromMethodIdx.size(); mi++) {
if (bodyIdxFromMethodIdx.get(mi) > bindex) {
bodyIdxFromMethodIdx.set(mi, bodyIdxFromMethodIdx.get(mi) - 1);
}
}
}
bodyIdxFromMethodIdx.remove(index);
bodyIdxFromMethodIdx = null;
method_info.remove(index);
}

View File

@@ -1560,7 +1560,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
}
String variableName = n.getVariableName();
if ("this".equals(variableName) || "super".equals(variableName) || paramNames.contains(variableName) || "argmuments".equals(variableName)) {
if ("this".equals(variableName) || "super".equals(variableName) || paramNames.contains(variableName) || "arguments".equals(variableName)) {
continue;
}

View File

@@ -23,7 +23,6 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceAIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceSIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertIIns;
import com.jpexs.decompiler.flash.abc.avm2.model.CallSuperAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.IntegerValueAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.NanAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.NullAVM2Item;

View File

@@ -12,7 +12,8 @@
* 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.abc.types;
/**
@@ -23,6 +24,9 @@ public class Decimal {
public byte[] data;
public Decimal() {
}
public Decimal(byte[] data) {
this.data = data;
}

View File

@@ -12,7 +12,8 @@
* 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.abc.types;
import com.jpexs.decompiler.flash.abc.ABC;
@@ -26,6 +27,7 @@ import com.jpexs.decompiler.flash.abc.types.traits.Traits;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.flash.types.annotations.SWFField;
import com.jpexs.decompiler.graph.Graph;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.ScopeStack;
@@ -54,6 +56,7 @@ public final class MethodBody implements Cloneable {
public int max_regs;
public int init_scope_depth;
public int max_scope_depth;
@SWFField
private byte[] codeBytes = new byte[0];
private AVM2Code code;
public ABCException[] exceptions = new ABCException[0];

View File

@@ -12,7 +12,8 @@
* 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.abc.types;
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
@@ -195,6 +196,9 @@ public class MethodInfo {
return (flags & FLAG_HAS_PARAMNAMES) == FLAG_HAS_PARAMNAMES;
}
public MethodInfo() {
}
public MethodInfo(int[] param_types, int ret_type, int name_index, int flags, ValueKind[] optional, int[] paramNames) {
this.param_types = param_types;
this.ret_type = ret_type;

View File

@@ -12,7 +12,8 @@
* 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.abc.types;
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
@@ -53,6 +54,9 @@ public class Multiname {
return cnt;
}
public Multiname() {
}
public Multiname(int kind, int name_index, int namespace_index, int namespace_set_index, int qname_index, List<Integer> params) {
this.kind = kind;
this.name_index = name_index;

View File

@@ -12,7 +12,8 @@
* 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.abc.types;
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
@@ -53,6 +54,9 @@ public class Namespace {
return null;
}
public Namespace() {
}
public Namespace(int kind, int name_index) {
this.kind = kind;
this.name_index = name_index;

View File

@@ -12,7 +12,8 @@
* 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.abc.types;
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
@@ -41,6 +42,9 @@ public class ValueKind {
public int value_index;
public int value_kind;
public ValueKind() {
}
public ValueKind(int value_index, int value_kind) {
this.value_index = value_index;
this.value_kind = value_kind;

View File

@@ -12,7 +12,8 @@
* 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.swf4;
import com.jpexs.decompiler.flash.SWFInputStream;
@@ -32,6 +33,7 @@ import com.jpexs.decompiler.flash.action.model.UnLoadMovieActionItem;
import com.jpexs.decompiler.flash.action.model.UnLoadMovieNumActionItem;
import com.jpexs.decompiler.flash.action.parser.ActionParseException;
import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer;
import com.jpexs.decompiler.flash.types.annotations.Reserved;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateStack;
import java.io.ByteArrayOutputStream;
@@ -47,6 +49,7 @@ public class ActionGetURL2 extends Action {
public static final int POST = 2;
public boolean loadTargetFlag;
public boolean loadVariablesFlag;
@Reserved
public int reserved;
public ActionGetURL2(int sendVarsMethod, boolean loadVariablesFlag, boolean loadTargetFlag) {

View File

@@ -12,7 +12,8 @@
* 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.swf4;
import com.jpexs.decompiler.flash.SWFInputStream;
@@ -21,6 +22,7 @@ import com.jpexs.decompiler.flash.action.Action;
import com.jpexs.decompiler.flash.action.model.GotoFrame2ActionItem;
import com.jpexs.decompiler.flash.action.parser.ActionParseException;
import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer;
import com.jpexs.decompiler.flash.types.annotations.Reserved;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateStack;
import java.io.ByteArrayOutputStream;
@@ -33,6 +35,7 @@ public class ActionGotoFrame2 extends Action {
boolean sceneBiasFlag;
boolean playFlag;
public int sceneBias;
@Reserved
int reserved;
public ActionGotoFrame2(boolean playFlag, boolean sceneBiasFlag, int sceneBias) {

View File

@@ -12,7 +12,8 @@
* 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.swf7;
import com.jpexs.decompiler.flash.SWFInputStream;
@@ -25,6 +26,7 @@ import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer;
import com.jpexs.decompiler.flash.action.parser.script.VariableActionItem;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.flash.types.annotations.Reserved;
import com.jpexs.decompiler.graph.GraphSourceItemContainer;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateStack;
@@ -51,6 +53,7 @@ public class ActionDefineFunction2 extends Action implements GraphSourceItemCont
public boolean preloadArgumentsFlag;
public boolean suppressThisFlag;
public boolean preloadThisFlag;
@Reserved
public int reserved;
public boolean preloadGlobalFlag;
public int registerCount;

View File

@@ -12,7 +12,8 @@
* 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.swf7;
import com.jpexs.decompiler.flash.SWFInputStream;
@@ -27,6 +28,7 @@ import com.jpexs.decompiler.flash.action.parser.pcode.ASMParsedSymbol;
import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer;
import com.jpexs.decompiler.flash.action.swf4.RegisterNumber;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.flash.types.annotations.Reserved;
import com.jpexs.decompiler.graph.GraphSourceItemContainer;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TranslateStack;
@@ -40,6 +42,7 @@ import java.util.Set;
public class ActionTry extends Action implements GraphSourceItemContainer {
@Reserved
public int reserved;
public boolean catchInRegisterFlag;
public boolean finallyBlockFlag;

View File

@@ -220,7 +220,7 @@ public class SwfJavaExporter {
sb2.indent();
sb2.indent();
String indent = getIndent(writer.getIndent() + 1, javaIndentString);
Field fields[] = obj.getClass().getFields();
Field[] fields = obj.getClass().getFields();
for (Field f : fields) {
if (Modifier.isStatic(f.getModifiers())) {
continue;

View File

@@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.helpers.LazyObject;
import com.jpexs.decompiler.flash.types.annotations.Internal;
import com.jpexs.helpers.ByteArrayRange;
import com.jpexs.helpers.Helper;
import com.jpexs.helpers.ReflectionTools;
import com.jpexs.helpers.utf8.Utf8OutputStreamWriter;
import java.io.BufferedWriter;
import java.io.File;
@@ -61,7 +62,6 @@ public class SwfXmlExporter {
try {
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document xmlDoc = docBuilder.newDocument();
xmlDoc.appendChild(xmlDoc.createComment("WARNING: The structure of this XML is not final. In later versions of FFDec it can be changed."));
exportXml(swf, xmlDoc, xmlDoc);
try (Writer writer = new BufferedWriter(new Utf8OutputStreamWriter(new FileOutputStream(file)))) {
writer.append(getXml(xmlDoc));
@@ -99,7 +99,7 @@ public class SwfXmlExporter {
if (obj == null) {
return;
}
Class cls = obj.getClass();
Object value = null;
@@ -156,10 +156,14 @@ public class SwfXmlExporter {
}
String className = obj.getClass().getSimpleName();
Field fields[] = obj.getClass().getFields();
List<Field> fields = ReflectionTools.getSwfFields(obj.getClass());
Element objNode = doc.createElement(name);
objNode.setAttribute("type", className);
node.appendChild(objNode);
if (level == 0) {
objNode.appendChild(doc.createComment("WARNING: The structure of this XML is not final. In later versions of FFDec it can be changed."));
}
for (Field f : fields) {
if (Modifier.isStatic(f.getModifiers())) {

View File

@@ -17,6 +17,24 @@
package com.jpexs.decompiler.flash.importers;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
import com.jpexs.decompiler.flash.abc.types.ABCException;
import com.jpexs.decompiler.flash.abc.types.ClassInfo;
import com.jpexs.decompiler.flash.abc.types.Decimal;
import com.jpexs.decompiler.flash.abc.types.InstanceInfo;
import com.jpexs.decompiler.flash.abc.types.MethodBody;
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
import com.jpexs.decompiler.flash.abc.types.Multiname;
import com.jpexs.decompiler.flash.abc.types.Namespace;
import com.jpexs.decompiler.flash.abc.types.NamespaceSet;
import com.jpexs.decompiler.flash.abc.types.ScriptInfo;
import com.jpexs.decompiler.flash.abc.types.ValueKind;
import com.jpexs.decompiler.flash.abc.types.traits.TraitClass;
import com.jpexs.decompiler.flash.abc.types.traits.TraitFunction;
import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter;
import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
import com.jpexs.decompiler.flash.abc.types.traits.Traits;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.types.ALPHABITMAPDATA;
import com.jpexs.decompiler.flash.types.ALPHACOLORMAPDATA;
@@ -31,7 +49,6 @@ import com.jpexs.decompiler.flash.types.COLORMAPDATA;
import com.jpexs.decompiler.flash.types.CXFORM;
import com.jpexs.decompiler.flash.types.CXFORMWITHALPHA;
import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.decompiler.flash.types.ConstantColorColorTransform;
import com.jpexs.decompiler.flash.types.FILLSTYLE;
import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY;
import com.jpexs.decompiler.flash.types.FOCALGRADIENT;
@@ -100,6 +117,7 @@ public class SwfXmlImporter {
private Map<String, Class> swfTags;
private Map<String, Class> swfObjects;
private Map<String, Class> swfObjectsParam;
public void importSwf(SWF swf, String xml) throws IOException {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
@@ -112,6 +130,18 @@ public class SwfXmlImporter {
}
}
private Field getField(Class cls, String name) throws NoSuchFieldException {
Field field;
try {
field = cls.getField(name);
} catch (NoSuchFieldException ex) {
field = cls.getDeclaredField(name);
field.setAccessible(true);
}
return field;
}
private void processElement(Element element, Object obj, SWF swf) {
Class cls = obj.getClass();
for (int i = 0; i < element.getAttributes().getLength(); i++) {
@@ -119,7 +149,7 @@ public class SwfXmlImporter {
String name = attr.getName();
if (!name.equals("type")) {
try {
Field field = cls.getField(name);
Field field = getField(cls, name);
String attrValue = attr.getValue();
field.set(obj, getAs(field.getType(), attrValue));
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) {
@@ -134,7 +164,7 @@ public class SwfXmlImporter {
Element child = (Element) childNode;
String name = child.getTagName();
try {
Field field = cls.getField(name);
Field field = getField(cls, name);
Class childCls = field.getType();
if (List.class.isAssignableFrom(childCls)) {
List list = new ArrayList();
@@ -193,12 +223,15 @@ public class SwfXmlImporter {
Map<Integer, Class> knownTags = Tag.getKnownClasses();
for (Integer key : knownTags.keySet()) {
Class cls = knownTags.get(key);
if (!ReflectionTools.canInstantiate(cls)) {
System.err.println("Can't instantiate: " + cls.getName());
}
tags.put(cls.getSimpleName(), cls);
}
swfTags = tags;
}
Class cls = swfTags.get(type);
if (cls != null) {
return cls.getConstructor(SWF.class).newInstance(swf);
@@ -208,15 +241,22 @@ public class SwfXmlImporter {
Map<String, Class> objects = new HashMap<>();
Class[] knownObjects = new Class[] { ALPHABITMAPDATA.class, ALPHACOLORMAPDATA.class, ARGB.class, BITMAPDATA.class,
BUTTONCONDACTION.class, BUTTONRECORD.class, CLIPACTIONRECORD.class, CLIPACTIONS.class, CLIPEVENTFLAGS.class,
COLORMAPDATA.class, ColorTransform.class, ConstantColorColorTransform.class, CXFORM.class, CXFORMWITHALPHA.class,
COLORMAPDATA.class, ColorTransform.class, CXFORM.class, CXFORMWITHALPHA.class,
FILLSTYLE.class, FILLSTYLEARRAY.class, FOCALGRADIENT.class, GLYPHENTRY.class, GRADIENT.class, GRADRECORD.class,
KERNINGRECORD.class, LANGCODE.class, LINESTYLE.class, LINESTYLE2.class, LINESTYLEARRAY.class, MATRIX.class,
MORPHFILLSTYLE.class, MORPHFILLSTYLEARRAY.class, MORPHFOCALGRADIENT.class, MORPHGRADIENT.class,
MORPHGRADRECORD.class, MORPHLINESTYLE.class, MORPHLINESTYLE2.class, MORPHLINESTYLEARRAY.class, PIX15.class,
PIX24.class, RECT.class, RGB.class, RGBA.class, SHAPE.class, SHAPEWITHSTYLE.class, SOUNDENVELOPE.class,
SOUNDINFO.class, TEXTRECORD.class, ZONEDATA.class, ZONERECORD.class,
CurvedEdgeRecord.class, EndShapeRecord.class, StraightEdgeRecord.class, StyleChangeRecord.class };
CurvedEdgeRecord.class, EndShapeRecord.class, StraightEdgeRecord.class, StyleChangeRecord.class,
AVM2ConstantPool.class, Decimal.class, Namespace.class, NamespaceSet.class, Multiname.class, MethodInfo.class,
ValueKind.class, InstanceInfo.class, Traits.class, TraitClass.class, TraitFunction.class,
TraitMethodGetterSetter.class, TraitSlotConst.class, ClassInfo.class, ScriptInfo.class, MethodBody.class,
ABCException.class };
for (Class cls2 : knownObjects) {
if (!ReflectionTools.canInstantiateDefaultConstructor(cls2)) {
System.err.println("Can't instantiate: " + cls2.getName());
}
objects.put(cls2.getSimpleName(), cls2);
}
@@ -228,6 +268,25 @@ public class SwfXmlImporter {
return cls.getConstructor().newInstance();
}
if (swfObjectsParam == null) {
Map<String, Class> objects = new HashMap<>();
Class[] knownObjects = new Class[] { ABC.class };
for (Class cls2 : knownObjects) {
if (!ReflectionTools.canInstantiate(cls2)) {
System.err.println("Can't instantiate: " + cls2.getName());
}
objects.put(cls2.getSimpleName(), cls2);
}
swfObjectsParam = objects;
}
cls = swfObjectsParam.get(type);
if (cls != null) {
return cls.getConstructor(SWF.class).newInstance(swf);
}
System.err.println("Type not found: " + type);
return null;
}

View File

@@ -25,6 +25,7 @@ import com.jpexs.decompiler.flash.abc.CopyOutputStream;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.annotations.HideInRawEdit;
import com.jpexs.decompiler.flash.types.annotations.SWFField;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.helpers.ByteArrayRange;
import java.io.ByteArrayInputStream;
@@ -45,6 +46,7 @@ public class DoABCDefineTag extends Tag implements ABCContainerTag {
* ActionScript 3 bytecodes
*/
@HideInRawEdit
@SWFField
private final ABC abc;
/**
* A 32-bit flags value, which may contain the following bits set:

View File

@@ -24,6 +24,7 @@ import com.jpexs.decompiler.flash.abc.ABCInputStream;
import com.jpexs.decompiler.flash.abc.CopyOutputStream;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.types.annotations.HideInRawEdit;
import com.jpexs.decompiler.flash.types.annotations.SWFField;
import com.jpexs.helpers.ByteArrayRange;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -39,6 +40,7 @@ public class DoABCTag extends Tag implements ABCContainerTag {
* ActionScript 3 bytecodes
*/
@HideInRawEdit
@SWFField
private final ABC abc;
public static final int ID = 72;

View File

@@ -12,7 +12,8 @@
* 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.types;
import com.jpexs.decompiler.flash.DisassemblyListener;
@@ -47,17 +48,21 @@ public class BUTTONCONDACTION implements ASMSource, Exportable, Serializable {
private final SWF swf;
private final Tag tag;
private final Tag tag;
@Override
public SWF getSwf() {
return swf;
}
// Constructor for Generic tag editor. TODO:Handle this somehow better
public BUTTONCONDACTION() {
swf = null;
tag = null;
}
public BUTTONCONDACTION(SWF swf, SWFInputStream sis, Tag tag) throws IOException {
this.swf = swf;
this.tag = tag;
this.tag = tag;
int condActionSize = sis.readUI16("condActionSize");
isLast = condActionSize <= 0;
condIdleToOverDown = sis.readUB(1, "condIdleToOverDown") == 1;

View File

@@ -12,7 +12,8 @@
* 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.types;
import com.jpexs.decompiler.flash.DisassemblyListener;
@@ -92,7 +93,7 @@ public class CLIPACTIONRECORD implements ASMSource, Exportable, Serializable {
@Internal
private final Tag tag;
// Constructor for Generic tag editor. TODO:Handle this somehow better
public CLIPACTIONRECORD() {
swf = null;
tag = null;

View File

@@ -22,7 +22,6 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Field is internal
*
* @author JPEXS
*/

View File

@@ -0,0 +1,32 @@
/*
* 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.
*/
package com.jpexs.decompiler.flash.types.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
*
* @author JPEXS
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface SWFField {
}

View File

@@ -873,7 +873,7 @@ public class Helper {
StringBuilder sb = new StringBuilder(text.length());
for (int i = 0; i < text.length(); i++) {
char ch = text.charAt(i);
if (i > 31 || i == 9 || i == 10 || i == 13) {
if (ch > 31 || ch == 9 || ch == 10 || ch == 13) {
sb.append(ch);
}
}

View File

@@ -16,10 +16,13 @@
*/
package com.jpexs.helpers;
import com.jpexs.decompiler.flash.types.annotations.Internal;
import com.jpexs.decompiler.flash.types.annotations.SWFField;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -96,6 +99,20 @@ public class ReflectionTools {
return true;
}
public static boolean canInstantiateDefaultConstructor(Class<?> cls) {
if (!canInstantiate(cls)) {
return false;
}
try {
cls.getConstructor();
} catch (NoSuchMethodException | SecurityException ex) {
return false;
}
return true;
}
public static boolean canAddToField(Object object, Field field) {
if (List.class.isAssignableFrom(field.getType())) {
@@ -300,4 +317,40 @@ public class ReflectionTools {
}
return true;
}
public static List<Field> getSwfFields(Class cls) {
List<Field> result = new ArrayList<>();
Field[] fields = cls.getFields();
for (Field f : fields) {
if (Modifier.isStatic(f.getModifiers())) {
continue;
}
Internal inter = f.getAnnotation(Internal.class);
if (inter != null) {
continue;
}
result.add(f);
}
fields = cls.getDeclaredFields();
// Add private fields marked with SWFField annotation
for (Field f : fields) {
if (Modifier.isStatic(f.getModifiers())) {
continue;
}
if (!Modifier.isPrivate(f.getModifiers())) {
continue;
}
SWFField swfField = f.getAnnotation(SWFField.class);
if (swfField != null) {
result.add(f);
}
}
return result;
}
}