From adf66538075417ba3a3ca24ce4cad019434e358c Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 14 Aug 2022 21:32:00 -0500 Subject: [PATCH] swf: Write a non-zero 'index' value for true/false/undefined/null default values A zero 'index' does not have a subsequent 'kind' field in the written SWF. The 'index' field is not actually used for true/false/undefined/null, so it can be anything as long as it's non-zero. --- swf/src/avm2/read.rs | 18 ++++++++++++++++++ swf/src/avm2/write.rs | 16 +++++++++------- swf/tests/swfs/Avm2DefaultValue.as | 8 ++++++++ swf/tests/swfs/Avm2DefaultValue.swf | Bin 0 -> 580 bytes 4 files changed, 35 insertions(+), 7 deletions(-) create mode 100644 swf/tests/swfs/Avm2DefaultValue.as create mode 100644 swf/tests/swfs/Avm2DefaultValue.swf 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 0000000000000000000000000000000000000000..67bd81344c18d43d5345f095dc2b2c5cc3eac8c7 GIT binary patch literal 580 zcmV-K0=xY~S5qc^0{{Sc+J#b0Z__{!owXf1UxHKxlpc^QA(0D-9akI@r51rGhzpen zMTkSl#$Ly!8{4wibvPmMPq^?mxNzYX{sO1|2&Ay`!4Uv_I=n;xgT(dvuSR2iwWML%=h;ciXDsd;MxN)L{J0Y(3!~fX^$gQ8EUV2K z?et^F@TwiA4_bC%Fe0gw1ThPuP!~C#M;SY5wYILVb8Q-D2`wyL#~_p}Nyt*8+v##6 z*Xesvvc$~BaZCdT3p-=gPW{L^&+!FmdlaYsz}ORoh6Rigdl+NKC;FI@l|J0d3-T31 zaNT{M_O>C9D>}GP7kw3qzj;CzXLA~)K1p_UCXvT-obZBC7P|XVd!mpz3BfG-uV_aT z5{kn`h8M&p;rp{maeWOH6JW-N%@%t1@gv