swf: Support SWZ files
This commit is contained in:
parent
10c19fef57
commit
5c9bf3ffc0
|
@ -2443,6 +2443,17 @@ dependencies = [
|
||||||
"minimal-lexical",
|
"minimal-lexical",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-bigint"
|
||||||
|
version = "0.2.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"num-integer",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-complex"
|
name = "num-complex"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
|
@ -3507,6 +3518,17 @@ version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
|
checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "simple_asn1"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "692ca13de57ce0613a363c8c2f1de925adebc81b04c923ac60c5488bb44abe4b"
|
||||||
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
|
"num-bigint",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.7"
|
version = "0.4.7"
|
||||||
|
@ -3640,6 +3662,7 @@ dependencies = [
|
||||||
"lzma-rs",
|
"lzma-rs",
|
||||||
"num-derive",
|
"num-derive",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
|
"simple_asn1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -32,7 +32,7 @@ use ruffle_render::utils::{determine_jpeg_tag_format, JpegTagFormat};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::sync::{Arc, Mutex, Weak};
|
use std::sync::{Arc, Mutex, Weak};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use swf::read::read_compression_type;
|
use swf::read::{extract_swz, read_compression_type};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use url::form_urlencoded;
|
use url::form_urlencoded;
|
||||||
|
|
||||||
|
@ -1270,6 +1270,11 @@ impl<'gc> Loader<'gc> {
|
||||||
let sniffed_type = ContentType::sniff(data);
|
let sniffed_type = ContentType::sniff(data);
|
||||||
let mut length = data.len();
|
let mut length = data.len();
|
||||||
|
|
||||||
|
if sniffed_type == ContentType::Unknown {
|
||||||
|
if let Ok(data) = extract_swz(data) {
|
||||||
|
return Self::movie_loader_data(handle, player, &data, url, loader_url, in_memory);
|
||||||
|
}
|
||||||
|
}
|
||||||
player.lock().unwrap().update(|uc| {
|
player.lock().unwrap().update(|uc| {
|
||||||
let (clip, event_handler) = match uc.load_manager.get_loader(handle) {
|
let (clip, event_handler) = match uc.load_manager.get_loader(handle) {
|
||||||
Some(Loader::Movie {
|
Some(Loader::Movie {
|
||||||
|
|
|
@ -21,6 +21,7 @@ log = "0.4"
|
||||||
flate2 = {version = "1.0", optional = true}
|
flate2 = {version = "1.0", optional = true}
|
||||||
lzma-rs = {version = "0.2.0", optional = true }
|
lzma-rs = {version = "0.2.0", optional = true }
|
||||||
enum-map = "2.4.0"
|
enum-map = "2.4.0"
|
||||||
|
simple_asn1 = "0.4.1"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["flate2", "lzma"]
|
default = ["flate2", "lzma"]
|
||||||
|
|
|
@ -7,6 +7,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
use bitstream_io::BitRead;
|
use bitstream_io::BitRead;
|
||||||
use byteorder::{LittleEndian, ReadBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt};
|
||||||
|
use simple_asn1::ASN1Block;
|
||||||
use std::io::{self, Read};
|
use std::io::{self, Read};
|
||||||
|
|
||||||
/// Parse a decompressed SWF.
|
/// Parse a decompressed SWF.
|
||||||
|
@ -28,6 +29,28 @@ pub fn parse_swf(swf_buf: &SwfBuf) -> Result<Swf<'_>> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Extracts an SWF inside of an SWZ file.
|
||||||
|
pub fn extract_swz(input: &[u8]) -> Result<Vec<u8>> {
|
||||||
|
let asn1_blocks =
|
||||||
|
simple_asn1::from_der(input).map_err(|_| Error::invalid_data("Invalid ASN1 blob"))?;
|
||||||
|
if let Some(ASN1Block::Sequence(_, s)) = asn1_blocks.into_iter().nth(0) {
|
||||||
|
for t in s {
|
||||||
|
if let ASN1Block::Explicit(_, _, _, block) = t {
|
||||||
|
if let ASN1Block::Sequence(_, s) = *block {
|
||||||
|
if let Some(ASN1Block::Sequence(_, s)) = s.into_iter().nth(2) {
|
||||||
|
if let Some(ASN1Block::Explicit(_, _, _, octet)) = s.into_iter().nth(1) {
|
||||||
|
if let ASN1Block::OctetString(_, bytes) = *octet {
|
||||||
|
return Ok(bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(Error::invalid_data("Invalid ASN1 blob"))
|
||||||
|
}
|
||||||
|
|
||||||
/// Parses an SWF header and returns a `Reader` that can be used
|
/// Parses an SWF header and returns a `Reader` that can be used
|
||||||
/// to read the SWF tags inside the SWF file.
|
/// to read the SWF tags inside the SWF file.
|
||||||
///
|
///
|
||||||
|
|
Loading…
Reference in New Issue