core: Replaced tag_utils Error with an actual Error enum

This commit is contained in:
= 2022-08-20 22:36:51 +02:00 committed by Nathan Adams
parent 67eb34fbc5
commit 620820be9e
4 changed files with 80 additions and 48 deletions

View File

@ -267,7 +267,7 @@ impl<'gc> Avm2<'gc> {
domain: Domain<'gc>, domain: Domain<'gc>,
reader: &mut SwfStream<'_>, reader: &mut SwfStream<'_>,
tag_len: usize, tag_len: usize,
) -> Result<(), Error> { ) -> Result<(), crate::tag_utils::Error> {
let start = reader.as_slice(); let start = reader.as_slice();
// Queue the actions. // Queue the actions.
// TODO: The tag reader parses the entire ABC file, instead of just // TODO: The tag reader parses the entire ABC file, instead of just
@ -282,7 +282,8 @@ impl<'gc> Avm2<'gc> {
let slice = swf.resize_to_reader(reader, tag_len - num_read); let slice = swf.resize_to_reader(reader, tag_len - num_read);
if !slice.is_empty() { if !slice.is_empty() {
Avm2::load_abc(slice, &name, is_lazy_initialize, context, domain)?; Avm2::load_abc(slice, &name, is_lazy_initialize, context, domain)
.map_err(|e| crate::tag_utils::Error::InvalidABC(e.to_string()))?;
} }
Ok(()) Ok(())

View File

@ -34,7 +34,7 @@ use crate::events::{ButtonKeyCode, ClipEvent, ClipEventResult};
use crate::font::Font; use crate::font::Font;
use crate::prelude::*; use crate::prelude::*;
use crate::string::{AvmString, WStr, WString}; use crate::string::{AvmString, WStr, WString};
use crate::tag_utils::{self, DecodeResult, SwfMovie, SwfSlice, SwfStream}; use crate::tag_utils::{self, DecodeResult, Error, SwfMovie, SwfSlice, SwfStream};
use crate::vminterface::{AvmObject, Instantiator}; use crate::vminterface::{AvmObject, Instantiator};
use gc_arena::{Collect, Gc, GcCell, MutationContext}; use gc_arena::{Collect, Gc, GcCell, MutationContext};
use smallvec::SmallVec; use smallvec::SmallVec;
@ -589,9 +589,7 @@ impl<'gc> MovieClip<'gc> {
context: &mut UpdateContext<'_, 'gc, '_>, context: &mut UpdateContext<'_, 'gc, '_>,
reader: &mut SwfStream<'_>, reader: &mut SwfStream<'_>,
) -> DecodeResult { ) -> DecodeResult {
let movie = self let movie = self.movie().ok_or(Error::NoSymbolClasses)?;
.movie()
.ok_or("Attempted to set symbol classes on movie without any")?;
let mut activation = Avm2Activation::from_nothing(context.reborrow()); let mut activation = Avm2Activation::from_nothing(context.reborrow());
let num_symbols = reader.read_u16()?; let num_symbols = reader.read_u16()?;
@ -2633,11 +2631,7 @@ impl<'gc, 'a> MovieClipData<'gc> {
Ok(()) Ok(())
} }
_ => Err(format!( _ => Err(Error::PreloadVideoIntoInvalidCharacter(vframe.stream_id)),
"Attempted to preload video frames into non-video character {}",
vframe.stream_id
)
.into()),
} }
} }

View File

