avm1: Correctly handle undefined delimiter in String.split()

This commit is contained in:
nosamu 2023-12-19 07:04:31 -06:00 committed by Lord-McSweeney
parent ba6ba842d7
commit d443bd9def
4 changed files with 39 additions and 27 deletions

View File

@ -258,33 +258,42 @@ fn split<'gc>(
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
let this = Value::from(this).coerce_to_string(activation)?;
let delimiter = args
.get(0)
.unwrap_or(&Value::Undefined)
.coerce_to_string(activation)?;
let limit = match args.get(1).unwrap_or(&Value::Undefined) {
Value::Undefined => usize::MAX,
limit => limit.coerce_to_i32(activation)?.max(0) as usize,
};
if delimiter.is_empty() {
// When using an empty delimiter, Str::split adds an extra beginning and trailing item, but Flash does not.
// e.g., split("foo", "") returns ["", "f", "o", "o", ""] in Rust but ["f, "o", "o"] in Flash.
// Special case this to match Flash's behavior.
Ok(ArrayObject::new(
activation.context.gc_context,
activation.context.avm1.prototypes().array,
this.iter().take(limit).map(|c| {
AvmString::new(activation.context.gc_context, WString::from_unit(c)).into()
}),
)
.into())
if let Some(delimiter) = match args.get(0).unwrap_or(&Value::Undefined) {
&Value::Undefined => None,
v => Some(v.coerce_to_string(activation)?),
} {
if delimiter.is_empty() {
// When using an empty delimiter, Str::split adds an extra beginning and trailing item,
// but Flash does not.
// e.g., split("foo", "") returns ["", "f", "o", "o", ""] in Rust but ["f, "o", "o"] in Flash.
// Special case this to match Flash's behavior.
Ok(ArrayObject::new(
activation.context.gc_context,
activation.context.avm1.prototypes().array,
this.iter().take(limit).map(|c| {
AvmString::new(activation.context.gc_context, WString::from_unit(c)).into()
}),
)
.into())
} else {
Ok(ArrayObject::new(
activation.context.gc_context,
activation.context.avm1.prototypes().array,
this.split(&delimiter)
.take(limit)
.map(|c| AvmString::new(activation.context.gc_context, c).into()),
)
.into())
}
} else {
Ok(ArrayObject::new(
activation.context.gc_context,
activation.context.avm1.prototypes().array,
this.split(&delimiter)
.take(limit)
.map(|c| AvmString::new(activation.context.gc_context, c).into()),
[this.into()]
)
.into())
}

View File

@ -242,8 +242,8 @@ HELLO𝔄hello
// split
// s.split(",")
5
A,,b,c,
6
A,,b,undefined0,c,
// s.split(",", 2)
2
A,
@ -254,20 +254,23 @@ A,
0
// s.split(",", undefined)
5
A,,b,c,
6
A,,b,undefined0,c,
// s.split(",", null)
0
// s.split("")
7
A,,,,,b,,,c,,
18
A,,,,,b,,,u,n,d,e,f,i,n,e,d,0,,,c,,
// s.split(undefined)
1
A,,b,c,
A,,b,undefined0,c,
// s.split(undefined, 0)
1
A,,b,undefined0,c,
// s.split()
1
A,,b,c,
A,,b,undefined0,c,
// toLowerCase
// "teST😋".toLowerCase()