From ef9c073d26a122e80d7b4fc376d7a0421b9a82a4 Mon Sep 17 00:00:00 2001 From: relrelb Date: Fri, 9 Jul 2021 17:05:13 +0300 Subject: [PATCH] swf: General cleanup Just mechanical cleanups to ease future refactors. --- swf/README.md | 4 ++-- swf/src/avm1/read.rs | 13 +++++++++++- swf/src/avm1/write.rs | 46 ++++++++++++++++++++----------------------- swf/src/avm2/read.rs | 2 ++ swf/src/avm2/write.rs | 6 ++++-- swf/src/extensions.rs | 34 +++++--------------------------- swf/src/lib.rs | 9 +-------- swf/src/read.rs | 36 ++++++++++++++++----------------- swf/src/test_data.rs | 2 +- swf/src/types.rs | 2 +- swf/src/write.rs | 46 +++++++++++++++---------------------------- 11 files changed, 82 insertions(+), 118 deletions(-) diff --git a/swf/README.md b/swf/README.md index 980b4c415..365688054 100644 --- a/swf/README.md +++ b/swf/README.md @@ -18,7 +18,7 @@ use std::fs::File; let file = File::open("file.swf").unwrap(); let reader = BufReader::new(file); -let swf = swf::read_swf(reader).unwrap(); +let swf = swf::parse_swf(reader).unwrap(); println!("The SWF has {} frames", swf.header.num_frames); ``` @@ -64,4 +64,4 @@ at your option. Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any -additional terms or conditions. \ No newline at end of file +additional terms or conditions. diff --git a/swf/src/avm1/read.rs b/swf/src/avm1/read.rs index 467620ed3..62317960f 100644 --- a/swf/src/avm1/read.rs +++ b/swf/src/avm1/read.rs @@ -41,6 +41,18 @@ impl<'a> Reader<'a> { &mut self.input } + #[inline] + fn read_f64_me(&mut self) -> Result { + // Flash weirdly stores (some?) f64 as two LE 32-bit chunks. + // First word is the hi-word, second word is the lo-word. + let mut bytes = self.read_u64()?.to_le_bytes(); + bytes.swap(0, 4); + bytes.swap(1, 5); + bytes.swap(2, 6); + bytes.swap(3, 7); + Ok(f64::from_le_bytes(bytes)) + } + #[inline] pub fn read_action(&mut self) -> Result>> { let (opcode, mut length) = self.read_opcode_and_length()?; @@ -79,7 +91,6 @@ impl<'a> Reader<'a> { /// The `length` passed in should be the length excluding any sub-blocks. /// The final `length` returned will be total length of the action, including sub-blocks. #[inline] - #[allow(clippy::inconsistent_digit_grouping)] fn read_op(&mut self, opcode: u8, length: &mut usize) -> Result>> { use num_traits::FromPrimitive; let action = if let Some(op) = OpCode::from_u8(opcode) { diff --git a/swf/src/avm1/write.rs b/swf/src/avm1/write.rs index 9a63f0113..fe6232440 100644 --- a/swf/src/avm1/write.rs +++ b/swf/src/avm1/write.rs @@ -1,90 +1,86 @@ -#![allow(clippy::cognitive_complexity, clippy::unreadable_literal)] - use crate::avm1::opcode::OpCode; use crate::avm1::types::*; use crate::string::SwfStr; use crate::write::SwfWriteExt; use byteorder::{LittleEndian, WriteBytesExt}; -use std::io::{self, Result, Write}; +use std::io::{Result, Write}; -#[allow(dead_code)] pub struct Writer { output: W, + #[allow(dead_code)] version: u8, } impl SwfWriteExt for Writer { #[inline] - fn write_u8(&mut self, n: u8) -> io::Result<()> { + fn write_u8(&mut self, n: u8) -> Result<()> { self.output.write_u8(n) } #[inline] - fn write_u16(&mut self, n: u16) -> io::Result<()> { + fn write_u16(&mut self, n: u16) -> Result<()> { self.output.write_u16::(n) } #[inline] - fn write_u32(&mut self, n: u32) -> io::Result<()> { + fn write_u32(&mut self, n: u32) -> Result<()> { self.output.write_u32::(n) } #[inline] - fn write_u64(&mut self, n: u64) -> io::Result<()> { + fn write_u64(&mut self, n: u64) -> Result<()> { self.output.write_u64::(n) } #[inline] - fn write_i8(&mut self, n: i8) -> io::Result<()> { + fn write_i8(&mut self, n: i8) -> Result<()> { self.output.write_i8(n) } #[inline] - fn write_i16(&mut self, n: i16) -> io::Result<()> { + fn write_i16(&mut self, n: i16) -> Result<()> { self.output.write_i16::(n) } #[inline] - fn write_i32(&mut self, n: i32) -> io::Result<()> { + fn write_i32(&mut self, n: i32) -> Result<()> { self.output.write_i32::(n) } #[inline] - fn write_f32(&mut self, n: f32) -> io::Result<()> { + fn write_f32(&mut self, n: f32) -> Result<()> { self.output.write_f32::(n) } #[inline] - fn write_f64(&mut self, n: f64) -> io::Result<()> { + fn write_f64(&mut self, n: f64) -> Result<()> { self.output.write_f64::(n) } #[inline] - fn write_string(&mut self, s: &'_ SwfStr) -> io::Result<()> { + fn write_string(&mut self, s: &'_ SwfStr) -> Result<()> { self.output.write_all(s.as_bytes())?; self.write_u8(0) } } impl Writer { - pub fn new(output: W, version: u8) -> Writer { - Writer { output, version } + pub fn new(output: W, version: u8) -> Self { + Self { output, version } } #[inline] - fn write_f64_me(&mut self, n: f64) -> io::Result<()> { + fn write_f64_me(&mut self, n: f64) -> Result<()> { // Flash weirdly stores f64 as two LE 32-bit chunks. // First word is the hi-word, second word is the lo-word. - let mut num = [0u8; 8]; - (&mut num[..]).write_f64::(n)?; - num.swap(0, 4); - num.swap(1, 5); - num.swap(2, 6); - num.swap(3, 7); - self.output.write_all(&num) + let mut bytes = n.to_le_bytes(); + bytes.swap(0, 4); + bytes.swap(1, 5); + bytes.swap(2, 6); + bytes.swap(3, 7); + self.output.write_all(&bytes) } - #[allow(clippy::inconsistent_digit_grouping)] pub fn write_action(&mut self, action: &Action) -> Result<()> { match *action { Action::Add => self.write_action_header(OpCode::Add, 0)?, diff --git a/swf/src/avm2/read.rs b/swf/src/avm2/read.rs index f0a6b2ceb..118e57dbc 100644 --- a/swf/src/avm2/read.rs +++ b/swf/src/avm2/read.rs @@ -1,3 +1,5 @@ +#![allow(clippy::unusual_byte_groupings)] + use crate::avm2::types::*; use crate::error::{Error, Result}; use crate::extensions::ReadSwfExt; diff --git a/swf/src/avm2/write.rs b/swf/src/avm2/write.rs index 42a643195..3f29b6ae7 100644 --- a/swf/src/avm2/write.rs +++ b/swf/src/avm2/write.rs @@ -1,3 +1,5 @@ +#![allow(clippy::unusual_byte_groupings)] + use crate::avm2::opcode::OpCode; use crate::avm2::types::*; use crate::string::SwfStr; @@ -63,8 +65,8 @@ impl SwfWriteExt for Writer { } impl Writer { - pub fn new(output: W) -> Writer { - Writer { output } + pub fn new(output: W) -> Self { + Self { output } } pub fn write(&mut self, abc_file: AbcFile) -> Result<()> { diff --git a/swf/src/extensions.rs b/swf/src/extensions.rs index 9c18a33ad..17fba9496 100644 --- a/swf/src/extensions.rs +++ b/swf/src/extensions.rs @@ -1,8 +1,7 @@ -use crate::byteorder::{LittleEndian, ReadBytesExt}; use crate::error::Result; use crate::string::SwfStr; -use crate::{Fixed16, Fixed8}; -use std::io::{self, Read}; +use byteorder::{LittleEndian, ReadBytesExt}; +use std::io; pub trait ReadSwfExt<'a> { fn as_mut_slice(&mut self) -> &mut &'a [u8]; @@ -15,9 +14,9 @@ pub trait ReadSwfExt<'a> { // TODO: Make this fallible? fn seek(&mut self, data: &'a [u8], relative_offset: isize) { - let mut pos = self.pos(data); - pos = (pos as isize + relative_offset) as usize; - pos = pos.min(data.len()); + let pos = self.pos(data); + let pos = (pos as isize + relative_offset) as usize; + let pos = pos.min(data.len()); *self.as_mut_slice() = &data[pos..]; } @@ -66,16 +65,6 @@ pub trait ReadSwfExt<'a> { Ok(ReadBytesExt::read_f64::(self.as_mut_slice())?) } - #[inline] - fn read_fixed8(&mut self) -> Result { - Ok(Fixed8::from_bits(self.read_i16()?)) - } - - #[inline] - fn read_fixed16(&mut self) -> Result { - Ok(Fixed16::from_bits(self.read_i32()?)) - } - #[inline] fn read_encoded_u32(&mut self) -> Result { let mut val: u32 = 0; @@ -89,19 +78,6 @@ pub trait ReadSwfExt<'a> { Ok(val) } - #[inline] - fn read_f64_me(&mut self) -> Result { - // Flash weirdly stores (some?) f64 as two LE 32-bit chunks. - // First word is the hi-word, second word is the lo-word. - let mut num = [0u8; 8]; - self.as_mut_slice().read_exact(&mut num)?; - num.swap(0, 4); - num.swap(1, 5); - num.swap(2, 6); - num.swap(3, 7); - Ok(ReadBytesExt::read_f64::(&mut &num[..])?) - } - fn read_slice(&mut self, len: usize) -> Result<&'a [u8]> { let slice = self.as_mut_slice(); if slice.len() >= len { diff --git a/swf/src/lib.rs b/swf/src/lib.rs index 99c5e51c7..9ae6d4381 100644 --- a/swf/src/lib.rs +++ b/swf/src/lib.rs @@ -6,14 +6,7 @@ //! //! This library consists of a `read` module for decoding SWF data, and a `write` library for //! writing SWF data. -#![allow( - renamed_and_removed_lints, - clippy::unknown_clippy_lints, - clippy::unusual_byte_groupings, - clippy::upper_case_acronyms -)] -extern crate byteorder; #[cfg(feature = "flate2")] extern crate flate2; #[cfg(feature = "libflate")] @@ -36,7 +29,7 @@ pub mod write; #[cfg(test)] mod test_data; -/// Reexports +/// Re-exports pub use read::{decompress_swf, parse_swf}; pub use string::*; pub use tag_code::TagCode; diff --git a/swf/src/read.rs b/swf/src/read.rs index dcd219a2b..b68436a50 100644 --- a/swf/src/read.rs +++ b/swf/src/read.rs @@ -1,9 +1,4 @@ -#![allow( - renamed_and_removed_lints, - clippy::unknown_clippy_lints, - clippy::inconsistent_digit_grouping, - clippy::unreadable_literal -)] +#![allow(clippy::unusual_byte_groupings)] use crate::extensions::ReadSwfExt; use crate::{ @@ -16,7 +11,7 @@ use bitstream_io::BitRead; use byteorder::{LittleEndian, ReadBytesExt}; use std::io::{self, Read}; -/// Parse a decompressed SWF and return a `Vec` of tags. +/// Parse a decompressed SWF. /// /// # Example /// ``` @@ -220,16 +215,11 @@ fn make_lzma_reader<'a, R: Read + 'a>( )) } -pub struct BitReader<'a, 'b> { +struct BitReader<'a, 'b> { bits: bitstream_io::BitReader<&'b mut &'a [u8], bitstream_io::BigEndian>, } impl<'a, 'b> BitReader<'a, 'b> { - #[inline] - fn byte_align(&mut self) { - self.bits.byte_align(); - } - #[inline] fn read_bit(&mut self) -> io::Result { self.bits.read_bit() @@ -271,7 +261,7 @@ impl<'a, 'b> BitReader<'a, 'b> { #[inline] fn reader(&mut self) -> &mut &'a [u8] { - self.byte_align(); + self.bits.byte_align(); self.bits.reader().unwrap() } } @@ -295,8 +285,8 @@ impl<'a> ReadSwfExt<'a> for Reader<'a> { impl<'a> Reader<'a> { #[inline] - pub const fn new(input: &'a [u8], version: u8) -> Reader<'a> { - Reader { input, version } + pub const fn new(input: &'a [u8], version: u8) -> Self { + Self { input, version } } /// Returns the suggested string encoding for this SWF. @@ -333,6 +323,16 @@ impl<'a> Reader<'a> { } } + #[inline] + fn read_fixed8(&mut self) -> Result { + Ok(Fixed8::from_bits(self.read_i16()?)) + } + + #[inline] + fn read_fixed16(&mut self) -> Result { + Ok(Fixed16::from_bits(self.read_i32()?)) + } + /// Reads the next SWF tag from the stream. /// # Example /// ``` @@ -795,8 +795,7 @@ impl<'a> Reader<'a> { // to the characters in a button in sequence. // We don't know how many color transforms this tag will contain, so read it into a buffer. - let version = self.version; - let mut reader = Reader::new(self.read_slice(tag_length)?, version); + let mut reader = Reader::new(self.read_slice(tag_length)?, self.version); let id = reader.read_character_id()?; let mut color_transforms = Vec::new(); @@ -1819,7 +1818,6 @@ impl<'a> Reader<'a> { // but SWFs in the wild exist with them in DefineShape1 (generated by third party tools), // and these run correctly in the Flash Player. if (flags & 0b10000) != 0 { - bits.byte_align(); let mut reader = Reader::new(bits.reader(), context.swf_version); let (new_styles, num_fill_bits, num_line_bits) = reader.read_shape_styles(context.shape_version)?; diff --git a/swf/src/test_data.rs b/swf/src/test_data.rs index 8cdc67511..9f67ba1e1 100644 --- a/swf/src/test_data.rs +++ b/swf/src/test_data.rs @@ -1,4 +1,4 @@ -#![allow(clippy::inconsistent_digit_grouping, clippy::unreadable_literal)] +#![allow(clippy::unusual_byte_groupings)] use crate::avm1::types::*; use crate::avm2::read::tests::read_abc_from_file; diff --git a/swf/src/types.rs b/swf/src/types.rs index f3d2829a9..ce3f258aa 100644 --- a/swf/src/types.rs +++ b/swf/src/types.rs @@ -13,7 +13,7 @@ pub use fixed::*; pub use matrix::Matrix; /// A complete header and tags in the SWF file. -/// This is returned by the `swf::read_swf` convenience method. +/// This is returned by the `swf::parse_swf` convenience method. #[derive(Debug)] pub struct Swf<'a> { pub header: HeaderExt, diff --git a/swf/src/write.rs b/swf/src/write.rs index d15240370..7a99694ce 100644 --- a/swf/src/write.rs +++ b/swf/src/write.rs @@ -1,9 +1,4 @@ -#![allow( - clippy::cognitive_complexity, - clippy::float_cmp, - clippy::inconsistent_digit_grouping, - clippy::unreadable_literal -)] +#![allow(clippy::unusual_byte_groupings)] use crate::{ error::{Error, Result}, @@ -22,16 +17,16 @@ use std::io::{self, Write}; /// use swf::*; /// /// let header = Header { -/// compression: Compression::Zlib, -/// version: 6, -/// stage_size: Rectangle { x_min: Twips::from_pixels(0.0), x_max: Twips::from_pixels(400.0), y_min: Twips::from_pixels(0.0), y_max: Twips::from_pixels(400.0) }, -/// frame_rate: Fixed8::from_f32(60.0), -/// num_frames: 1, -/// }; +/// compression: Compression::Zlib, +/// version: 6, +/// stage_size: Rectangle { x_min: Twips::from_pixels(0.0), x_max: Twips::from_pixels(400.0), y_min: Twips::from_pixels(0.0), y_max: Twips::from_pixels(400.0) }, +/// frame_rate: Fixed8::from_f32(60.0), +/// num_frames: 1, +/// }; /// let tags = [ -/// Tag::SetBackgroundColor(Color { r: 255, g: 0, b: 0, a: 255 }), -/// Tag::ShowFrame -/// ]; +/// Tag::SetBackgroundColor(Color { r: 255, g: 0, b: 0, a: 255 }), +/// Tag::ShowFrame, +/// ]; /// let output = Vec::new(); /// swf::write_swf(&header, &tags, output).unwrap(); /// ``` @@ -63,22 +58,16 @@ pub fn write_swf(header: &Header, tags: &[Tag<'_>], mut output: W) -> // Compress SWF body. match header.compression { - Compression::None => { - output.write_all(&swf_body)?; - } + Compression::None => output.write_all(&swf_body)?, Compression::Zlib => write_zlib_swf(&mut output, &swf_body)?, - // LZMA header. - // SWF format has a mangled LZMA header, so we have to do some magic to convert the - // standard LZMA header to SWF format. - // https://adobe.ly/2s8oYzn Compression::Lzma => { write_lzma_swf(&mut output, &swf_body)?; // 5 bytes of garbage data? //output.write_all(&[0xFF, 0xB5, 0xE6, 0xF8, 0xCB])?; } - }; + } Ok(()) } @@ -265,13 +254,8 @@ impl SwfWriteExt for Writer { } impl Writer { - fn new(output: W, version: u8) -> Writer { - Writer { output, version } - } - - #[allow(dead_code)] - fn into_inner(self) -> W { - self.output + fn new(output: W, version: u8) -> Self { + Self { output, version } } #[inline] @@ -281,10 +265,12 @@ impl Writer { } } + #[inline] fn write_fixed8(&mut self, n: Fixed8) -> io::Result<()> { self.write_i16(n.get()) } + #[inline] fn write_fixed16(&mut self, n: Fixed16) -> io::Result<()> { self.write_i32(n.get()) }