avm2: Fix edge cases in RegExp constructor
This commit is contained in:
parent
fc4b51b20f
commit
4e84632609
|
@ -1,6 +1,7 @@
|
|||
//! `RegExp` impl
|
||||
|
||||
use crate::avm2::class::Class;
|
||||
use crate::avm2::error::type_error;
|
||||
use crate::avm2::method::{Method, NativeMethodImpl, ParamConfig};
|
||||
use crate::avm2::object::{regexp_allocator, ArrayObject, FunctionObject, Object, TObject};
|
||||
use crate::avm2::regexp::RegExpFlags;
|
||||
|
@ -27,16 +28,34 @@ pub fn instance_init<'gc>(
|
|||
activation.super_init(this, &[])?;
|
||||
|
||||
if let Some(mut regexp) = this.as_regexp_mut(activation.context.gc_context) {
|
||||
regexp.set_source(
|
||||
args.get(0)
|
||||
let source: AvmString<'gc> = match args.get(0) {
|
||||
Some(Value::Undefined) => "".into(),
|
||||
Some(Value::Object(Object::RegExpObject(o))) => {
|
||||
if !matches!(args.get(1), Some(Value::Undefined)) {
|
||||
return Err(Error::AvmError(type_error(
|
||||
activation,
|
||||
"Error #1100: Cannot supply flags when constructing one RegExp from another.",
|
||||
1100,
|
||||
)?));
|
||||
}
|
||||
let other = o.as_regexp().unwrap();
|
||||
regexp.set_source(other.source());
|
||||
regexp.set_flags(other.flags());
|
||||
return Ok(Value::Undefined);
|
||||
}
|
||||
arg => arg
|
||||
.unwrap_or(&Value::String("".into()))
|
||||
.coerce_to_string(activation)?,
|
||||
);
|
||||
};
|
||||
|
||||
let flag_chars = args
|
||||
.get(1)
|
||||
.unwrap_or(&Value::String("".into()))
|
||||
.coerce_to_string(activation)?;
|
||||
regexp.set_source(source);
|
||||
|
||||
let flag_chars = match args.get(1) {
|
||||
Some(Value::Undefined) => "".into(),
|
||||
arg => arg
|
||||
.unwrap_or(&Value::String("".into()))
|
||||
.coerce_to_string(activation)?,
|
||||
};
|
||||
|
||||
let mut flags = RegExpFlags::empty();
|
||||
for c in &flag_chars {
|
||||
|
@ -299,16 +318,8 @@ pub fn create_class<'gc>(activation: &mut Activation<'_, 'gc>) -> GcCell<'gc, Cl
|
|||
instance_init,
|
||||
"<RegExp instance initializer>",
|
||||
vec![
|
||||
ParamConfig::optional(
|
||||
"re",
|
||||
Multiname::new(activation.avm2().public_namespace, "String"),
|
||||
"",
|
||||
),
|
||||
ParamConfig::optional(
|
||||
"flags",
|
||||
Multiname::new(activation.avm2().public_namespace, "String"),
|
||||
"",
|
||||
),
|
||||
ParamConfig::optional("re", Multiname::any(mc), Value::Undefined),
|
||||
ParamConfig::optional("flags", Multiname::any(mc), Value::Undefined),
|
||||
],
|
||||
false,
|
||||
mc,
|
||||
|
|
|
@ -14,8 +14,10 @@ trace("ignoreCase", re.ignoreCase);
|
|||
trace("multiline", re.multiline);
|
||||
trace("");
|
||||
|
||||
function test(source:String, flags:String) {
|
||||
trace("// new RegExp(\"" + source + "\", \"" + flags + "\");");
|
||||
function test(source:*, flags:*) {
|
||||
var sourceStr = (typeof source === "string") ? "\"" + source + "\"" : source;
|
||||
var flagsStr = (typeof flags === "string") ? "\"" + flags + "\"" : flags;
|
||||
trace("// new RegExp(" + sourceStr + ", " + flagsStr + ");");
|
||||
var re = new RegExp(source, flags);
|
||||
trace(re);
|
||||
trace(re.source == source);
|
||||
|
@ -38,3 +40,19 @@ test("all flags", "sxgim");
|
|||
test("invalid flags", "|%?-/.あa");
|
||||
test("uppercase flags", "SXGIM");
|
||||
test("duplicate flags", "ssgg");
|
||||
|
||||
test(undefined, undefined);
|
||||
test(null, null);
|
||||
test(/#((.*))$/m, undefined);
|
||||
test(/empty flags/, undefined);
|
||||
test(/dotall embedded flags/s, undefined);
|
||||
try {
|
||||
test(/empty string separate flag/s, "");
|
||||
} catch(e) {
|
||||
trace(e);
|
||||
}
|
||||
try {
|
||||
test(/dotall separate flags/s, "s");
|
||||
} catch(e) {
|
||||
trace(e);
|
||||
}
|
||||
|
|
|
@ -97,3 +97,52 @@ global true
|
|||
ignoreCase false
|
||||
multiline false
|
||||
|
||||
// new RegExp(undefined, undefined);
|
||||
//
|
||||
false
|
||||
dotall false
|
||||
extended false
|
||||
global false
|
||||
ignoreCase false
|
||||
multiline false
|
||||
|
||||
// new RegExp(null, null);
|
||||
/null/
|
||||
false
|
||||
dotall false
|
||||
extended false
|
||||
global false
|
||||
ignoreCase false
|
||||
multiline false
|
||||
|
||||
// new RegExp(/#((.*))$/m, undefined);
|
||||
/#((.*))$/m
|
||||
false
|
||||
dotall false
|
||||
extended false
|
||||
global false
|
||||
ignoreCase false
|
||||
multiline true
|
||||
|
||||
// new RegExp(/empty flags/, undefined);
|
||||
/empty flags/
|
||||
false
|
||||
dotall false
|
||||
extended false
|
||||
global false
|
||||
ignoreCase false
|
||||
multiline false
|
||||
|
||||
// new RegExp(/dotall embedded flags/s, undefined);
|
||||
/dotall embedded flags/s
|
||||
false
|
||||
dotall true
|
||||
extended false
|
||||
global false
|
||||
ignoreCase false
|
||||
multiline false
|
||||
|
||||
// new RegExp(/empty string separate flag/s, "");
|
||||
TypeError: Error #1100: Cannot supply flags when constructing one RegExp from another.
|
||||
// new RegExp(/dotall separate flags/s, "s");
|
||||
TypeError: Error #1100: Cannot supply flags when constructing one RegExp from another.
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue