core: Report unexpected content type errors better.

This commit is contained in:
David Wendt 2022-03-27 15:58:33 -04:00 committed by Mike Welsh
parent 27697c6611
commit ac7bb84e08
1 changed files with 32 additions and 7 deletions

View File

@ -16,6 +16,7 @@ use crate::vminterface::Instantiator;
use encoding_rs::UTF_8; use encoding_rs::UTF_8;
use gc_arena::{Collect, CollectionContext}; use gc_arena::{Collect, CollectionContext};
use generational_arena::{Arena, Index}; use generational_arena::{Arena, Index};
use std::fmt;
use std::sync::{Arc, Mutex, Weak}; use std::sync::{Arc, Mutex, Weak};
use swf::read::read_compression_type; use swf::read::read_compression_type;
use thiserror::Error; use thiserror::Error;
@ -26,7 +27,7 @@ pub type Handle = Index;
/// Enumeration of all content types that `Loader` can handle. /// Enumeration of all content types that `Loader` can handle.
/// ///
/// This is a superset of `JpegTagFormat`. /// This is a superset of `JpegTagFormat`.
#[derive(PartialEq)] #[derive(PartialEq, Debug)]
pub enum ContentType { pub enum ContentType {
Swf, Swf,
Jpeg, Jpeg,
@ -46,6 +47,18 @@ impl From<JpegTagFormat> for ContentType {
} }
} }
impl fmt::Display for ContentType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Swf => write!(f, "SWF"),
Self::Jpeg => write!(f, "JPEG"),
Self::Png => write!(f, "PNG"),
Self::Gif => write!(f, "GIF"),
Self::Unknown => write!(f, "Unknown"),
}
}
}
impl ContentType { impl ContentType {
fn sniff(data: &[u8]) -> ContentType { fn sniff(data: &[u8]) -> ContentType {
if read_compression_type(data).is_ok() { if read_compression_type(data).is_ok() {
@ -54,6 +67,15 @@ impl ContentType {
determine_jpeg_tag_format(data).into() determine_jpeg_tag_format(data).into()
} }
} }
/// Assert that content is of a given type, and error otherwise.
fn expect(self, expected: Self) -> Result<Self, Error> {
if self == expected {
Ok(self)
} else {
Err(Error::UnexpectedData(expected, self))
}
}
} }
#[derive(Error, Debug)] #[derive(Error, Debug)]
@ -79,8 +101,11 @@ pub enum Error {
#[error("Invalid SWF")] #[error("Invalid SWF")]
InvalidSwf(#[from] crate::tag_utils::Error), InvalidSwf(#[from] crate::tag_utils::Error),
#[error("Invalid data")] #[error("Unexpected content of type {1}, expected {0}")]
InvalidData, UnexpectedData(ContentType, ContentType),
#[error("Unknown or corrupted data")]
UnknownData,
// TODO: We can't support lifetimes on this error object yet (or we'll need some backends inside // TODO: We can't support lifetimes on this error object yet (or we'll need some backends inside
// the GC arena). We're losing info here. How do we fix that? // the GC arena). We're losing info here. How do we fix that?
@ -432,9 +457,9 @@ impl<'gc> Loader<'gc> {
let sniffed_type = ContentType::sniff(&data); let sniffed_type = ContentType::sniff(&data);
let length = data.len(); let length = data.len();
//TODO: Does replacing the root movie with an image require any if replacing_root_movie {
//special work? sniffed_type.expect(ContentType::Swf)?;
if replacing_root_movie && sniffed_type == ContentType::Swf {
let movie = let movie =
SwfMovie::from_data(&data, Some(url.into_owned()), loader_url.clone())?; SwfMovie::from_data(&data, Some(url.into_owned()), loader_url.clone())?;
let movie = Arc::new(movie); let movie = Arc::new(movie);
@ -528,7 +553,7 @@ impl<'gc> Loader<'gc> {
mc.replace_at_depth(uc, bitmap_obj.into(), 1); mc.replace_at_depth(uc, bitmap_obj.into(), 1);
} }
} }
ContentType::Unknown => return Err(Error::InvalidData), ContentType::Unknown => return Err(Error::UnknownData),
} }
if let Some(broadcaster) = broadcaster { if let Some(broadcaster) = broadcaster {