avm2: Implement Op::EscXAttr and Op::EscXElem
This commit is contained in:
parent
e453cbf0ef
commit
0ea564f75c
|
@ -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 += """,
|
||||
'<' => r += "<",
|
||||
'&' => r += "&",
|
||||
'\u{000A}' => r += "
",
|
||||
'\u{000D}' => r += "
",
|
||||
'\u{0009}' => r += "	",
|
||||
_ => 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 += "<",
|
||||
'>' => r += ">",
|
||||
'&' => r += "&",
|
||||
_ => 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(
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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!\"£$%^&*()");
|
|
@ -0,0 +1,2 @@
|
|||
// EscXAttr( 'TestString<&>#\n\r\tTest!"£$%^&*()' )
|
||||
TestString<&>#\n\r\tTest!"£$%^&*()
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue