avm2: Implement encodeURI and encodeURIComponent
This commit is contained in:
parent
e970174339
commit
7f58b92348
|
@ -468,6 +468,14 @@ pub fn load_player_globals<'gc>(
|
|||
function(activation, "", "parseInt", toplevel::parse_int, script)?;
|
||||
function(activation, "", "parseFloat", toplevel::parse_float, script)?;
|
||||
function(activation, "", "escape", toplevel::escape, script)?;
|
||||
function(activation, "", "encodeURI", toplevel::encode_uri, script)?;
|
||||
function(
|
||||
activation,
|
||||
"",
|
||||
"encodeURIComponent",
|
||||
toplevel::encode_uri_component,
|
||||
script,
|
||||
)?;
|
||||
|
||||
avm2_system_class!(regexp, activation, regexp::create_class(activation), script);
|
||||
avm2_system_class!(vector, activation, vector::create_class(activation), script);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
//! Global scope built-ins
|
||||
|
||||
use ruffle_wstr::Units;
|
||||
|
||||
use crate::avm2::activation::Activation;
|
||||
use crate::avm2::object::Object;
|
||||
use crate::avm2::value::Value;
|
||||
|
@ -7,6 +9,7 @@ use crate::avm2::Error;
|
|||
use crate::string::{AvmString, WStr, WString};
|
||||
use crate::stub::Stub;
|
||||
use std::borrow::Cow;
|
||||
use std::fmt::Write;
|
||||
|
||||
pub fn trace<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
|
@ -263,3 +266,68 @@ pub fn escape<'gc>(
|
|||
|
||||
Ok(AvmString::new(activation.context.gc_context, output).into())
|
||||
}
|
||||
|
||||
pub fn encode_uri<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
_this: Option<Object<'gc>>,
|
||||
args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
encode_utf8_with_exclusions(
|
||||
activation,
|
||||
args,
|
||||
// Characters that are not escaped, sourced from as3 docs
|
||||
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@;/?:@&=+$,#-_.!~*'()",
|
||||
)
|
||||
}
|
||||
|
||||
pub fn encode_uri_component<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
_this: Option<Object<'gc>>,
|
||||
args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
encode_utf8_with_exclusions(
|
||||
activation,
|
||||
args,
|
||||
// Characters that are not escaped, sourced from as3 docs
|
||||
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_.!~*'()",
|
||||
)
|
||||
}
|
||||
|
||||
fn encode_utf8_with_exclusions<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
args: &[Value<'gc>],
|
||||
not_converted: &str,
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
let value = match args.first() {
|
||||
None => return Ok("undefined".into()),
|
||||
Some(Value::Undefined) => return Ok("null".into()),
|
||||
Some(value) => value,
|
||||
};
|
||||
|
||||
let mut output = String::new();
|
||||
|
||||
let input = value.coerce_to_string(activation)?;
|
||||
let input_string = match input.units() {
|
||||
// Latin-1 values map directly to unicode codepoints,
|
||||
// so we can directly convert to a `char`
|
||||
Units::Bytes(bytes) => bytes.iter().map(|b| *b as char).collect(),
|
||||
Units::Wide(wide) => String::from_utf16_lossy(wide),
|
||||
};
|
||||
|
||||
for x in input_string.chars() {
|
||||
if not_converted.contains(x) {
|
||||
output.push(x);
|
||||
} else {
|
||||
let mut bytes = [0; 4];
|
||||
let utf8_bytes = x.encode_utf8(&mut bytes);
|
||||
let mut encoded = String::new();
|
||||
// Each byte in the utf-8 encoding is encoded as a hex value
|
||||
for byte in utf8_bytes.bytes() {
|
||||
write!(encoded, "%{x:02X}", x = byte).unwrap();
|
||||
}
|
||||
output.push_str(&encoded);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(AvmString::new_utf8(activation.context.gc_context, output).into())
|
||||
}
|
||||
|
|
|
@ -4,38 +4,44 @@
|
|||
}
|
||||
}
|
||||
|
||||
trace("// escape()");
|
||||
trace(escape());
|
||||
import flash.utils.getDefinitionByName;
|
||||
|
||||
var fns = ["escape", "encodeURI", "encodeURIComponent"];
|
||||
for each (var fnName in fns) {
|
||||
var fn = getDefinitionByName(fnName);
|
||||
trace("// " + fnName + "()");
|
||||
trace(fn());
|
||||
trace("");
|
||||
|
||||
trace("// escape(undefined)");
|
||||
trace(escape(undefined));
|
||||
trace("// " + fnName + "(undefined)");
|
||||
trace(fn(undefined));
|
||||
trace("");
|
||||
|
||||
trace("// typeof(escape(undefined))");
|
||||
trace(typeof(escape(undefined)));
|
||||
trace("// typeof(" + fnName + "(undefined))");
|
||||
trace(typeof(fn(undefined)));
|
||||
trace("");
|
||||
|
||||
trace("// escape(null)");
|
||||
trace(escape(null));
|
||||
trace("// " + fnName + "(null)");
|
||||
trace(fn(null));
|
||||
trace("");
|
||||
|
||||
var input = "test";
|
||||
trace("// escape(\"" + input + "\")");
|
||||
trace(escape(input));
|
||||
trace("// " + fnName + "(\"" + input + "\")");
|
||||
trace(fn(input));
|
||||
trace("");
|
||||
|
||||
var input = "!\"£$%^&*()1234567890qwertyuiop[]asdfghjkl;'#\zxcvbnm,./QWERTYUIOP{}ASDFGHJKL:@~|ZXCVBNM<>?\u0010";
|
||||
trace("// escape(\"" + input + "\")");
|
||||
trace(escape(input));
|
||||
trace("// " + fnName + "(\"" + input + "\")");
|
||||
trace(fn(input));
|
||||
trace("");
|
||||
|
||||
var input = "\x05";
|
||||
trace("// escape(\"\\x05\")");
|
||||
trace(escape(input));
|
||||
trace("// " + fnName + "(\"\\x05\")");
|
||||
trace(fn(input));
|
||||
trace("");
|
||||
|
||||
var input = "😭";
|
||||
trace("// escape(\"" + input + "\")");
|
||||
trace(escape(input));
|
||||
trace("// " + fnName + "(\"" + input + "\")");
|
||||
trace(fn(input));
|
||||
trace("");
|
||||
}
|
||||
|
|
|
@ -22,3 +22,51 @@ test
|
|||
// escape("😭")
|
||||
%uD83D%uDE2D
|
||||
|
||||
// encodeURI()
|
||||
undefined
|
||||
|
||||
// encodeURI(undefined)
|
||||
null
|
||||
|
||||
// typeof(encodeURI(undefined))
|
||||
string
|
||||
|
||||
// encodeURI(null)
|
||||
null
|
||||
|
||||
// encodeURI("test")
|
||||
test
|
||||
|
||||
// encodeURI("!"£$%^&*()1234567890qwertyuiop[]asdfghjkl;'#zxcvbnm,./QWERTYUIOP{}ASDFGHJKL:@~|ZXCVBNM<>?")
|
||||
!%22%C2%A3$%25%5E&*()1234567890qwertyuiop%5B%5Dasdfghjkl;'#zxcvbnm,./QWERTYUIOP%7B%7DASDFGHJKL:@~%7CZXCVBNM%3C%3E?%10
|
||||
|
||||
// encodeURI("\x05")
|
||||
%05
|
||||
|
||||
// encodeURI("😭")
|
||||
%F0%9F%98%AD
|
||||
|
||||
// encodeURIComponent()
|
||||
undefined
|
||||
|
||||
// encodeURIComponent(undefined)
|
||||
null
|
||||
|
||||
// typeof(encodeURIComponent(undefined))
|
||||
string
|
||||
|
||||
// encodeURIComponent(null)
|
||||
null
|
||||
|
||||
// encodeURIComponent("test")
|
||||
test
|
||||
|
||||
// encodeURIComponent("!"£$%^&*()1234567890qwertyuiop[]asdfghjkl;'#zxcvbnm,./QWERTYUIOP{}ASDFGHJKL:@~|ZXCVBNM<>?")
|
||||
!%22%C2%A3%24%25%5E%26*()1234567890qwertyuiop%5B%5Dasdfghjkl%3B'%23zxcvbnm%2C.%2FQWERTYUIOP%7B%7DASDFGHJKL%3A%40~%7CZXCVBNM%3C%3E%3F%10
|
||||
|
||||
// encodeURIComponent("\x05")
|
||||
%05
|
||||
|
||||
// encodeURIComponent("😭")
|
||||
%F0%9F%98%AD
|
||||
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue