diff --git a/swf/src/avm2/read.rs b/swf/src/avm2/read.rs index 441819966..ac66a84cb 100644 --- a/swf/src/avm2/read.rs +++ b/swf/src/avm2/read.rs @@ -904,6 +904,24 @@ pub mod tests { } } + #[test] + fn test_round_trip_default_value() { + use crate::avm2::write::Writer; + + let orig_bytes = read_abc_from_file("tests/swfs/Avm2DefaultValue.swf"); + let mut reader = Reader::new(&orig_bytes[..]); + let parsed = reader.read().unwrap(); + + let mut out = vec![]; + let mut writer = Writer::new(&mut out); + writer.write(parsed).unwrap(); + + assert_eq!( + orig_bytes, out, + "Incorrectly written Avm2DefaultValue class" + ); + } + #[test] fn read_u30() { let read = |data: &[u8]| Reader::new(data).read_u30().unwrap(); diff --git a/swf/src/avm2/write.rs b/swf/src/avm2/write.rs index e4e82fb3d..225c23c4f 100644 --- a/swf/src/avm2/write.rs +++ b/swf/src/avm2/write.rs @@ -373,9 +373,9 @@ impl Writer { DefaultValue::Private(ref i) => (i.as_u30(), 0x05), DefaultValue::Double(ref i) => (i.as_u30(), 0x06), DefaultValue::Namespace(ref i) => (i.as_u30(), 0x08), - DefaultValue::False => (0, 0x0a), - DefaultValue::True => (0, 0x0b), - DefaultValue::Null => (0, 0x0c), + DefaultValue::False => (0x0a, 0x0a), + DefaultValue::True => (0x0b, 0x0b), + DefaultValue::Null => (0x0c, 0x0c), DefaultValue::Package(ref i) => (i.as_u30(), 0x16), DefaultValue::PackageInternal(ref i) => (i.as_u30(), 0x17), DefaultValue::Protected(ref i) => (i.as_u30(), 0x18), @@ -392,16 +392,18 @@ impl Writer { None => self.write_u30(0)?, Some(ref value) => { let (index, kind) = match *value { - DefaultValue::Undefined => (0, 0x00), + // Just write out a non-zero 'index' field - it's unused, + // so it doesn't matter what it is. + DefaultValue::Undefined => (0x01, 0x00), DefaultValue::String(ref i) => (i.as_u30(), 0x01), DefaultValue::Int(ref i) => (i.as_u30(), 0x03), DefaultValue::Uint(ref i) => (i.as_u30(), 0x04), DefaultValue::Private(ref i) => (i.as_u30(), 0x05), DefaultValue::Double(ref i) => (i.as_u30(), 0x06), DefaultValue::Namespace(ref i) => (i.as_u30(), 0x08), - DefaultValue::False => (0, 0x0a), - DefaultValue::True => (0, 0x0b), - DefaultValue::Null => (0, 0x0c), + DefaultValue::False => (0x0a, 0x0a), + DefaultValue::True => (0x0b, 0x0b), + DefaultValue::Null => (0x0c, 0x0c), DefaultValue::Package(ref i) => (i.as_u30(), 0x16), DefaultValue::PackageInternal(ref i) => (i.as_u30(), 0x17), DefaultValue::Protected(ref i) => (i.as_u30(), 0x18), diff --git a/swf/tests/swfs/Avm2DefaultValue.as b/swf/tests/swfs/Avm2DefaultValue.as new file mode 100644 index 000000000..f413bb8d5 --- /dev/null +++ b/swf/tests/swfs/Avm2DefaultValue.as @@ -0,0 +1,8 @@ +package { + public class Avm2DefaultValue { + public static var defaultTrue:Boolean = true; + public static var defaultFalse:Boolean = false; + public static var defaultNull:String = null; + public static var defaultUndefined:* = undefined; + } +} diff --git a/swf/tests/swfs/Avm2DefaultValue.swf b/swf/tests/swfs/Avm2DefaultValue.swf new file mode 100644 index 000000000..67bd81344 Binary files /dev/null and b/swf/tests/swfs/Avm2DefaultValue.swf differ