avm2: Implement Op::EscXAttr and Op::EscXElem

This commit is contained in:
CUB3D 2021-03-30 01:42:36 +01:00 committed by kmeisthax
parent e453cbf0ef
commit 0ea564f75c
6 changed files with 61 additions and 1 deletions

View File

@ -678,6 +678,8 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
Op::DebugFile { file_name } => self.op_debug_file(method, file_name),
Op::DebugLine { line_num } => self.op_debug_line(line_num),
Op::TypeOf => self.op_type_of(),
Op::EscXAttr => self.op_esc_xattr(),
Op::EscXElem => self.op_esc_elem(),
_ => self.unknown_op(op),
};
@ -2321,6 +2323,52 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
Ok(FrameControl::Continue)
}
/// Implements `Op::EscXAttr`
fn op_esc_xattr(&mut self) -> Result<FrameControl<'gc>, Error> {
//TODO: does this coerce or type error if not string
let s = self.context.avm2.pop().coerce_to_string(self)?;
// Implementation of `EscapeAttributeValue` from ECMA-357(10.2.1.2)
let mut r = String::new();
for c in s.chars() {
match c {
'"' => r += "&quot;",
'<' => r += "&lt;",
'&' => r += "&amp;",
'\u{000A}' => r += "&#xA;",
'\u{000D}' => r += "&#xD;",
'\u{0009}' => r += "&#x9;",
_ => r.push(c)
}
}
self.context.avm2.push(AvmString::new(self.context.gc_context, r));
Ok(FrameControl::Continue)
}
/// Implements `Op::EscXElem`
fn op_esc_elem(&mut self) -> Result<FrameControl<'gc>, Error> {
//TODO: does this coerce or type error if not string
let s = self.context.avm2.pop().coerce_to_string(self)?;
//TODO: does this use escapeelement or escape value as the spec says, guessing the spec is wrong, but needs testing to be sure
// contrary to the avmplus documentation, this escapes the value on the top of the stack using EscapeElementValue from ECMA-357 *NOT* EscapeAttributeValue.
// Implementation of `EscapeElementValue` from ECMA-357(10.2.1.1)
let mut r = String::new();
for c in s.chars() {
match c {
'<' => r += "&lt;",
'>' => r += "&gt;",
'&' => r += "&amp;",
_ => r.push(c)
}
}
self.context.avm2.push(AvmString::new(self.context.gc_context, r));
Ok(FrameControl::Continue)
}
#[allow(unused_variables)]
#[cfg(avm_debug)]
fn op_debug(

View File

@ -541,6 +541,7 @@ swf_tests! {
(as3_shape_drawrect, "avm2/shape_drawrect", 1),
(as3_movieclip_drawrect, "avm2/movieclip_drawrect", 1),
(as3_get_timer, "avm2/get_timer", 1),
(as3_op_escxattr, "avm2/op_escxattr", 1),
}
// TODO: These tests have some inaccuracies currently, so we use approx_eq to test that numeric values are close enough.

View File

@ -0,0 +1,9 @@
package {
public class Test {
}
}
// Makes finding this is jpexs possible
var x = new XML();
trace("// EscXAttr( \'TestString<&>#\\n\\r\\tTest!\"£$%^&*()\' )");
trace("TestString<&>#\\n\\r\\tTest!\"£$%^&*()");

View File

@ -0,0 +1,2 @@
// EscXAttr( 'TestString<&>#\n\r\tTest!"£$%^&*()' )
TestString&lt;&amp;>#\n\r\tTest!&quot;£$%^&amp;*()

Binary file not shown.

Binary file not shown.