refactor: make LZMA support an optional feature
This commit is contained in:
parent
120f94711a
commit
5a0e7a8fd3
|
@ -14,7 +14,8 @@ byteorder = "1.0"
|
|||
flate2 = "1.0"
|
||||
num-derive = "0.2"
|
||||
num-traits = "0.2"
|
||||
xz2 = "0.1.5"
|
||||
xz2 = {version = "0.1.5", optional = true}
|
||||
|
||||
[features]
|
||||
default = []
|
||||
default = []
|
||||
lzma-support = ["xz2"]
|
|
@ -14,6 +14,7 @@ extern crate flate2;
|
|||
#[macro_use]
|
||||
extern crate num_derive;
|
||||
extern crate num_traits;
|
||||
#[cfg(feature = "lzma-support")]
|
||||
extern crate xz2;
|
||||
|
||||
pub mod avm1;
|
||||
|
|
53
src/read.rs
53
src/read.rs
|
@ -5,7 +5,6 @@ use flate2::read::ZlibDecoder;
|
|||
use std::collections::HashSet;
|
||||
use std::io::{Error, ErrorKind, Read, Result};
|
||||
use types::*;
|
||||
use xz2::read::XzDecoder;
|
||||
|
||||
/// Reads SWF data from a stream.
|
||||
pub fn read_swf<R: Read>(input: R) -> Result<Swf> {
|
||||
|
@ -24,22 +23,7 @@ fn read_swf_header<'a, R: Read + 'a>(mut input: R) -> Result<(Swf, Reader<Box<Re
|
|||
let decompressed_input: Box<Read> = match compression {
|
||||
Compression::None => Box::new(input),
|
||||
Compression::Zlib => Box::new(ZlibDecoder::new(input)),
|
||||
Compression::Lzma => {
|
||||
// Flash uses a mangled LZMA header, so we have to massage it into the normal
|
||||
// format.
|
||||
use std::io::{Cursor, Write};
|
||||
use xz2::stream::{Action, Stream};
|
||||
use byteorder::WriteBytesExt;
|
||||
input.read_u32::<LittleEndian>()?; // Compressed length
|
||||
let mut lzma_properties = [0u8; 5];
|
||||
input.read_exact(&mut lzma_properties)?;
|
||||
let mut lzma_header = Cursor::new(Vec::with_capacity(13));
|
||||
lzma_header.write_all(&lzma_properties)?;
|
||||
lzma_header.write_u64::<LittleEndian>(uncompressed_length as u64)?;
|
||||
let mut lzma_stream = Stream::new_lzma_decoder(u64::max_value())?;
|
||||
lzma_stream.process(&lzma_header.into_inner(), &mut [0u8; 1], Action::Run)?;
|
||||
Box::new(XzDecoder::new_stream(input, lzma_stream))
|
||||
}
|
||||
Compression::Lzma => make_lzma_reader(input)?,
|
||||
};
|
||||
|
||||
let mut reader = Reader::new(decompressed_input, version);
|
||||
|
@ -57,6 +41,29 @@ fn read_swf_header<'a, R: Read + 'a>(mut input: R) -> Result<(Swf, Reader<Box<Re
|
|||
Ok((swf, reader))
|
||||
}
|
||||
|
||||
#[cfg(feature = "lzma-support")]
|
||||
fn make_lzma_reader<'a, R: Read + 'a>(mut input: R) -> Result<Box<Read + 'a>> {
|
||||
// Flash uses a mangled LZMA header, so we have to massage it into the normal
|
||||
// format.
|
||||
use std::io::{Cursor, Write};
|
||||
use xz2::stream::{Action, Stream};
|
||||
use byteorder::WriteBytesExt;
|
||||
input.read_u32::<LittleEndian>()?; // Compressed length
|
||||
let mut lzma_properties = [0u8; 5];
|
||||
input.read_exact(&mut lzma_properties)?;
|
||||
let mut lzma_header = Cursor::new(Vec::with_capacity(13));
|
||||
lzma_header.write_all(&lzma_properties)?;
|
||||
lzma_header.write_u64::<LittleEndian>(uncompressed_length as u64)?;
|
||||
let mut lzma_stream = Stream::new_lzma_decoder(u64::max_value())?;
|
||||
lzma_stream.process(&lzma_header.into_inner(), &mut [0u8; 1], Action::Run)?;
|
||||
Box::new(XzDecoder::new_stream(input, lzma_stream))
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "lzma-support"))]
|
||||
fn make_lzma_reader<'a, R: Read + 'a>(_: R) -> Result<Box<Read + 'a>> {
|
||||
Err(Error::new(ErrorKind::InvalidData, "Support for LZMA compressed SWFs is not enabled."))
|
||||
}
|
||||
|
||||
pub trait SwfRead<R: Read> {
|
||||
fn get_inner(&mut self) -> &mut R;
|
||||
|
||||
|
@ -409,7 +416,7 @@ impl<R: Read> Reader<R> {
|
|||
|
||||
fn read_tag(&mut self) -> Result<Option<Tag>> {
|
||||
use num_traits::FromPrimitive;
|
||||
|
||||
|
||||
let (tag_code, length) = self.read_tag_code_and_length()?;
|
||||
|
||||
let mut tag_reader = Reader::new(self.input.by_ref().take(length as u64), self.version);
|
||||
|
@ -2669,10 +2676,12 @@ pub mod tests {
|
|||
read_from_file("tests/swfs/zlib.swf").compression,
|
||||
Compression::Zlib
|
||||
);
|
||||
assert_eq!(
|
||||
read_from_file("tests/swfs/lzma.swf").compression,
|
||||
Compression::Lzma
|
||||
);
|
||||
if cfg!(feature = "lzma-support") {
|
||||
assert_eq!(
|
||||
read_from_file("tests/swfs/lzma.swf").compression,
|
||||
Compression::Lzma
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
43
src/write.rs
43
src/write.rs
|
@ -9,7 +9,6 @@ use std::collections::HashSet;
|
|||
use std::io::{Error, ErrorKind, Result, Write};
|
||||
use tag_codes::TagCode;
|
||||
use types::*;
|
||||
use xz2::write::XzEncoder;
|
||||
|
||||
pub fn write_swf<W: Write>(swf: &Swf, mut output: W) -> Result<()> {
|
||||
let signature = match swf.compression {
|
||||
|
@ -52,22 +51,32 @@ pub fn write_swf<W: Write>(swf: &Swf, mut output: W) -> Result<()> {
|
|||
// SWF format has a mangled LZMA header, so we have to do some magic to conver the
|
||||
// standard LZMA header to SWF format.
|
||||
// https://adobe.ly/2s8oYzn
|
||||
Compression::Lzma => {
|
||||
use xz2::stream::{Action, LzmaOptions, Stream};
|
||||
let mut stream = Stream::new_lzma_encoder(&LzmaOptions::new_preset(9)?)?;
|
||||
let mut lzma_header = [0; 13];
|
||||
stream.process(&[], &mut lzma_header, Action::Run)?;
|
||||
// Compressed length. We just write out a dummy value.
|
||||
output.write_u32::<LittleEndian>(0xffffffff)?;
|
||||
output.write_all(&lzma_header[0..5])?; // LZMA property bytes.
|
||||
let mut encoder = XzEncoder::new_stream(&mut output, stream);
|
||||
encoder.write_all(&swf_body)?;
|
||||
}
|
||||
Compression::Lzma => write_lzma_swf(&mut output)?,
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "lzma-support")]
|
||||
fn write_lzma_swf<W: Write>(mut output: W) -> Result<()> {
|
||||
use xz2::write::XzEncoder;
|
||||
use xz2::stream::{Action, LzmaOptions, Stream};
|
||||
let mut stream = Stream::new_lzma_encoder(&LzmaOptions::new_preset(9)?)?;
|
||||
let mut lzma_header = [0; 13];
|
||||
stream.process(&[], &mut lzma_header, Action::Run)?;
|
||||
// Compressed length. We just write out a dummy value.
|
||||
output.write_u32::<LittleEndian>(0xffffffff)?;
|
||||
output.write_all(&lzma_header[0..5])?; // LZMA property bytes.
|
||||
let mut encoder = XzEncoder::new_stream(&mut output, stream);
|
||||
encoder.write_all(&swf_body)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "lzma-support"))]
|
||||
fn write_lzma_swf<W: Write>(_: W) -> Result<()> {
|
||||
Err(Error::new(ErrorKind::InvalidData, "Support for LZMA compressed SWFs is not enabled."))
|
||||
}
|
||||
|
||||
pub trait SwfWrite<W: Write> {
|
||||
fn get_inner(&mut self) -> &mut W;
|
||||
|
||||
|
@ -2691,10 +2700,12 @@ mod tests {
|
|||
write_dummy_swf(Compression::Zlib).is_ok(),
|
||||
"Failed to write zlib SWF."
|
||||
);
|
||||
assert!(
|
||||
write_dummy_swf(Compression::Lzma).is_ok(),
|
||||
"Failed to write LZMA SWF."
|
||||
);
|
||||
if cfg!(feature = "lzma-support") {
|
||||
assert!(
|
||||
write_dummy_swf(Compression::Lzma).is_ok(),
|
||||
"Failed to write LZMA SWF."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Reference in New Issue