diff --git a/.gitignore b/.gitignore index 25c90c1d4..d3caca575 100644 --- a/.gitignore +++ b/.gitignore @@ -1,71 +1,72 @@ -*.orig -*.dcu -*.ddp -*.orig.* -*.chg.* -*.rej -*.conflict~ -*.identcache -*.recompiled.swf -run_test_*.swf -Thumbs.db -/build/ -/reports/ -/installer.cfg -/releases/ -/locales/ -/javadoc/ -/coverage/ -/dist/ -/mac/ -/testdata/decompile/ -/testdata/recompile/ -/build_exe.xml -/build_exe64.xml -/coverage.ec -/libsrc/jsyntaxpane/jsyntaxpane/src/target/ -hs_err_pid*.log -*.~* -/revision.txt -/lib/ffdec_lib.jar -/lib/README.TXT -/libsrc/avi/nbproject/private/ -/libsrc/gnujpdf/dist/ -/libsrc/jsyntaxpane/jsyntaxpane/target/ -/libsrc/ffdec_lib/build/ -/libsrc/ffdec_lib/nbproject/private/ -/libsrc/ffdec_lib/javadoc/ -/libsrc/ffdec_lib/coverage/ -/libsrc/ffdec_lib/reports/ -/libsrc/ffdec_lib/dist/ -/libsrc/ffdec_lib/testdata/decompile/ -/libsrc/ffdec_lib/testdata/recompile/ -/libsrc/ffdec_lib/testdata/directediting/ -/libsrc/ffdec_lib/coverage.ec -/libsrc/ffdec_lib/revision.txt -/libsrc/gif/nbproject/private/ -/libsrc/gif/build/ -/libsrc/jpproxy/nbproject/private/ -/libsrc/jpproxy/dist/ -/libsrc/jpproxy/build/ -/libsrc/LZMA/nbproject/private/ -/libsrc/ttf/nbproject/private/ -/libsrc/ttf/build/ -/libsrc/tablelayout/nbproject/private/ -/libsrc/tablelayout/build/ -/libsrc/tablelayout/dist/ -/libsrc/uploader/nbproject/private/ -/libsrc/uploader/build/ -/libsrc/uploader/dist/ -/jpexs_website.properties -/version.properties -/tools.properties -/nbproject/private/ -/libsrc/cmykjpeg/build/ -/libsrc/cmykjpeg/nbproject/private/ -/libsrc/Plugins/nbproject/private/ -/libsrc/Plugins/build/ -/libsrc/Plugins/dist/ -/libsrc/treetable/nbproject/private/ -/libsrc/treetable/build/ -/libsrc/treetable/dist/ \ No newline at end of file +*.orig +*.dcu +*.ddp +*.orig.* +*.chg.* +*.rej +*.conflict~ +*.identcache +*.recompiled.swf +run_test_*.swf +Thumbs.db +/build/ +/reports/ +/installer.cfg +/releases/ +/locales/ +/javadoc/ +/coverage/ +/dist/ +/mac/ +/testdata/decompile/ +/testdata/recompile/ +/build_exe.xml +/build_exe64.xml +/coverage.ec +/libsrc/jsyntaxpane/jsyntaxpane/src/target/ +hs_err_pid*.log +*.~* +/revision.txt +/lib/ffdec_lib.jar +/lib/README.TXT +/libsrc/avi/nbproject/private/ +/libsrc/gnujpdf/dist/ +/libsrc/jsyntaxpane/jsyntaxpane/target/ +/libsrc/ffdec_lib/build/ +/libsrc/ffdec_lib/nbproject/private/ +/libsrc/ffdec_lib/javadoc/ +/libsrc/ffdec_lib/coverage/ +/libsrc/ffdec_lib/reports/ +/libsrc/ffdec_lib/dist/ +/libsrc/ffdec_lib/testdata/decompile/ +/libsrc/ffdec_lib/testdata/recompile/ +/libsrc/ffdec_lib/testdata/directediting/ +/libsrc/ffdec_lib/coverage.ec +/libsrc/ffdec_lib/revision.txt +/libsrc/gif/nbproject/private/ +/libsrc/gif/build/ +/libsrc/jpproxy/nbproject/private/ +/libsrc/jpproxy/dist/ +/libsrc/jpproxy/build/ +/libsrc/LZMA/nbproject/private/ +/libsrc/ttf/nbproject/private/ +/libsrc/ttf/build/ +/libsrc/tablelayout/nbproject/private/ +/libsrc/tablelayout/build/ +/libsrc/tablelayout/dist/ +/libsrc/uploader/nbproject/private/ +/libsrc/uploader/build/ +/libsrc/uploader/dist/ +/jpexs_website.properties +/version.properties +/tools.properties +/nbproject/private/ +/libsrc/cmykjpeg/build/ +/libsrc/cmykjpeg/nbproject/private/ +/libsrc/Plugins/nbproject/private/ +/libsrc/Plugins/build/ +/libsrc/Plugins/dist/ +/libsrc/treetable/nbproject/private/ +/libsrc/treetable/build/ +/libsrc/treetable/dist/ +/libsrc/plugins/nbproject/private/ \ No newline at end of file diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/AMF3InputStream.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/AMF3InputStream.java index 368232a91..9b0a162f9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/AMF3InputStream.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/AMF3InputStream.java @@ -12,8 +12,10 @@ import com.jpexs.decompiler.flash.amf.amf3.types.VectorDoubleType; import com.jpexs.decompiler.flash.amf.amf3.types.DictionaryType; import com.jpexs.decompiler.flash.amf.amf3.types.VectorUIntType; import com.jpexs.decompiler.flash.amf.amf3.types.BasicType; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.file.NoSuchFileException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -103,7 +105,7 @@ public class AMF3InputStream extends InputStream { byte buf[] = new byte[(int) byteLength]; //how about long strings(?), will the int length be enough? int cnt = is.read(buf); if (cnt < buf.length) { - throw new IOException("EOF"); + throw new PrematureEndOfTheStreamException(); } String retString = new String(buf, "UTF-8"); return retString; @@ -131,7 +133,7 @@ public class AMF3InputStream extends InputStream { private int safeRead() throws IOException { int ret = read(); if (ret == -1) { - throw new IOException("EOF"); + throw new PrematureEndOfTheStreamException(); } return ret; } @@ -141,11 +143,11 @@ public class AMF3InputStream extends InputStream { return is.read(); } - public Object readValue() throws IOException { + public Object readValue() throws IOException, NoSerializerExistsException { return readValue(new HashMap<>()); } - public Object readValue(Map serializers) throws IOException { + public Object readValue(Map serializers) throws IOException, NoSerializerExistsException { return readValue(serializers, new ArrayList<>(), new ArrayList<>(), new ArrayList<>()); } @@ -153,7 +155,7 @@ public class AMF3InputStream extends InputStream { List objectTable, List traitsTable, List stringTable - ) throws IOException { + ) throws IOException, NoSerializerExistsException { int marker = readU8(); switch (marker) { @@ -197,7 +199,7 @@ public class AMF3InputStream extends InputStream { byte buf[] = new byte[(int) byteLength]; //TODO: long strings, int is not enough for them int cnt = is.read(buf); if (cnt < buf.length) { - throw new IOException("EOF"); + throw new PrematureEndOfTheStreamException(); } xval = new String(buf, "UTF-8"); } @@ -243,14 +245,27 @@ public class AMF3InputStream extends InputStream { if (key.isEmpty()) { break; } else { - Object val = readValue(serializers, objectTable, traitsTable, stringTable); - assocPart.add(new Pair<>(key, val)); + try { + Object val = readValue(serializers, objectTable, traitsTable, stringTable); + assocPart.add(new Pair<>(key, val)); + } catch (NoSerializerExistsException nse) { + assocPart.add(new Pair<>(key, nse.getIncompleteData())); + throw new NoSerializerExistsException(nse.getClassName(), retArray, nse); + } } } LOGGER.log(Level.FINEST, "Array value: assocSize={0}", new Object[]{assocPart.size()}); for (int i = 0; i < denseCount; i++) { - densePart.add(readValue(serializers, objectTable, traitsTable, stringTable)); + try { + densePart.add(readValue(serializers, objectTable, traitsTable, stringTable)); + } catch (NoSerializerExistsException nse) { + densePart.add(nse.getIncompleteData()); + for (int j = i + 1; j < denseCount; j++) { + densePart.add(BasicType.UNKNOWN); + } + throw new NoSerializerExistsException(nse.getClassName(), retArray, nse); + } } LOGGER.log(Level.FINER, "Array value: dense_size={0},assocSize={1}", new Object[]{densePart.size(), assocPart.size()}); return retArray; @@ -274,13 +289,17 @@ public class AMF3InputStream extends InputStream { if (objectTraitsExtFlag == 1) { String className = readUtf8Vr(stringTable); if (!serializers.containsKey(className)) { - throw new IOException("No (de)serializer for class " + className + " found"); + throw new NoSerializerExistsException(className, new ObjectType(className, null, new ArrayList<>()), null); } - retObjectType = serializers.get(className).readObject(className, is); + + MonitoredInputStream mis = new MonitoredInputStream(is); + List> serMembers = serializers.get(className).readObject(className, mis); + byte serData[] = mis.getReadData(); + retObjectType = new ObjectType(className, serData, serMembers); + LOGGER.log(Level.FINER, "Object/Traits value: customSerialized"); - traits = new Traits(className, true, new ArrayList<>());// FIXME??? - traitsTable.add(traits); - //TODO: verify this + objectTable.add(retObjectType); + return retObjectType; } else { int dynamicFlag = (int) ((objectU29 >> 3) & 1); int numSealed = (int) (objectU29 >> 4); @@ -310,8 +329,19 @@ public class AMF3InputStream extends InputStream { Object retObjectType = new ObjectType(traits.isDynamic(), sealedMembers, dynamicMembers, traits.getClassName()); objectTable.add(retObjectType); //add it before any subvalue can reference it List sealedMemberValues = new ArrayList<>(); + NoSerializerExistsException error = null; + for (int i = 0; i < traits.getSealedMemberNames().size(); i++) { - sealedMemberValues.add(readValue(serializers, objectTable, traitsTable, stringTable)); + try { + sealedMemberValues.add(readValue(serializers, objectTable, traitsTable, stringTable)); + } catch (NoSerializerExistsException nse) { + sealedMemberValues.add(nse.getIncompleteData()); + for (int j = i + 1; j < traits.getSealedMemberNames().size(); j++) { + sealedMemberValues.add(BasicType.UNKNOWN); + } + error = nse; + break; + } } for (int i = 0; i < traits.getSealedMemberNames().size(); i++) { @@ -320,8 +350,13 @@ public class AMF3InputStream extends InputStream { if (traits.isDynamic()) { String dynamicMemberName; while (!(dynamicMemberName = readUtf8Vr(stringTable)).isEmpty()) { - Object dynamicMemberValue = readValue(serializers, objectTable, traitsTable, stringTable); - dynamicMembers.add(new Pair<>(dynamicMemberName, dynamicMemberValue)); + try { + Object dynamicMemberValue = readValue(serializers, objectTable, traitsTable, stringTable); + dynamicMembers.add(new Pair<>(dynamicMemberName, dynamicMemberValue)); + } catch (NoSerializerExistsException nse) { + dynamicMembers.add(new Pair<>(dynamicMemberName, nse.getIncompleteData())); + throw new NoSerializerExistsException(nse.getClassName(), retObjectType, nse); + } } } @@ -356,7 +391,7 @@ public class AMF3InputStream extends InputStream { int byteArrayLength = (int) (byteArrayU29 >> 1); byte byteArrayBuf[] = new byte[byteArrayLength]; if (is.read(byteArrayBuf) != byteArrayLength) { - throw new IOException("EOF"); + throw new PrematureEndOfTheStreamException(); } LOGGER.log(Level.FINER, "ByteArray value: bytes[{0}]", byteArrayLength); @@ -437,12 +472,25 @@ public class AMF3InputStream extends InputStream { int fixed = readU8(); String objectTypeName = readUtf8Vr(stringTable); //uses "*" for any type List vals = new ArrayList<>(); + NoSerializerExistsException error = null; for (int i = 0; i < vectorObjectCountItems; i++) { - vals.add(readValue(serializers, objectTable, traitsTable, stringTable)); + try { + vals.add(readValue(serializers, objectTable, traitsTable, stringTable)); + } catch (NoSerializerExistsException nse) { + vals.add(nse.getIncompleteData()); + for (int j = i + 1; j < vectorObjectCountItems; j++) { + vals.add(BasicType.UNKNOWN); + } + error = nse; + break; + } } VectorObjectType retVectorObject = new VectorObjectType(fixed == 1, objectTypeName, vals); LOGGER.log(Level.FINER, "Vector value: fixed={0}, size={1}, typeName:{2}]", new Object[]{fixed, vectorObjectCountItems, objectTypeName}); objectTable.add(retVectorObject); + if (error != null) { + throw new NoSerializerExistsException(error.getClassName(), retVectorObject, error); + } return retVectorObject; } else { int refIndexVectorObject = (int) (vectorObjectU29 >> 1); @@ -456,13 +504,37 @@ public class AMF3InputStream extends InputStream { int numEntries = (int) (dictionaryObjectU29 >> 1); int weakKeys = readU8(); List> data = new ArrayList<>(); + NoSerializerExistsException error = null; for (int i = 0; i < numEntries; i++) { - Object key = readValue(serializers, objectTable, traitsTable, stringTable); - Object val = readValue(serializers, objectTable, traitsTable, stringTable); + Object key; + Object val; + try { + key = readValue(serializers, objectTable, traitsTable, stringTable); + try { + val = readValue(serializers, objectTable, traitsTable, stringTable); + } catch (NoSerializerExistsException nse) { + error = nse; + val = BasicType.UNKNOWN; + } + } catch (NoSerializerExistsException nse) { + error = nse; + key = BasicType.UNKNOWN; + val = BasicType.UNKNOWN; + } + data.add(new Pair<>(key, val)); + if (error != null) { + for (int j = i + 1; j < numEntries; j++) { + data.add(new Pair<>(BasicType.UNKNOWN, BasicType.UNKNOWN)); + } + break; + } } DictionaryType retDictionary = new DictionaryType(weakKeys == 1, data); objectTable.add(retDictionary); + if (error != null) { + throw new NoSerializerExistsException(error.getClassName(), retDictionary, error); + } return retDictionary; } else { int refIndexDictionary = (int) (dictionaryObjectU29 >> 1); @@ -470,8 +542,31 @@ public class AMF3InputStream extends InputStream { return objectTable.get(refIndexDictionary); } default: - return null; + throw new UnsupportedValueType(marker); } } + private class MonitoredInputStream extends InputStream { + + private final InputStream is; + private ByteArrayOutputStream baos; + + public MonitoredInputStream(InputStream is) { + this.is = is; + this.baos = new ByteArrayOutputStream(); + } + + @Override + public int read() throws IOException { + int ret = is.read(); + if (ret > -1) { + baos.write(ret); + } + return ret; + } + + public byte[] getReadData() { + return baos.toByteArray(); + } + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/AMF3Tools.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/AMF3Tools.java index 85125208d..eb9daa7ba 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/AMF3Tools.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/AMF3Tools.java @@ -46,6 +46,9 @@ public class AMF3Tools { if (((List) Arrays.asList(String.class, Long.class, Double.class, BasicType.class, Boolean.class)).contains(object.getClass())) { return; } + if (object instanceof BasicType) { + return; + } int prevRef = 0; if (referenceCount.containsKey(object)) { prevRef = referenceCount.get(object); @@ -85,7 +88,11 @@ public class AMF3Tools { if (object instanceof String) { return "\"" + Helper.escapeActionScriptString((String) object) + "\""; } - if (((List) Arrays.asList(Long.class, Double.class, BasicType.class, Boolean.class)).contains(object.getClass())) { + if (((List) Arrays.asList(Long.class, Double.class, Boolean.class)).contains(object.getClass())) { + return object.toString(); + } + + if (object instanceof BasicType) { return object.toString(); } @@ -122,35 +129,58 @@ public class AMF3Tools { ret.append(indent(level + 1)).append("\"type\": \"Object\",\r\n"); ret.append(addId); ret.append(indent(level + 1)).append("\"className\": ").append(amfToString(processedObjects, level, ot.getClassName(), referenceCount, objectAlias)).append(",\r\n"); - ret.append(indent(level + 1)).append("\"dynamic\": ").append(ot.isDynamic()).append(",\r\n"); - if (!ot.getSealedMembers().isEmpty()) { - ret.append(indent(level + 1)).append("\"sealedMembers\": {\r\n"); - for (int i = 0; i < ot.getSealedMembers().size(); i++) { - Pair member = ot.getSealedMembers().get(i); - ret.append(indent(level + 2)).append(amfToString(processedObjects, level + 2, member.getFirst(), referenceCount, objectAlias)).append(":").append(amfToString(processedObjects, level + 1, member.getSecond(), referenceCount, objectAlias)); - if (i < ot.getSealedMembers().size() - 1) { - ret.append(",\r\n"); - } else { + if (ot.isSerialized()) { + byte[] serData = ot.getSerializedData(); + if (serData == null) { + ret.append(indent(level + 1)).append("\"serialized\": unknown\r\n"); + } else { + ret.append(indent(level + 1)).append("\"serialized\": 0x").append(javax.xml.bind.DatatypeConverter.printHexBinary(serData)).append(",\r\n"); + if (!ot.getSerializedMembers().isEmpty()) { + ret.append(indent(level + 1)).append("\"unserializedMembers\": {\r\n"); + for (int i = 0; i < ot.getSerializedMembers().size(); i++) { + Pair member = ot.getSerializedMembers().get(i); + ret.append(indent(level + 2)).append(amfToString(processedObjects, level + 2, member.getFirst(), referenceCount, objectAlias)).append(":").append(amfToString(processedObjects, level + 1, member.getSecond(), referenceCount, objectAlias)); + if (i < ot.getSerializedMembers().size() - 1) { + ret.append(",\r\n"); + } else { + ret.append("\r\n"); + } + } + ret.append(indent(level + 1)).append("}"); ret.append("\r\n"); } } - ret.append(indent(level + 1)).append("}"); - if (!ot.getDynamicMembers().isEmpty()) { - ret.append(","); - } - ret.append("\r\n"); - } - if (!ot.getDynamicMembers().isEmpty()) { - ret.append(indent(level + 1)).append("\"dynamicMembers\": {\r\n"); - for (int i = 0; i < ot.getDynamicMembers().size(); i++) { - Pair member = ot.getDynamicMembers().get(i); - ret.append(indent(level + 2)).append(amfToString(processedObjects, level + 2, member.getFirst(), referenceCount, objectAlias)).append(":").append(amfToString(processedObjects, level + 2, member.getSecond(), referenceCount, objectAlias)); - if (i < ot.getDynamicMembers().size() - 1) { + } else { + ret.append(indent(level + 1)).append("\"dynamic\": ").append(ot.isDynamic()).append(",\r\n"); + if (!ot.getSealedMembers().isEmpty()) { + ret.append(indent(level + 1)).append("\"sealedMembers\": {\r\n"); + for (int i = 0; i < ot.getSealedMembers().size(); i++) { + Pair member = ot.getSealedMembers().get(i); + ret.append(indent(level + 2)).append(amfToString(processedObjects, level + 2, member.getFirst(), referenceCount, objectAlias)).append(":").append(amfToString(processedObjects, level + 1, member.getSecond(), referenceCount, objectAlias)); + if (i < ot.getSealedMembers().size() - 1) { + ret.append(",\r\n"); + } else { + ret.append("\r\n"); + } + } + ret.append(indent(level + 1)).append("}"); + if (!ot.getDynamicMembers().isEmpty()) { ret.append(","); } ret.append("\r\n"); } - ret.append(indent(level + 1)).append("}\r\n"); + if (!ot.getDynamicMembers().isEmpty()) { + ret.append(indent(level + 1)).append("\"dynamicMembers\": {\r\n"); + for (int i = 0; i < ot.getDynamicMembers().size(); i++) { + Pair member = ot.getDynamicMembers().get(i); + ret.append(indent(level + 2)).append(amfToString(processedObjects, level + 2, member.getFirst(), referenceCount, objectAlias)).append(":").append(amfToString(processedObjects, level + 2, member.getSecond(), referenceCount, objectAlias)); + if (i < ot.getDynamicMembers().size() - 1) { + ret.append(","); + } + ret.append("\r\n"); + } + ret.append(indent(level + 1)).append("}\r\n"); + } } ret.append(indent(level)).append("}"); } else if (object instanceof ArrayType) { @@ -198,7 +228,7 @@ public class AMF3Tools { ret.append("\r\n"); } ret.append(indent(level + 1)).append("}\r\n"); - ret.append(indent(level)).append("}"); + ret.append(indent(level) + "}"); } else if (object instanceof ByteArrayType) { ByteArrayType ba = (ByteArrayType) object; byte data[] = ba.getData(); @@ -228,10 +258,6 @@ public class AMF3Tools { + addId + indent(level + 1) + "\"value\": " + amfToString(processedObjects, level, ((XmlType) object).getData(), referenceCount, objectAlias) + "\r\n" + indent(level) + "}"; - } else if (object == BasicType.NULL) { - return "null"; - } else if (object == BasicType.UNDEFINED) { - return "undefined"; } else { throw new IllegalArgumentException("Unsupported type: " + object.getClass()); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/NoSerializerExistsException.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/NoSerializerExistsException.java new file mode 100644 index 000000000..f4cd492f8 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/NoSerializerExistsException.java @@ -0,0 +1,25 @@ +package com.jpexs.decompiler.flash.amf.amf3; + +public class NoSerializerExistsException extends Exception { + + private final String className; + private final Object incompleteData; + + /*public NoSerializerExistsException(String className, Object incompleteData) { + this(className, incompleteData, null); + }*/ + public NoSerializerExistsException(String className, Object incompleteData, Throwable cause) { + super("Cannot read AMF - no deserializer defined for class \"" + className + "\".", cause); + this.className = className; + this.incompleteData = incompleteData; + } + + public String getClassName() { + return className; + } + + public Object getIncompleteData() { + return incompleteData; + } + +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/ObjectTypeSerializeHandler.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/ObjectTypeSerializeHandler.java index 67fe64ac2..1acbc0b71 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/ObjectTypeSerializeHandler.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/ObjectTypeSerializeHandler.java @@ -1,12 +1,13 @@ package com.jpexs.decompiler.flash.amf.amf3; -import com.jpexs.decompiler.flash.amf.amf3.types.ObjectType; +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.List; public interface ObjectTypeSerializeHandler { - public ObjectType readObject(String className, InputStream is); + public List> readObject(String className, InputStream is) throws IOException; - public void writeObject(ObjectType val, OutputStream os); + public void writeObject(List> members, OutputStream os) throws IOException; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/PrematureEndOfTheStreamException.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/PrematureEndOfTheStreamException.java new file mode 100644 index 000000000..8c85fa2df --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/PrematureEndOfTheStreamException.java @@ -0,0 +1,11 @@ +package com.jpexs.decompiler.flash.amf.amf3; + +import java.io.IOException; + +public class PrematureEndOfTheStreamException extends IOException { + + public PrematureEndOfTheStreamException() { + super("Premature end of the stream reached"); + } + +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/UnsupportedValueType.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/UnsupportedValueType.java new file mode 100644 index 000000000..1228a4cd1 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/UnsupportedValueType.java @@ -0,0 +1,16 @@ +package com.jpexs.decompiler.flash.amf.amf3; + +public class UnsupportedValueType extends RuntimeException { + + private int marker; + + public UnsupportedValueType(int marker) { + super("Unsupported type of value - marker: 0x" + Integer.toHexString(marker)); + this.marker = marker; + } + + public int getMarker() { + return marker; + } + +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/AbstractVectorType.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/AbstractVectorType.java new file mode 100644 index 000000000..ebdb1b2ad --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/AbstractVectorType.java @@ -0,0 +1,40 @@ +package com.jpexs.decompiler.flash.amf.amf3.types; + +import com.jpexs.decompiler.flash.amf.amf3.AMF3Tools; +import java.util.ArrayList; +import java.util.List; +import com.jpexs.decompiler.flash.amf.amf3.WithSubValues; + +public abstract class AbstractVectorType implements WithSubValues { + + private boolean fixed; + private List values; + + public boolean isFixed() { + return fixed; + } + + public AbstractVectorType(boolean fixed, List values) { + this.values = values; + this.fixed = fixed; + } + + public List getValues() { + return values; + } + + @Override + public List getSubValues() { + List ret = new ArrayList<>(); + ret.addAll(values); + return ret; + } + + public abstract String getTypeName(); + + @Override + public String toString() { + return AMF3Tools.amfToString(this); + } + +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/ArrayType.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/ArrayType.java new file mode 100644 index 000000000..a3caf7030 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/ArrayType.java @@ -0,0 +1,46 @@ +package com.jpexs.decompiler.flash.amf.amf3.types; + +import com.jpexs.decompiler.flash.amf.amf3.AMF3Tools; +import com.jpexs.decompiler.flash.amf.amf3.Pair; +import com.jpexs.helpers.Helper; +import java.util.ArrayList; +import java.util.List; +import com.jpexs.decompiler.flash.amf.amf3.WithSubValues; + +public class ArrayType implements WithSubValues { + + private List denseValues; + private List> associativeValues; + + public ArrayType(List denseValues, List> associativeValues) { + this.denseValues = denseValues; + this.associativeValues = associativeValues; + } + + public List getDenseValues() { + return denseValues; + } + + public List> getAssociativeValues() { + return associativeValues; + } + + @Override + public String toString() { + return AMF3Tools.amfToString(this); + } + + @Override + public List getSubValues() { + List ret = new ArrayList<>(); + for (Pair p : associativeValues) { + ret.add(p.getFirst()); + ret.add(p.getSecond()); + } + for (Object v : denseValues) { + ret.add(v); + } + return ret; + } + +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/BasicType.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/BasicType.java new file mode 100644 index 000000000..1d5752451 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/BasicType.java @@ -0,0 +1,26 @@ +package com.jpexs.decompiler.flash.amf.amf3.types; + +public enum BasicType { + NULL { + @Override + public String toString() { + return "null"; + } + + }, + UNDEFINED { + @Override + public String toString() { + return "undefined"; + } + + }, + //Special types for errors while reading + UNKNOWN { + @Override + public String toString() { + return "unknown"; + } + + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/ByteArrayType.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/ByteArrayType.java new file mode 100644 index 000000000..93cedf228 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/ByteArrayType.java @@ -0,0 +1,22 @@ +package com.jpexs.decompiler.flash.amf.amf3.types; + +import com.jpexs.decompiler.flash.amf.amf3.AMF3Tools; + +public class ByteArrayType { + + private byte[] data; + + public ByteArrayType(byte[] data) { + this.data = data; + } + + public byte[] getData() { + return data; + } + + @Override + public String toString() { + return AMF3Tools.amfToString(this); + } + +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/DateType.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/DateType.java new file mode 100644 index 000000000..821a8a0cb --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/DateType.java @@ -0,0 +1,30 @@ +package com.jpexs.decompiler.flash.amf.amf3.types; + +import com.jpexs.decompiler.flash.amf.amf3.AMF3Tools; +import java.util.Date; + +public class DateType { + + private double val; + + public DateType(double val) { + this.val = val; + } + + public double getVal() { + return val; + } + + public void setVal(double val) { + this.val = val; + } + + @Override + public String toString() { + return AMF3Tools.amfToString(this); + } + + public Date toDate() { + return new Date((long) val); + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/DictionaryType.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/DictionaryType.java new file mode 100644 index 000000000..29cf399f2 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/DictionaryType.java @@ -0,0 +1,38 @@ +package com.jpexs.decompiler.flash.amf.amf3.types; + +import com.jpexs.decompiler.flash.amf.amf3.AMF3Tools; +import com.jpexs.decompiler.flash.amf.amf3.Pair; +import java.util.ArrayList; +import java.util.List; +import com.jpexs.decompiler.flash.amf.amf3.WithSubValues; + +public class DictionaryType implements WithSubValues { + + private boolean weakKeys; + private List> pairs; + + public DictionaryType(boolean weakKeys, List> pairs) { + this.weakKeys = weakKeys; + this.pairs = pairs; + } + + public List> getPairs() { + return pairs; + } + + @Override + public List getSubValues() { + List ret = new ArrayList<>(); + for (Pair p : pairs) { + ret.add(p.getFirst()); + ret.add(p.getSecond()); + } + return ret; + } + + @Override + public String toString() { + return AMF3Tools.amfToString(this); + } + +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/ObjectType.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/ObjectType.java new file mode 100644 index 000000000..3e0dfb4cc --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/ObjectType.java @@ -0,0 +1,116 @@ +package com.jpexs.decompiler.flash.amf.amf3.types; + +import com.jpexs.decompiler.flash.amf.amf3.AMF3Tools; +import com.jpexs.decompiler.flash.amf.amf3.Pair; +import com.jpexs.helpers.Helper; +import java.util.ArrayList; +import java.util.List; +import com.jpexs.decompiler.flash.amf.amf3.WithSubValues; + +public class ObjectType implements WithSubValues { + + private boolean dynamic; + private List> sealedMembers; + private List> dynamicMembers; + private List> serializedMembers; + private String className; + //null = not serialized or unknown + private byte[] serializedData = null; + private boolean serialized; + + public boolean isSerialized() { + return serialized; + } + + public ObjectType(String className, byte[] serializedData, List> serializedMembers) { + this.className = className; + this.serializedData = serializedData; + this.serializedMembers = serializedMembers; + this.dynamicMembers = new ArrayList<>(); + this.sealedMembers = new ArrayList<>(); + this.serialized = true; + } + + public ObjectType(boolean dynamic, List> sealedMembers, List> dynamicMembers, String className) { + this.dynamic = dynamic; + this.sealedMembers = sealedMembers; + this.dynamicMembers = dynamicMembers; + this.className = className; + this.serializedMembers = new ArrayList<>(); + this.serialized = false; + } + + public boolean isDynamic() { + return dynamic; + } + + public List> getDynamicMembers() { + return dynamicMembers; + } + + public List> getSealedMembers() { + return sealedMembers; + } + + public String getClassName() { + return className; + } + + public void setDynamic(boolean dynamic) { + this.dynamic = dynamic; + } + + public void setDynamicMembers(List> dynamicMembers) { + this.dynamicMembers = dynamicMembers; + } + + public void setSealedMembers(List> sealedMembers) { + this.sealedMembers = sealedMembers; + } + + public void setClassName(String className) { + this.className = className; + } + + @Override + public List getSubValues() { + List ret = new ArrayList<>(); + for (Pair p : dynamicMembers) { + ret.add(p.getFirst()); + ret.add(p.getSecond()); + } + for (Pair p : sealedMembers) { + ret.add(p.getFirst()); + ret.add(p.getSecond()); + } + + for (Pair p : serializedMembers) { + ret.add(p.getFirst()); + ret.add(p.getSecond()); + } + + return ret; + } + + @Override + public String toString() { + return AMF3Tools.amfToString(this); + } + + public void setSerializedData(byte[] serializedData) { + this.serializedData = serializedData; + } + + public byte[] getSerializedData() { + return serializedData; + } + + public void setSerializedMembers(List> serializedMembers) { + this.serializedMembers = serializedMembers; + } + + public List> getSerializedMembers() { + return serializedMembers; + } + +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/VectorDoubleType.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/VectorDoubleType.java new file mode 100644 index 000000000..6755a08db --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/VectorDoubleType.java @@ -0,0 +1,16 @@ +package com.jpexs.decompiler.flash.amf.amf3.types; + +import java.util.List; + +public class VectorDoubleType extends AbstractVectorType { + + public VectorDoubleType(boolean fixed, List values) { + super(fixed, values); + } + + @Override + public String getTypeName() { + return "Number"; + } + +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/VectorIntType.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/VectorIntType.java new file mode 100644 index 000000000..2841545a8 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/VectorIntType.java @@ -0,0 +1,16 @@ +package com.jpexs.decompiler.flash.amf.amf3.types; + +import java.util.List; + +public class VectorIntType extends AbstractVectorType { + + public VectorIntType(boolean fixed, List values) { + super(fixed, values); + } + + @Override + public String getTypeName() { + return "int"; + } + +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/VectorObjectType.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/VectorObjectType.java new file mode 100644 index 000000000..98bad08cb --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/VectorObjectType.java @@ -0,0 +1,21 @@ +package com.jpexs.decompiler.flash.amf.amf3.types; + +import com.jpexs.helpers.Helper; +import java.util.ArrayList; +import java.util.List; + +public class VectorObjectType extends AbstractVectorType { + + private String typeName; + + public VectorObjectType(boolean fixed, String typeName, List values) { + super(fixed, values); + this.typeName = typeName; + } + + @Override + public String getTypeName() { + return typeName; + } + +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/VectorUIntType.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/VectorUIntType.java new file mode 100644 index 000000000..a130fd3ac --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/VectorUIntType.java @@ -0,0 +1,17 @@ +package com.jpexs.decompiler.flash.amf.amf3.types; + +import java.util.ArrayList; +import java.util.List; + +public class VectorUIntType extends AbstractVectorType { + + public VectorUIntType(boolean fixed, List values) { + super(fixed, values); + } + + @Override + public String getTypeName() { + return "uint"; + } + +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/XmlDocType.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/XmlDocType.java new file mode 100644 index 000000000..37207bccf --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/XmlDocType.java @@ -0,0 +1,24 @@ +package com.jpexs.decompiler.flash.amf.amf3.types; + +public class XmlDocType { + + private String data; + + public XmlDocType(String data) { + this.data = data; + } + + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + } + + @Override + public String toString() { + return data; + } + +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/XmlType.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/XmlType.java new file mode 100644 index 000000000..bd0e77027 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3/types/XmlType.java @@ -0,0 +1,24 @@ +package com.jpexs.decompiler.flash.amf.amf3.types; + +public class XmlType { + + private String data; + + public XmlType(String data) { + this.data = data; + } + + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + } + + @Override + public String toString() { + return data; + } + +} diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/amf/amf3/Amf3InputStreamTest.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/amf/amf3/Amf3InputStreamTest.java new file mode 100644 index 000000000..7a83cb0a5 --- /dev/null +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/amf/amf3/Amf3InputStreamTest.java @@ -0,0 +1,171 @@ +package com.jpexs.decompiler.flash.amf.amf3; + +import com.jpexs.decompiler.flash.amf.amf3.types.ArrayType; +import com.jpexs.decompiler.flash.amf.amf3.types.DictionaryType; +import com.jpexs.decompiler.flash.amf.amf3.types.ObjectType; +import com.jpexs.decompiler.flash.amf.amf3.types.VectorObjectType; +import java.io.ByteArrayInputStream; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import static org.testng.Assert.*; +import org.testng.annotations.AfterTest; +import org.testng.annotations.Test; + +public class Amf3InputStreamTest { + + private FileInputStream fis; + private AMF3InputStream is; + + @AfterTest + public void deinitStream() { + if (is != null) { + try { + is.close(); + } catch (IOException ex) { + //ignore + } + is = null; + } + if (fis != null) { + try { + fis.close(); + } catch (IOException ex) { + //ignore + } + fis = null; + } + } + + private void initStream(String fileName) throws FileNotFoundException { + fis = new FileInputStream("testdata/amf3/generated/" + fileName); + is = new AMF3InputStream(fis); + } + + @Test + public void testReadObject() throws IOException, NoSerializerExistsException { + initStream("all.bin"); + is.readValue(); + } + + private Map getSerializers() { + Map serializers = new HashMap<>(); + serializers.put("CustomClass", new ObjectTypeSerializeHandler() { + @Override + public List> readObject(String className, InputStream is) throws IOException { + List> members = new ArrayList<>(); + members.add(new Pair<>("val8", (long) is.read())); + members.add(new Pair<>("val32", (long) ((is.read() << 24) + (is.read() << 16) + (is.read() << 8) + (is.read())))); + return members; + } + + @Override + public void writeObject(List> members, OutputStream os) throws IOException { + throw new UnsupportedOperationException("Not supported yet."); + } + }); + return serializers; + } + + @Test(expectedExceptions = NoSerializerExistsException.class) + public void testReadCustomSerializedNeedsSerializer() throws IOException, NoSerializerExistsException { + initStream("custom.bin"); + is.readValue(); //needs deserializer for CustomClass + } + + @Test + public void testReadCustomSerialized() throws IOException, NoSerializerExistsException { + initStream("custom.bin"); + is.readValue(getSerializers()); + } + + @Test + public void testNoSerializerHandlingInObjectDynamicProp() throws IOException { + initStream("noserializer_object_dynamic.bin"); + try { + is.readValue(); + } catch (NoSerializerExistsException ex) { + assertTrue(ex.getIncompleteData() instanceof ObjectType, "Expected datatype: ObjectType, Actual datatype: " + ex.getIncompleteData().getClass()); + //TODO: examinate the data more + } + } + + @Test + public void testNoSerializerHandlingInObjectSealedProp() throws IOException { + initStream("noserializer_object_sealed.bin"); + try { + is.readValue(); + } catch (NoSerializerExistsException ex) { + assertTrue(ex.getIncompleteData() instanceof ObjectType, "Expected datatype: ObjectType, Actual datatype: " + ex.getIncompleteData().getClass()); + //TODO: examinate the data more + } + } + + @Test + public void testNoSerializerHandlingInArrayDense() throws IOException { + initStream("noserializer_array_dense.bin"); + try { + is.readValue(); + } catch (NoSerializerExistsException ex) { + assertTrue(ex.getIncompleteData() instanceof ArrayType, "Expected datatype: ArrayType, Actual datatype: " + ex.getIncompleteData().getClass()); + //TODO: examinate the data more + } + } + + @Test + public void testNoSerializerHandlingInArrayAssociative() throws IOException { + initStream("noserializer_array_associative.bin"); + try { + is.readValue(); + } catch (NoSerializerExistsException ex) { + assertTrue(ex.getIncompleteData() instanceof ArrayType, "Expected datatype: ArrayType, Actual datatype: " + ex.getIncompleteData().getClass()); + //TODO: examinate the data more + } + } + + @Test + public void testNoSerializerHandlingInVector() throws IOException { + initStream("noserializer_vector.bin"); + try { + is.readValue(); + } catch (NoSerializerExistsException ex) { + assertTrue(ex.getIncompleteData() instanceof VectorObjectType, "Expected datatype: VectorObjectType, Actual datatype: " + ex.getIncompleteData().getClass()); + //TODO: examinate the data more + } + } + + @Test + public void testNoSerializerHandlingInDictionaryValues() throws IOException { + initStream("noserializer_dictionary_value.bin"); + try { + is.readValue(); + } catch (NoSerializerExistsException ex) { + assertTrue(ex.getIncompleteData() instanceof DictionaryType, "Expected datatype: DictionaryType, Actual datatype: " + ex.getIncompleteData().getClass()); + //TODO: examinate the data more + } + } + + @Test + public void testNoSerializerHandlingInDictionaryKeys() throws IOException { + initStream("noserializer_dictionary_key.bin"); + try { + is.readValue(); + } catch (NoSerializerExistsException ex) { + assertTrue(ex.getIncompleteData() instanceof DictionaryType, "Expected datatype: DictionaryType, Actual datatype: " + ex.getIncompleteData().getClass()); + //TODO: examinate the data more + } + } + + @Test(expectedExceptions = UnsupportedValueType.class) + public void testUnsupportedMarker() throws IOException, NoSerializerExistsException { + final int UNSUPPORTED_MARKER = 100; + is = new AMF3InputStream(new ByteArrayInputStream(new byte[]{UNSUPPORTED_MARKER})); + is.readValue(); + } +} diff --git a/libsrc/ffdec_lib/testdata/amf3/AmfTest.as b/libsrc/ffdec_lib/testdata/amf3/AmfTest.as new file mode 100644 index 000000000..37c7934fc --- /dev/null +++ b/libsrc/ffdec_lib/testdata/amf3/AmfTest.as @@ -0,0 +1,169 @@ +package +{ + import flash.display.Sprite; + import flash.utils.ByteArray; + import flash.filesystem.File; + import flash.filesystem.FileStream; + import flash.filesystem.FileMode; + + import flash.utils.Dictionary; + import flash.geom.Point; + import flash.xml.XMLDocument; + + import flash.net.registerClassAlias; + + /** + * Generating test data file + */ + public class AmfTest extends Sprite + { + + private function writeToFile(filename:String,data) + { + var urlStr:String = "file:///"+File.applicationDirectory.nativePath+"/generated/"+filename; + var file:File = new File() ; + file.url = urlStr; + var fileStream:FileStream = new FileStream(); + fileStream.open(file, FileMode.WRITE); + var bytes:ByteArray = new ByteArray(); + bytes.writeObject(data); + fileStream.writeBytes(bytes, 0, bytes.length); + fileStream.close(); + + } + + public function AmfTest() { + + + + var ar = ["a","b","c"]; + + var asoc_array = [1,2,3]; + asoc_array["key1"] = 5; + asoc_array["key2"] = 6; + + var ba:ByteArray = new ByteArray(); + ba.writeByte(65); + ba.writeByte(66); + ba.writeByte(67); + + + var vector_int:Vector. = new [-10,20,-30,40]; + var vector_uint:Vector. = new [10,20,30,40]; + var vector_double:Vector. = new [-10.1,20.2,-30.3,40.4]; + var vector_string:Vector. = new ["x","y","z"]; + var vector_point:Vector. = new [new Point(10,20),new Point(30,40),new Point(50,60)]; + + var dict = new Dictionary(); + dict["dkey1"] = "TestOne"; + dict["dkey2"] = "TestTwo"; + + var txmldoc:XMLDocument = new XMLDocument("aa"); + + var txml:XML = + Hello + Hi + ; + + var date = new Date(); + + var me = { + "01_int":5, + "02_negative-int":-5, + "03_string":"String", + "04_true":true, + "05_false":false, + "06_undefined":undefined, + "07_null":null, + "08_double":5.6, + "09_negative-double":-5.6, + "10_array":ar, + "11_asoc_array": asoc_array, + "12_date":date, + "13_xml":txml, + "14_byteArray":ba, + "15_vectorInt":vector_int, + "16_vectorUInt":vector_uint, + "17_vectorDouble":vector_double, + "18_vectorString":vector_string, + "19_vectorPoint":vector_point, + "20_dictionary":dict, + "21_xmldoc":txmldoc, + "22_ref_string":"String", + "23_ref_array":ar, + "24_ref_date":date, + "25_ref_byteArray":ba, + "26_ref_vectorInt":vector_int, + "27_ref_vectorUInt":vector_uint, + "28_ref_vectorDouble":vector_double, + "29_ref_vectorString":vector_string, + "30_ref_dictionary":dict, + "31_ref_xml":txml, + "32_ref_xmldoc":txmldoc + }; + me["33_me"] = me; + + writeToFile("all.bin",me); + + var custom = new CustomClass(); + custom.setVal8(127); + custom.setVal32(-2500); + registerClassAlias("CustomClass", CustomClass); + + var cust_obj = { + "member1":5, + "member2":custom, + "member3":27 + }; + + writeToFile("custom.bin",cust_obj); + + writeToFile("noserializer_object_dynamic.bin",{ + "a":5, + "b":8, + "c":custom, + "d":6, + "e":7, + "f":26 + }); + writeToFile("noserializer_array_dense.bin", + ["a","b",custom,"d","e","f"] + ); + + var arx = []; + arx["a"] = 1; + arx["b"] = 2; + arx["c"] = custom; + arx["d"] = 4; + arx["e"] = 5; + arx["f"] = 6; + writeToFile("noserializer_array_associative.bin", arx); + + + writeToFile("noserializer_vector.bin", new ["a","b",custom,"d","e","f"]); + + var nsdict = new Dictionary(); + nsdict["a"] = "One"; + nsdict["b"] = "Two"; + nsdict["c"] = custom; + nsdict["d"] = "Three"; + nsdict["e"] = "Four"; + nsdict["f"] = "Five"; + + writeToFile("noserializer_dictionary_value.bin", nsdict); + + var nsdict2 = new Dictionary(); + nsdict2["a"] = "One"; + nsdict2["b"] = "Two"; + nsdict2[custom] = "Three"; + nsdict2["d"] = "Three"; + nsdict2["e"] = "Four"; + nsdict2["f"] = "Five"; + + writeToFile("noserializer_dictionary_key.bin", nsdict2); + + var objWithCustom:ObjectWithCustom = new ObjectWithCustom("1","2",custom,"4","5","6"); + writeToFile("noserializer_object_sealed.bin", objWithCustom); + } + } +} \ No newline at end of file diff --git a/libsrc/ffdec_lib/testdata/amf3/AmfTest.swf b/libsrc/ffdec_lib/testdata/amf3/AmfTest.swf new file mode 100644 index 000000000..eed907c18 Binary files /dev/null and b/libsrc/ffdec_lib/testdata/amf3/AmfTest.swf differ diff --git a/libsrc/ffdec_lib/testdata/amf3/CustomClass.as b/libsrc/ffdec_lib/testdata/amf3/CustomClass.as new file mode 100644 index 000000000..d353e27f4 --- /dev/null +++ b/libsrc/ffdec_lib/testdata/amf3/CustomClass.as @@ -0,0 +1,32 @@ +package +{ + import flash.utils.IExternalizable; + import flash.utils.IDataOutput; + import flash.utils.IDataInput; + + public class CustomClass implements IExternalizable + { + + private var val8:int; + private var val32:int; + public function CustomClass() { //No constructor parameters allowed + } + + public function setVal8(v:int){ + this.val8 = v; + } + public function setVal32(v:int){ + this.val32 = v; + } + + public function writeExternal(output:IDataOutput):void { + output.writeByte(val8); + output.writeInt(val32); + } + + public function readExternal(input:IDataInput):void { + this.val8 = input.readByte(); + this.val32 = input.readInt(); + } + } +} \ No newline at end of file diff --git a/libsrc/ffdec_lib/testdata/amf3/ObjectWithCustom.as b/libsrc/ffdec_lib/testdata/amf3/ObjectWithCustom.as new file mode 100644 index 000000000..21db1efa6 --- /dev/null +++ b/libsrc/ffdec_lib/testdata/amf3/ObjectWithCustom.as @@ -0,0 +1,24 @@ +package +{ + public class ObjectWithCustom + { + + public var a:String; + public var b:String; + public var c:CustomClass; + public var d:String; + public var e:String; + public var f:String; + + + public function ObjectWithCustom(a:String,b:String,c:CustomClass,d:String,e:String,f:String) { + this.a = a; + this.b = b; + this.c = c; + this.d = d; + this.e = e; + this.f = f; + } + + } +} \ No newline at end of file diff --git a/libsrc/ffdec_lib/testdata/amf3/app.xml b/libsrc/ffdec_lib/testdata/amf3/app.xml new file mode 100644 index 000000000..403dadf31 --- /dev/null +++ b/libsrc/ffdec_lib/testdata/amf3/app.xml @@ -0,0 +1,14 @@ + + + samples.flex.HelloWorld + 1 + HelloWorld + + AmfTest.swf + true + none + true + 400 + 200 + + \ No newline at end of file diff --git a/libsrc/ffdec_lib/testdata/amf3/generated/all.bin b/libsrc/ffdec_lib/testdata/amf3/generated/all.bin new file mode 100644 index 000000000..22b5dc4c0 Binary files /dev/null and b/libsrc/ffdec_lib/testdata/amf3/generated/all.bin differ diff --git a/libsrc/ffdec_lib/testdata/amf3/generated/custom.bin b/libsrc/ffdec_lib/testdata/amf3/generated/custom.bin new file mode 100644 index 000000000..c3bed6b07 --- /dev/null +++ b/libsrc/ffdec_lib/testdata/amf3/generated/custom.bin @@ -0,0 +1,3 @@ + + member3member1member2 +CustomClassÿÿö< \ No newline at end of file diff --git a/libsrc/ffdec_lib/testdata/amf3/generated/noserializer_array_associative.bin b/libsrc/ffdec_lib/testdata/amf3/generated/noserializer_array_associative.bin new file mode 100644 index 000000000..c1b45c8b6 --- /dev/null +++ b/libsrc/ffdec_lib/testdata/amf3/generated/noserializer_array_associative.bin @@ -0,0 +1,2 @@ + fabc +CustomClassÿÿö<de \ No newline at end of file diff --git a/libsrc/ffdec_lib/testdata/amf3/generated/noserializer_array_dense.bin b/libsrc/ffdec_lib/testdata/amf3/generated/noserializer_array_dense.bin new file mode 100644 index 000000000..5438f07e1 --- /dev/null +++ b/libsrc/ffdec_lib/testdata/amf3/generated/noserializer_array_dense.bin @@ -0,0 +1,2 @@ + ab +CustomClassÿÿö<def \ No newline at end of file diff --git a/libsrc/ffdec_lib/testdata/amf3/generated/noserializer_dictionary_key.bin b/libsrc/ffdec_lib/testdata/amf3/generated/noserializer_dictionary_key.bin new file mode 100644 index 000000000..24d9b65ac Binary files /dev/null and b/libsrc/ffdec_lib/testdata/amf3/generated/noserializer_dictionary_key.bin differ diff --git a/libsrc/ffdec_lib/testdata/amf3/generated/noserializer_dictionary_value.bin b/libsrc/ffdec_lib/testdata/amf3/generated/noserializer_dictionary_value.bin new file mode 100644 index 000000000..05d9b4e62 Binary files /dev/null and b/libsrc/ffdec_lib/testdata/amf3/generated/noserializer_dictionary_value.bin differ diff --git a/libsrc/ffdec_lib/testdata/amf3/generated/noserializer_object_dynamic.bin b/libsrc/ffdec_lib/testdata/amf3/generated/noserializer_object_dynamic.bin new file mode 100644 index 000000000..e7793c3ae --- /dev/null +++ b/libsrc/ffdec_lib/testdata/amf3/generated/noserializer_object_dynamic.bin @@ -0,0 +1,3 @@ + + fabc +CustomClassÿÿö<de \ No newline at end of file diff --git a/libsrc/ffdec_lib/testdata/amf3/generated/noserializer_object_sealed.bin b/libsrc/ffdec_lib/testdata/amf3/generated/noserializer_object_sealed.bin new file mode 100644 index 000000000..cfaf1f8c4 --- /dev/null +++ b/libsrc/ffdec_lib/testdata/amf3/generated/noserializer_object_sealed.bin @@ -0,0 +1,3 @@ + +ccfadbe +CustomClassÿÿö<61425 \ No newline at end of file diff --git a/libsrc/ffdec_lib/testdata/amf3/generated/noserializer_vector.bin b/libsrc/ffdec_lib/testdata/amf3/generated/noserializer_vector.bin new file mode 100644 index 000000000..ff6653f8d Binary files /dev/null and b/libsrc/ffdec_lib/testdata/amf3/generated/noserializer_vector.bin differ diff --git a/libsrc/ffdec_lib/testdata/amf3/run.bat b/libsrc/ffdec_lib/testdata/amf3/run.bat new file mode 100644 index 000000000..e7aa460f3 --- /dev/null +++ b/libsrc/ffdec_lib/testdata/amf3/run.bat @@ -0,0 +1,20 @@ +@echo off +set ISDEBUG=false +if "%1" == "debug" goto blockset +goto block2 +:blockset +set ISDEBUG=true +:block2 +set AIRPATH=c:\air +set COMPILERPATH=%AIRPATH%\bin\amxmlc.bat +if not exist %COMPILERPATH% goto notex +call %COMPILERPATH% -warnings=false -debug=%ISDEBUG% AmfTest.as>NUL +if errorlevel==1 goto failed +goto end +:notex +echo AIR SDK not found. Download and unpack Flex SDK into C:\air directory, then run build again +goto end +:failed +pause +:end +%AIRPATH%\bin\adl.exe app.xml \ No newline at end of file diff --git a/libsrc/ffdec_lib/testdata/as3/CustomClass.as b/libsrc/ffdec_lib/testdata/as3/CustomClass.as new file mode 100644 index 000000000..3f268b9dc --- /dev/null +++ b/libsrc/ffdec_lib/testdata/as3/CustomClass.as @@ -0,0 +1,34 @@ +package +{ + import flash.utils.IExternalizable; + import flash.utils.IDataOutput; + import flash.utils.IDataInput; + + public class CustomClass implements IExternalizable + { + + private var val8:int; + private var val32:int; + public function CustomClass() + { + } + + public function setVal8(v:int){ + this.val8 = v; + } + public function setVal32(v:int){ + this.val32 = v; + } + + public function writeExternal(output:IDataOutput):void { + output.writeByte(val8); + output.writeInt(val32); + + } + + public function readExternal(input:IDataInput):void { + this.val8 = input.readByte(); + this.val32 = input.readInt(); + } + } +} \ No newline at end of file diff --git a/libsrc/ttf/nbproject/build-impl.xml b/libsrc/ttf/nbproject/build-impl.xml index 41c1b513d..0e2c1d29f 100644 --- a/libsrc/ttf/nbproject/build-impl.xml +++ b/libsrc/ttf/nbproject/build-impl.xml @@ -1,1413 +1,1419 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must set src.dir - Must set test.src.dir - Must set build.dir - Must set dist.dir - Must set build.classes.dir - Must set dist.javadoc.dir - Must set build.test.classes.dir - Must set build.test.results.dir - Must set build.classes.excludes - Must set dist.jar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must set javac.includes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - No tests executed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must set JVM to use for profiling in profiler.info.jvm - Must set profiler agent JVM arguments in profiler.info.jvmargs.agent - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must select some files in the IDE or set javac.includes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - To run this application from the command line without Ant, try: - - java -jar "${dist.jar.resolved}" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must select one file in the IDE or set run.class - - - - Must select one file in the IDE or set run.class - - - - - - - - - - - - - - - - - - - - - - - Must select one file in the IDE or set debug.class - - - - - Must select one file in the IDE or set debug.class - - - - - Must set fix.includes - - - - - - - - - - This target only works when run from inside the NetBeans IDE. - - - - - - - - - Must select one file in the IDE or set profile.class - This target only works when run from inside the NetBeans IDE. - - - - - - - - - This target only works when run from inside the NetBeans IDE. - - - - - - - - - - - - - This target only works when run from inside the NetBeans IDE. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must select one file in the IDE or set run.class - - - - - - Must select some files in the IDE or set test.includes - - - - - Must select one file in the IDE or set run.class - - - - - Must select one file in the IDE or set applet.url - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Must select some files in the IDE or set javac.includes - - - - - - - - - - - - - - - - - - - - Some tests failed; see details above. - - - - - - - - - Must select some files in the IDE or set test.includes - - - - Some tests failed; see details above. - - - - Must select some files in the IDE or set test.class - Must select some method in the IDE or set test.method - - - - Some tests failed; see details above. - - - - - Must select one file in the IDE or set test.class - - - - Must select one file in the IDE or set test.class - Must select some method in the IDE or set test.method - - - - - - - - - - - - - - Must select one file in the IDE or set applet.url - - - - - - - - - Must select one file in the IDE or set applet.url - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + No tests executed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + Must select one file in the IDE or set profile.class + This target only works when run from inside the NetBeans IDE. + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + + + Must select some files in the IDE or set test.includes + + + + + Must select one file in the IDE or set run.class + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + Must select some files in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + Must select one file in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libsrc/ttf/nbproject/genfiles.properties b/libsrc/ttf/nbproject/genfiles.properties index 29b2c0e4d..32a75fe67 100644 --- a/libsrc/ttf/nbproject/genfiles.properties +++ b/libsrc/ttf/nbproject/genfiles.properties @@ -1,8 +1,8 @@ -build.xml.data.CRC32=ffc041f7 -build.xml.script.CRC32=9bce9219 -build.xml.stylesheet.CRC32=8064a381@1.68.1.46 -# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. -# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. -nbproject/build-impl.xml.data.CRC32=ffc041f7 -nbproject/build-impl.xml.script.CRC32=fdde8048 -nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.74.1.48 +build.xml.data.CRC32=ffc041f7 +build.xml.script.CRC32=9bce9219 +build.xml.stylesheet.CRC32=8064a381@1.68.1.46 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=ffc041f7 +nbproject/build-impl.xml.script.CRC32=c196f24b +nbproject/build-impl.xml.stylesheet.CRC32=05530350@1.79.1.48