swf: Make avm2 Reader operate directly with byte slices
This commit is contained in:
parent
73b251d6ec
commit
dad21d4398
|
@ -1460,7 +1460,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
||||||
) -> Result<FrameControl<'gc>, Error<'gc>> {
|
) -> Result<FrameControl<'gc>, Error<'gc>> {
|
||||||
let val = self.context.avm1.pop();
|
let val = self.context.avm1.pop();
|
||||||
if val.as_bool(self.current_swf_version()) {
|
if val.as_bool(self.current_swf_version()) {
|
||||||
self.seek(jump_offset, reader, data)?;
|
reader.seek(data.as_ref(), jump_offset);
|
||||||
}
|
}
|
||||||
Ok(FrameControl::Continue)
|
Ok(FrameControl::Continue)
|
||||||
}
|
}
|
||||||
|
@ -1543,7 +1543,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
||||||
reader: &mut Reader<'b>,
|
reader: &mut Reader<'b>,
|
||||||
data: &'b SwfSlice,
|
data: &'b SwfSlice,
|
||||||
) -> Result<FrameControl<'gc>, Error<'gc>> {
|
) -> Result<FrameControl<'gc>, Error<'gc>> {
|
||||||
self.seek(jump_offset, reader, data)?;
|
reader.seek(data.as_ref(), jump_offset);
|
||||||
Ok(FrameControl::Continue)
|
Ok(FrameControl::Continue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3008,18 +3008,4 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
||||||
Ok(FrameControl::Continue)
|
Ok(FrameControl::Continue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn seek<'b>(
|
|
||||||
&self,
|
|
||||||
jump_offset: i16,
|
|
||||||
reader: &mut Reader<'b>,
|
|
||||||
data: &'b SwfSlice,
|
|
||||||
) -> Result<(), Error<'gc>> {
|
|
||||||
let slice = data.movie.data();
|
|
||||||
let mut pos = reader.get_ref().as_ptr() as usize - slice.as_ptr() as usize;
|
|
||||||
pos = (pos as isize + isize::from(jump_offset)) as usize;
|
|
||||||
pos = pos.min(slice.len());
|
|
||||||
*reader.get_mut() = &slice[pos as usize..];
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,6 @@ use crate::avm2::{value, Avm2, Error};
|
||||||
use crate::context::UpdateContext;
|
use crate::context::UpdateContext;
|
||||||
use gc_arena::{Gc, GcCell, MutationContext};
|
use gc_arena::{Gc, GcCell, MutationContext};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::io::Cursor;
|
|
||||||
use swf::avm2::read::Reader;
|
use swf::avm2::read::Reader;
|
||||||
use swf::avm2::types::{
|
use swf::avm2::types::{
|
||||||
Class as AbcClass, Index, Method as AbcMethod, Multiname as AbcMultiname,
|
Class as AbcClass, Index, Method as AbcMethod, Multiname as AbcMultiname,
|
||||||
|
@ -507,10 +506,11 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
||||||
let body: Result<_, Error> = method
|
let body: Result<_, Error> = method
|
||||||
.body()
|
.body()
|
||||||
.ok_or_else(|| "Cannot execute non-native method without body".into());
|
.ok_or_else(|| "Cannot execute non-native method without body".into());
|
||||||
let mut read = Reader::new(Cursor::new(body?.code.as_ref()));
|
let body = body?;
|
||||||
|
let mut reader = Reader::new(&body.code);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let result = self.do_next_opcode(method, &mut read);
|
let result = self.do_next_opcode(method, &mut reader, &body.code);
|
||||||
match result {
|
match result {
|
||||||
Ok(FrameControl::Return(value)) => break Ok(value),
|
Ok(FrameControl::Return(value)) => break Ok(value),
|
||||||
Ok(FrameControl::Continue) => {}
|
Ok(FrameControl::Continue) => {}
|
||||||
|
@ -520,10 +520,11 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run a single action from a given action reader.
|
/// Run a single action from a given action reader.
|
||||||
fn do_next_opcode(
|
fn do_next_opcode<'b>(
|
||||||
&mut self,
|
&mut self,
|
||||||
method: Gc<'gc, BytecodeMethod<'gc>>,
|
method: Gc<'gc, BytecodeMethod<'gc>>,
|
||||||
reader: &mut Reader<Cursor<&[u8]>>,
|
reader: &mut Reader<'b>,
|
||||||
|
full_data: &'b [u8],
|
||||||
) -> Result<FrameControl<'gc>, Error> {
|
) -> Result<FrameControl<'gc>, Error> {
|
||||||
if self.context.update_start.elapsed() >= self.context.max_execution_duration {
|
if self.context.update_start.elapsed() >= self.context.max_execution_duration {
|
||||||
return Err(
|
return Err(
|
||||||
|
@ -635,21 +636,21 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
||||||
Op::SubtractI => self.op_subtract_i(),
|
Op::SubtractI => self.op_subtract_i(),
|
||||||
Op::Swap => self.op_swap(),
|
Op::Swap => self.op_swap(),
|
||||||
Op::URShift => self.op_urshift(),
|
Op::URShift => self.op_urshift(),
|
||||||
Op::Jump { offset } => self.op_jump(offset, reader),
|
Op::Jump { offset } => self.op_jump(offset, reader, full_data),
|
||||||
Op::IfTrue { offset } => self.op_if_true(offset, reader),
|
Op::IfTrue { offset } => self.op_if_true(offset, reader, full_data),
|
||||||
Op::IfFalse { offset } => self.op_if_false(offset, reader),
|
Op::IfFalse { offset } => self.op_if_false(offset, reader, full_data),
|
||||||
Op::IfStrictEq { offset } => self.op_if_strict_eq(offset, reader),
|
Op::IfStrictEq { offset } => self.op_if_strict_eq(offset, reader, full_data),
|
||||||
Op::IfStrictNe { offset } => self.op_if_strict_ne(offset, reader),
|
Op::IfStrictNe { offset } => self.op_if_strict_ne(offset, reader, full_data),
|
||||||
Op::IfEq { offset } => self.op_if_eq(offset, reader),
|
Op::IfEq { offset } => self.op_if_eq(offset, reader, full_data),
|
||||||
Op::IfNe { offset } => self.op_if_ne(offset, reader),
|
Op::IfNe { offset } => self.op_if_ne(offset, reader, full_data),
|
||||||
Op::IfGe { offset } => self.op_if_ge(offset, reader),
|
Op::IfGe { offset } => self.op_if_ge(offset, reader, full_data),
|
||||||
Op::IfGt { offset } => self.op_if_gt(offset, reader),
|
Op::IfGt { offset } => self.op_if_gt(offset, reader, full_data),
|
||||||
Op::IfLe { offset } => self.op_if_le(offset, reader),
|
Op::IfLe { offset } => self.op_if_le(offset, reader, full_data),
|
||||||
Op::IfLt { offset } => self.op_if_lt(offset, reader),
|
Op::IfLt { offset } => self.op_if_lt(offset, reader, full_data),
|
||||||
Op::IfNge { offset } => self.op_if_nge(offset, reader),
|
Op::IfNge { offset } => self.op_if_nge(offset, reader, full_data),
|
||||||
Op::IfNgt { offset } => self.op_if_ngt(offset, reader),
|
Op::IfNgt { offset } => self.op_if_ngt(offset, reader, full_data),
|
||||||
Op::IfNle { offset } => self.op_if_nle(offset, reader),
|
Op::IfNle { offset } => self.op_if_nle(offset, reader, full_data),
|
||||||
Op::IfNlt { offset } => self.op_if_nlt(offset, reader),
|
Op::IfNlt { offset } => self.op_if_nlt(offset, reader, full_data),
|
||||||
Op::StrictEquals => self.op_strict_equals(),
|
Op::StrictEquals => self.op_strict_equals(),
|
||||||
Op::Equals => self.op_equals(),
|
Op::Equals => self.op_equals(),
|
||||||
Op::GreaterEquals => self.op_greater_equals(),
|
Op::GreaterEquals => self.op_greater_equals(),
|
||||||
|
@ -1834,219 +1835,234 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
||||||
Ok(FrameControl::Continue)
|
Ok(FrameControl::Continue)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_jump(
|
fn op_jump<'b>(
|
||||||
&mut self,
|
&mut self,
|
||||||
offset: i32,
|
offset: i32,
|
||||||
reader: &mut Reader<Cursor<&[u8]>>,
|
reader: &mut Reader<'b>,
|
||||||
|
full_data: &'b [u8],
|
||||||
) -> Result<FrameControl<'gc>, Error> {
|
) -> Result<FrameControl<'gc>, Error> {
|
||||||
reader.seek(offset as i64)?;
|
reader.seek(full_data, offset);
|
||||||
|
|
||||||
Ok(FrameControl::Continue)
|
Ok(FrameControl::Continue)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_if_true(
|
fn op_if_true<'b>(
|
||||||
&mut self,
|
&mut self,
|
||||||
offset: i32,
|
offset: i32,
|
||||||
reader: &mut Reader<Cursor<&[u8]>>,
|
reader: &mut Reader<'b>,
|
||||||
|
full_data: &'b [u8],
|
||||||
) -> Result<FrameControl<'gc>, Error> {
|
) -> Result<FrameControl<'gc>, Error> {
|
||||||
let value = self.context.avm2.pop().coerce_to_boolean();
|
let value = self.context.avm2.pop().coerce_to_boolean();
|
||||||
|
|
||||||
if value {
|
if value {
|
||||||
reader.seek(offset as i64)?;
|
reader.seek(full_data, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(FrameControl::Continue)
|
Ok(FrameControl::Continue)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_if_false(
|
fn op_if_false<'b>(
|
||||||
&mut self,
|
&mut self,
|
||||||
offset: i32,
|
offset: i32,
|
||||||
reader: &mut Reader<Cursor<&[u8]>>,
|
reader: &mut Reader<'b>,
|
||||||
|
full_data: &'b [u8],
|
||||||
) -> Result<FrameControl<'gc>, Error> {
|
) -> Result<FrameControl<'gc>, Error> {
|
||||||
let value = self.context.avm2.pop().coerce_to_boolean();
|
let value = self.context.avm2.pop().coerce_to_boolean();
|
||||||
|
|
||||||
if !value {
|
if !value {
|
||||||
reader.seek(offset as i64)?;
|
reader.seek(full_data, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(FrameControl::Continue)
|
Ok(FrameControl::Continue)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_if_strict_eq(
|
fn op_if_strict_eq<'b>(
|
||||||
&mut self,
|
&mut self,
|
||||||
offset: i32,
|
offset: i32,
|
||||||
reader: &mut Reader<Cursor<&[u8]>>,
|
reader: &mut Reader<'b>,
|
||||||
|
full_data: &'b [u8],
|
||||||
) -> Result<FrameControl<'gc>, Error> {
|
) -> Result<FrameControl<'gc>, Error> {
|
||||||
let value2 = self.context.avm2.pop();
|
let value2 = self.context.avm2.pop();
|
||||||
let value1 = self.context.avm2.pop();
|
let value1 = self.context.avm2.pop();
|
||||||
|
|
||||||
if value1 == value2 {
|
if value1 == value2 {
|
||||||
reader.seek(offset as i64)?;
|
reader.seek(full_data, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(FrameControl::Continue)
|
Ok(FrameControl::Continue)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_if_strict_ne(
|
fn op_if_strict_ne<'b>(
|
||||||
&mut self,
|
&mut self,
|
||||||
offset: i32,
|
offset: i32,
|
||||||
reader: &mut Reader<Cursor<&[u8]>>,
|
reader: &mut Reader<'b>,
|
||||||
|
full_data: &'b [u8],
|
||||||
) -> Result<FrameControl<'gc>, Error> {
|
) -> Result<FrameControl<'gc>, Error> {
|
||||||
let value2 = self.context.avm2.pop();
|
let value2 = self.context.avm2.pop();
|
||||||
let value1 = self.context.avm2.pop();
|
let value1 = self.context.avm2.pop();
|
||||||
|
|
||||||
if value1 != value2 {
|
if value1 != value2 {
|
||||||
reader.seek(offset as i64)?;
|
reader.seek(full_data, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(FrameControl::Continue)
|
Ok(FrameControl::Continue)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_if_eq(
|
fn op_if_eq<'b>(
|
||||||
&mut self,
|
&mut self,
|
||||||
offset: i32,
|
offset: i32,
|
||||||
reader: &mut Reader<Cursor<&[u8]>>,
|
reader: &mut Reader<'b>,
|
||||||
|
full_data: &'b [u8],
|
||||||
) -> Result<FrameControl<'gc>, Error> {
|
) -> Result<FrameControl<'gc>, Error> {
|
||||||
let value2 = self.context.avm2.pop();
|
let value2 = self.context.avm2.pop();
|
||||||
let value1 = self.context.avm2.pop();
|
let value1 = self.context.avm2.pop();
|
||||||
|
|
||||||
if value1.abstract_eq(&value2, self)? {
|
if value1.abstract_eq(&value2, self)? {
|
||||||
reader.seek(offset as i64)?;
|
reader.seek(full_data, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(FrameControl::Continue)
|
Ok(FrameControl::Continue)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_if_ne(
|
fn op_if_ne<'b>(
|
||||||
&mut self,
|
&mut self,
|
||||||
offset: i32,
|
offset: i32,
|
||||||
reader: &mut Reader<Cursor<&[u8]>>,
|
reader: &mut Reader<'b>,
|
||||||
|
full_data: &'b [u8],
|
||||||
) -> Result<FrameControl<'gc>, Error> {
|
) -> Result<FrameControl<'gc>, Error> {
|
||||||
let value2 = self.context.avm2.pop();
|
let value2 = self.context.avm2.pop();
|
||||||
let value1 = self.context.avm2.pop();
|
let value1 = self.context.avm2.pop();
|
||||||
|
|
||||||
if !value1.abstract_eq(&value2, self)? {
|
if !value1.abstract_eq(&value2, self)? {
|
||||||
reader.seek(offset as i64)?;
|
reader.seek(full_data, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(FrameControl::Continue)
|
Ok(FrameControl::Continue)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_if_ge(
|
fn op_if_ge<'b>(
|
||||||
&mut self,
|
&mut self,
|
||||||
offset: i32,
|
offset: i32,
|
||||||
reader: &mut Reader<Cursor<&[u8]>>,
|
reader: &mut Reader<'b>,
|
||||||
|
full_data: &'b [u8],
|
||||||
) -> Result<FrameControl<'gc>, Error> {
|
) -> Result<FrameControl<'gc>, Error> {
|
||||||
let value2 = self.context.avm2.pop();
|
let value2 = self.context.avm2.pop();
|
||||||
let value1 = self.context.avm2.pop();
|
let value1 = self.context.avm2.pop();
|
||||||
|
|
||||||
if value1.abstract_lt(&value2, self)? == Some(false) {
|
if value1.abstract_lt(&value2, self)? == Some(false) {
|
||||||
reader.seek(offset as i64)?;
|
reader.seek(full_data, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(FrameControl::Continue)
|
Ok(FrameControl::Continue)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_if_gt(
|
fn op_if_gt<'b>(
|
||||||
&mut self,
|
&mut self,
|
||||||
offset: i32,
|
offset: i32,
|
||||||
reader: &mut Reader<Cursor<&[u8]>>,
|
reader: &mut Reader<'b>,
|
||||||
|
full_data: &'b [u8],
|
||||||
) -> Result<FrameControl<'gc>, Error> {
|
) -> Result<FrameControl<'gc>, Error> {
|
||||||
let value2 = self.context.avm2.pop();
|
let value2 = self.context.avm2.pop();
|
||||||
let value1 = self.context.avm2.pop();
|
let value1 = self.context.avm2.pop();
|
||||||
|
|
||||||
if value2.abstract_lt(&value1, self)? == Some(true) {
|
if value2.abstract_lt(&value1, self)? == Some(true) {
|
||||||
reader.seek(offset as i64)?;
|
reader.seek(full_data, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(FrameControl::Continue)
|
Ok(FrameControl::Continue)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_if_le(
|
fn op_if_le<'b>(
|
||||||
&mut self,
|
&mut self,
|
||||||
offset: i32,
|
offset: i32,
|
||||||
reader: &mut Reader<Cursor<&[u8]>>,
|
reader: &mut Reader<'b>,
|
||||||
|
full_data: &'b [u8],
|
||||||
) -> Result<FrameControl<'gc>, Error> {
|
) -> Result<FrameControl<'gc>, Error> {
|
||||||
let value2 = self.context.avm2.pop();
|
let value2 = self.context.avm2.pop();
|
||||||
let value1 = self.context.avm2.pop();
|
let value1 = self.context.avm2.pop();
|
||||||
|
|
||||||
if value2.abstract_lt(&value1, self)? == Some(false) {
|
if value2.abstract_lt(&value1, self)? == Some(false) {
|
||||||
reader.seek(offset as i64)?;
|
reader.seek(full_data, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(FrameControl::Continue)
|
Ok(FrameControl::Continue)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_if_lt(
|
fn op_if_lt<'b>(
|
||||||
&mut self,
|
&mut self,
|
||||||
offset: i32,
|
offset: i32,
|
||||||
reader: &mut Reader<Cursor<&[u8]>>,
|
reader: &mut Reader<'b>,
|
||||||
|
full_data: &'b [u8],
|
||||||
) -> Result<FrameControl<'gc>, Error> {
|
) -> Result<FrameControl<'gc>, Error> {
|
||||||
let value2 = self.context.avm2.pop();
|
let value2 = self.context.avm2.pop();
|
||||||
let value1 = self.context.avm2.pop();
|
let value1 = self.context.avm2.pop();
|
||||||
|
|
||||||
if value1.abstract_lt(&value2, self)? == Some(true) {
|
if value1.abstract_lt(&value2, self)? == Some(true) {
|
||||||
reader.seek(offset as i64)?;
|
reader.seek(full_data, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(FrameControl::Continue)
|
Ok(FrameControl::Continue)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_if_nge(
|
fn op_if_nge<'b>(
|
||||||
&mut self,
|
&mut self,
|
||||||
offset: i32,
|
offset: i32,
|
||||||
reader: &mut Reader<Cursor<&[u8]>>,
|
reader: &mut Reader<'b>,
|
||||||
|
full_data: &'b [u8],
|
||||||
) -> Result<FrameControl<'gc>, Error> {
|
) -> Result<FrameControl<'gc>, Error> {
|
||||||
let value2 = self.context.avm2.pop();
|
let value2 = self.context.avm2.pop();
|
||||||
let value1 = self.context.avm2.pop();
|
let value1 = self.context.avm2.pop();
|
||||||
|
|
||||||
if value1.abstract_lt(&value2, self)?.unwrap_or(true) {
|
if value1.abstract_lt(&value2, self)?.unwrap_or(true) {
|
||||||
reader.seek(offset as i64)?;
|
reader.seek(full_data, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(FrameControl::Continue)
|
Ok(FrameControl::Continue)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_if_ngt(
|
fn op_if_ngt<'b>(
|
||||||
&mut self,
|
&mut self,
|
||||||
offset: i32,
|
offset: i32,
|
||||||
reader: &mut Reader<Cursor<&[u8]>>,
|
reader: &mut Reader<'b>,
|
||||||
|
full_data: &'b [u8],
|
||||||
) -> Result<FrameControl<'gc>, Error> {
|
) -> Result<FrameControl<'gc>, Error> {
|
||||||
let value2 = self.context.avm2.pop();
|
let value2 = self.context.avm2.pop();
|
||||||
let value1 = self.context.avm2.pop();
|
let value1 = self.context.avm2.pop();
|
||||||
|
|
||||||
if !value2.abstract_lt(&value1, self)?.unwrap_or(false) {
|
if !value2.abstract_lt(&value1, self)?.unwrap_or(false) {
|
||||||
reader.seek(offset as i64)?;
|
reader.seek(full_data, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(FrameControl::Continue)
|
Ok(FrameControl::Continue)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_if_nle(
|
fn op_if_nle<'b>(
|
||||||
&mut self,
|
&mut self,
|
||||||
offset: i32,
|
offset: i32,
|
||||||
reader: &mut Reader<Cursor<&[u8]>>,
|
reader: &mut Reader<'b>,
|
||||||
|
full_data: &'b [u8],
|
||||||
) -> Result<FrameControl<'gc>, Error> {
|
) -> Result<FrameControl<'gc>, Error> {
|
||||||
let value2 = self.context.avm2.pop();
|
let value2 = self.context.avm2.pop();
|
||||||
let value1 = self.context.avm2.pop();
|
let value1 = self.context.avm2.pop();
|
||||||
|
|
||||||
if value2.abstract_lt(&value1, self)?.unwrap_or(true) {
|
if value2.abstract_lt(&value1, self)?.unwrap_or(true) {
|
||||||
reader.seek(offset as i64)?;
|
reader.seek(full_data, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(FrameControl::Continue)
|
Ok(FrameControl::Continue)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn op_if_nlt(
|
fn op_if_nlt<'b>(
|
||||||
&mut self,
|
&mut self,
|
||||||
offset: i32,
|
offset: i32,
|
||||||
reader: &mut Reader<Cursor<&[u8]>>,
|
reader: &mut Reader<'b>,
|
||||||
|
full_data: &'b [u8],
|
||||||
) -> Result<FrameControl<'gc>, Error> {
|
) -> Result<FrameControl<'gc>, Error> {
|
||||||
let value2 = self.context.avm2.pop();
|
let value2 = self.context.avm2.pop();
|
||||||
let value1 = self.context.avm2.pop();
|
let value1 = self.context.avm2.pop();
|
||||||
|
|
||||||
if !value1.abstract_lt(&value2, self)?.unwrap_or(false) {
|
if !value1.abstract_lt(&value2, self)?.unwrap_or(false) {
|
||||||
reader.seek(offset as i64)?;
|
reader.seek(full_data, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(FrameControl::Continue)
|
Ok(FrameControl::Continue)
|
||||||
|
|
|
@ -29,6 +29,13 @@ impl<'a> Reader<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn seek(&mut self, data: &'a [u8], jump_offset: i16) {
|
||||||
|
let mut pos = self.input.as_ptr() as usize - data.as_ptr() as usize;
|
||||||
|
pos = (pos as isize + isize::from(jump_offset)) as usize;
|
||||||
|
pos = pos.min(data.len());
|
||||||
|
self.input = &data[pos as usize..];
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn encoding(&self) -> &'static Encoding {
|
pub fn encoding(&self) -> &'static Encoding {
|
||||||
SwfStr::encoding_for_version(self.version)
|
SwfStr::encoding_for_version(self.version)
|
||||||
|
|
|
@ -2,25 +2,23 @@ use crate::avm2::types::*;
|
||||||
use crate::error::{Error, Result};
|
use crate::error::{Error, Result};
|
||||||
use crate::read::SwfReadExt;
|
use crate::read::SwfReadExt;
|
||||||
use byteorder::{LittleEndian, ReadBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt};
|
||||||
use std::io::{self, Read, Seek, SeekFrom};
|
use std::io::{self, Read};
|
||||||
|
|
||||||
pub struct Reader<R: Read> {
|
pub struct Reader<'a> {
|
||||||
input: R,
|
input: &'a [u8],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Reader<'a> {
|
||||||
|
pub fn new(input: &'a [u8]) -> Self {
|
||||||
|
Self { input }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R> Reader<R>
|
|
||||||
where
|
|
||||||
R: Read + Seek,
|
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn seek(&mut self, relative_offset: i64) -> std::io::Result<u64> {
|
pub fn seek(&mut self, data: &'a [u8], relative_offset: i32) {
|
||||||
self.input.seek(SeekFrom::Current(relative_offset as i64))
|
let mut pos = self.input.as_ptr() as usize - data.as_ptr() as usize;
|
||||||
}
|
pos = (pos as isize + relative_offset as isize) as usize;
|
||||||
}
|
pos = pos.min(data.len());
|
||||||
|
self.input = &data[pos as usize..];
|
||||||
impl<R: Read> Reader<R> {
|
|
||||||
pub fn new(input: R) -> Reader<R> {
|
|
||||||
Reader { input }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read(&mut self) -> Result<AbcFile> {
|
pub fn read(&mut self) -> Result<AbcFile> {
|
||||||
|
@ -861,7 +859,7 @@ impl<R: Read> Reader<R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, R: 'a + Read> SwfReadExt for Reader<R> {
|
impl<'a> SwfReadExt for Reader<'a> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn read_u8(&mut self) -> io::Result<u8> {
|
fn read_u8(&mut self) -> io::Result<u8> {
|
||||||
self.input.read_u8()
|
self.input.read_u8()
|
||||||
|
|
Loading…
Reference in New Issue