@ -134,6 +134,11 @@ pub enum Error {
// 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?
#[error("Error running avm1 script: {0}")] #[error("Error running avm1 script: {0}")]
Avm1Error(String), Avm1Error(String),
// 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?
#[error("Error running avm2 script: {0}")]
Avm2Error(String),
} }
impl From<crate::avm1::error::Error<'_>> for Error { impl From<crate::avm1::error::Error<'_>> for Error {
@ -579,10 +584,8 @@ impl<'gc> Loader<'gc> {
event_handler event_handler
{ {
let mut loader = loader_info let mut loader = loader_info
.get_property( .get_property(&Multiname::public("loader"), &mut activation)
&Multiname::public("loader"), .map_err(|e| Error::Avm2Error(e.to_string()))?
&mut activation,
)?
.as_object() .as_object()
.unwrap() .unwrap()
.as_display_object() .as_display_object()
@ -879,16 +882,18 @@ impl<'gc> Loader<'gc> {
// FIXME - Match the exact error message generated by Flash // FIXME - Match the exact error message generated by Flash
let io_error_evt_cls = activation.avm2().classes().ioerrorevent; let io_error_evt_cls = activation.avm2().classes().ioerrorevent;
let io_error_evt = io_error_evt_cls.construct( let io_error_evt = io_error_evt_cls
&mut activation, .construct(
&[ &mut activation,
"ioError".into(), &[
false.into(), "ioError".into(),
false.into(), false.into(),
"Error #2032: Stream Error".into(), false.into(),
2032.into(), "Error #2032: Stream Error".into(),
], 2032.into(),
)?; ],
)
.map_err(|e| Error::Avm2Error(e.to_string()))?;
if let Err(e) = Avm2::dispatch_event(uc, io_error_evt, target) { if let Err(e) = Avm2::dispatch_event(uc, io_error_evt, target) {
log::error!( log::error!(
@ -990,16 +995,21 @@ impl<'gc> Loader<'gc> {
Some(MovieLoaderEventHandler::Avm2LoaderInfo(loader_info)) => { Some(MovieLoaderEventHandler::Avm2LoaderInfo(loader_info)) => {
let mut activation = Avm2Activation::from_nothing(uc.reborrow()); let mut activation = Avm2Activation::from_nothing(uc.reborrow());
let progress_evt = activation.avm2().classes().progressevent.construct( let progress_evt = activation
&mut activation, .avm2()
&[ .classes()
"progress".into(), .progressevent
false.into(), .construct(
false.into(), &mut activation,
cur_len.into(), &[
total_len.into(), "progress".into(),
], false.into(),
)?; false.into(),
cur_len.into(),
total_len.into(),
],
)
.map_err(|e| Error::Avm2Error(e.to_string()))?;
if let Err(e) = Avm2::dispatch_event(uc, progress_evt, loader_info) { if let Err(e) = Avm2::dispatch_event(uc, progress_evt, loader_info) {
log::error!( log::error!(
@ -1101,16 +1111,18 @@ impl<'gc> Loader<'gc> {
// FIXME - Match the exact error message generated by Flash // FIXME - Match the exact error message generated by Flash
let io_error_evt_cls = activation.avm2().classes().ioerrorevent; let io_error_evt_cls = activation.avm2().classes().ioerrorevent;
let io_error_evt = io_error_evt_cls.construct( let io_error_evt = io_error_evt_cls
&mut activation, .construct(
&[ &mut activation,
"ioError".into(), &[
false.into(), "ioError".into(),
false.into(), false.into(),
"Movie loader error".into(), false.into(),
0.into(), "Movie loader error".into(),
], 0.into(),
)?; ],
)
.map_err(|e| Error::Avm2Error(e.to_string()))?;
if let Err(e) = Avm2::dispatch_event(uc, io_error_evt, loader_info) { if let Err(e) = Avm2::dispatch_event(uc, io_error_evt, loader_info) {
log::error!( log::error!(

View File

@ -1,8 +1,33 @@
use gc_arena::Collect; use gc_arena::Collect;
use std::sync::Arc; use std::sync::Arc;
use swf::{Fixed8, HeaderExt, Rectangle, TagCode, Twips}; use swf::{CharacterId, Fixed8, HeaderExt, Rectangle, TagCode, Twips};
use thiserror::Error;
#[derive(Error, Debug)]
pub enum Error {
#[error("Couldn't read SWF")]
InvalidSwf(#[from] swf::error::Error),
#[error("Couldn't register bitmap")]
InvalidBitmap(#[from] ruffle_render::error::Error),
#[error("Attempted to set symbol classes on movie without any")]
NoSymbolClasses,
#[error("Attempted to preload video frames into non-video character {0}")]
PreloadVideoIntoInvalidCharacter(CharacterId),
#[error("IO Error")]
IOError(#[from] std::io::Error),
#[error("Invalid SWF url")]
InvalidSwfUrl,
// TODO: Replace avm2 errors with something more substantial
#[error("Invalid ABC: {0}")]
InvalidABC(String),
}
pub type Error = Box<dyn std::error::Error>;
pub type DecodeResult = Result<(), Error>; pub type DecodeResult = Result<(), Error>;
pub type SwfStream<'a> = swf::read::Reader<'a>; pub type SwfStream<'a> = swf::read::Reader<'a>;
@ -57,7 +82,7 @@ impl SwfMovie {
let data = std::fs::read(&path)?; let data = std::fs::read(&path)?;
let abs_path = path.as_ref().canonicalize()?; let abs_path = path.as_ref().canonicalize()?;
let url = url::Url::from_file_path(abs_path).map_err(|()| "Invalid SWF URL")?; let url = url::Url::from_file_path(abs_path).map_err(|()| Error::InvalidSwfUrl)?;
Self::from_data(&data, Some(url.into()), loader_url) Self::from_data(&data, Some(url.into()), loader_url)
} }