avm2: String tests

This commit is contained in:
lukaszN 2021-09-09 13:22:41 +02:00 committed by Adrian Wielgosik
parent 4abde1500b
commit 42300d4a1e
14 changed files with 613 additions and 1 deletions

View File

@ -147,7 +147,7 @@ fn from_char_code<'gc>(
let mut out = String::with_capacity(args.len());
for arg in args {
let i = arg.coerce_to_u32(activation)? as u16;
if i == 0 {
if i == 0 {
continue;
}
out.push(string_utils::utf16_code_unit_to_char(i));

View File

@ -675,6 +675,10 @@ swf_tests! {
(as3_bitmapdata_constr, "avm2/bitmapdata_constr", 1),
(as3_bitmap_constr, "avm2/bitmap_constr", 1),
#[ignore] (as3_bitmap_properties, "avm2/bitmap_properties", 1),
(as3_string_concat_fromcharcode, "avm2/string_concat_fromcharcode", 1),
(as3_string_indexof_lastindexof, "avm2/string_indexof_lastindexof", 1),
(as3_string_match, "avm2/string_match", 1),
(as3_string_slice_substr_substring, "avm2/string_slice_substr_substring", 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,36 @@
// var s = new String("5");
// trace(s.concat());
5
// trace(s.concat(1));
51
// trace(s.concat(s));
55
// trace(s.concat(s, 1));
551
// trace(s.concat("asdf"));
5asdf
// trace(s.concat(null, s, undefined, 0, {}, ruffle_object, true));
5null5undefined0[object Object]Ruffle Test Objecttrue
/// fromCharCode
// trace(String.fromCharCode);
function Function() {}
// trace(String.fromCharCode(80));
P
// trace(String.fromCharCode(12345));
// trace(String.fromCharCode(65616));
P
// trace(String.fromCharCode(-65456));
P
// trace(String.fromCharCode(0xd801));
<EFBFBD>
// trace(String.fromCharCode("BAD"));
// String.fromCharCode(NaN)
// String.fromCharCode()
// String.fromCharCode(80, 81, 82)
PQR
// String.fromCharCode(80, 0, 82)
PR

View File

@ -0,0 +1,47 @@
package {
public class test {}
}
var ruffle_object = {s: "Ruffle Test Object"};
ruffle_object.toString = function() {
return this.s;
}
trace("// var s = new String(\"5\");");
var s = new String("5");
trace("// trace(s.concat());");
trace(s.concat());
trace("// trace(s.concat(1));");
trace(s.concat(1));
trace("// trace(s.concat(s));");
trace(s.concat(s));
trace("// trace(s.concat(s, 1));");
trace(s.concat(s, 1));
trace("// trace(s.concat(\"asdf\"));");
trace(s.concat("asdf"));
trace("// trace(s.concat(null, s, undefined, 0, {}, ruffle_object, true));");
trace(s.concat(null, s, undefined, 0, {}, ruffle_object, true));
trace("/// fromCharCode");
trace("// trace(String.fromCharCode);");
trace(String.fromCharCode);
trace("// trace(String.fromCharCode(80));");
trace(String.fromCharCode(80));
trace("// trace(String.fromCharCode(12345));");
trace(String.fromCharCode(12345));
trace("// trace(String.fromCharCode(65616));");
trace(String.fromCharCode(65616));
trace("// trace(String.fromCharCode(-65456));");
trace(String.fromCharCode(-65456));
trace("// trace(String.fromCharCode(0xd801));");
trace(String.fromCharCode(0xd801));
trace("// trace(String.fromCharCode(\"BAD\"));");
trace(String.fromCharCode("BAD"));
trace("// String.fromCharCode(NaN)");
trace(String.fromCharCode(NaN));
trace("// String.fromCharCode()");
trace(String.fromCharCode());
trace("// String.fromCharCode(80, 81, 82)");
trace(String.fromCharCode(80, 81, 82));
trace("// String.fromCharCode(80, 0, 82)");
trace(String.fromCharCode(80, 0, 82));

View File

@ -0,0 +1,20 @@
// // indexOf
// s.indexOf("a")
// s.indexOf("a", 16)
// s.indexOf("a", 14)
// s.indexOf("a", 13)
// s.indexOf("a", 0)
// s.indexOf("test")
// s.indexOf("test", 4)
// s.indexOf("test", 100)
// s.indexOf("test", -1)
// s.indexOf("test", 4294967300)
// s.indexOf("test", null)
// s.indexOf("test", undefined)
// s.indexOf("")
// s.indexOf("", 5)
// s.indexOf("", 100)
// s.indexOf()
// s.indexOf(null)
// s.indexOf(undefined)
// "hello undefined hi".indexOf(undefined)

View File

@ -0,0 +1,46 @@
package {
public class test {}
}
var s = "aaatestFOOtestaaanull";
trace("// // indexOf ");
// indexOf
trace("// s.indexOf(\"a\")");
s.indexOf("a")
trace("// s.indexOf(\"a\", 16)");
s.indexOf("a", 16)
trace("// s.indexOf(\"a\", 14)");
s.indexOf("a", 14)
trace("// s.indexOf(\"a\", 13)");
s.indexOf("a", 13)
trace("// s.indexOf(\"a\", 0)");
s.indexOf("a", 0)
trace("// s.indexOf(\"test\")");
s.indexOf("test")
trace("// s.indexOf(\"test\", 4)");
s.indexOf("test", 4)
trace("// s.indexOf(\"test\", 100)");
s.indexOf("test", 100)
trace("// s.indexOf(\"test\", -1)");
s.indexOf("test", -1)
trace("// s.indexOf(\"test\", 4294967300)");
s.indexOf("test", 4294967300)
trace("// s.indexOf(\"test\", null)");
s.indexOf("test", null)
trace("// s.indexOf(\"test\", undefined)");
s.indexOf("test", undefined)
trace("// s.indexOf(\"\")");
s.indexOf("")
trace("// s.indexOf(\"\", 5)");
s.indexOf("", 5)
trace("// s.indexOf(\"\", 100)");
s.indexOf("", 100)
trace("// s.indexOf()");
s.indexOf()
trace("// s.indexOf(null)");
s.indexOf(null)
trace("// s.indexOf(undefined)");
s.indexOf(undefined)
trace("// \"hello undefined hi\".indexOf(undefined)");
"hello undefined hi".indexOf(undefined)

View File

@ -0,0 +1,41 @@
// var str:String = new String("matchablematmatmat");
// var ret:Array = str.match("mat");
// trace(ret);
mat
// var re = new RegExp("MA*T|a[a-z]*e","i");
// re.lastIndex = 3;
// trace(str.match(re), re.lastIndex);
mat 3
// trace(str.match(re), re.lastIndex);
mat 3
// trace(str.match(re), re.lastIndex);
mat 3
// trace(str.match(new RegExp("MA*T|a[a-z]*e","i")));
mat
// trace(str.match(new RegExp("ma*t|a[a-z]*e","")));
mat
// trace(str.match(new RegExp("ma*t|a[a-z]*e","g")));
mat,able,mat,mat,mat
// trace(str.match(new RegExp("notmatch", "g")));
// var subject:String = "AAA";
// trace(subject.match(/(((((((((((((((((((a*)(abc|b))))))))))))))))))*.)*(...)*/g));
AAA
// trace(subject.match(/((((((((((((((((((d|.*)))))))))))))))))*.)*(...)*/g));
AAA
// trace(subject.match(/((((((((((((((((((a+)*))))))))))))))))*.)*(...)*/g));
AAA
// trace(subject.match("((((((((((((((((((a+)*))))))))))))))))*.)*(...)*"));
AAA,A,,,,,,,,,,,,,,,,,,
// trace(subject.match("((((((((((((((((((a+)*))))))))))))))))*.)*(...)*"));
AAA,A,,,,,,,,,,,,,,,,,,
// trace(subject.match("(A)(A)"));
AA,A,A
// trace(subject.match("AAA"));
AAA
// trace(subject.match("AA"));
AA
// trace(subject.match("A"));
A
// trace(str.match(ruffle_object));
null

View File

@ -0,0 +1,62 @@
package {
public class test {}
}
var ruffle_object = {s: "Ruffle Test Object"};
ruffle_object.toString = function() {
return this.s;
}
//Match tests
trace("// var str:String = new String(\"matchablematmatmat\");");
var str:String = new String("matchablematmatmat");
trace("// var ret:Array = str.match(\"mat\");");
var ret:Array = str.match("mat");
trace("// trace(ret);");
trace(ret);
trace("// var re = new RegExp(\"MA*T|a[a-z]*e\",\"i\");");
var re = new RegExp("MA*T|a[a-z]*e","i");
trace("// re.lastIndex = 3;");
re.lastIndex = 3;
trace("// trace(str.match(re), re.lastIndex);");
trace(str.match(re), re.lastIndex);
trace("// trace(str.match(re), re.lastIndex);");
trace(str.match(re), re.lastIndex);
trace("// trace(str.match(re), re.lastIndex);");
trace(str.match(re), re.lastIndex);
trace("// trace(str.match(new RegExp(\"MA*T|a[a-z]*e\",\"i\")));");
trace(str.match(new RegExp("MA*T|a[a-z]*e","i")));
trace("// trace(str.match(new RegExp(\"ma*t|a[a-z]*e\",\"\")));");
trace(str.match(new RegExp("ma*t|a[a-z]*e","")));
trace("// trace(str.match(new RegExp(\"ma*t|a[a-z]*e\",\"g\")));");
trace(str.match(new RegExp("ma*t|a[a-z]*e","g")));
trace("// trace(str.match(new RegExp(\"notmatch\", \"g\")));");
trace(str.match(new RegExp("notmatch", "g")));
trace("// var subject:String = \"AAA\";");
var subject:String = "AAA";
trace("// trace(subject.match(/(((((((((((((((((((a*)(abc|b))))))))))))))))))*.)*(...)*/g));");
trace(subject.match(/(((((((((((((((((((a*)(abc|b))))))))))))))))))*.)*(...)*/g));
trace("// trace(subject.match(/((((((((((((((((((d|.*)))))))))))))))))*.)*(...)*/g));");
trace(subject.match(/((((((((((((((((((d|.*)))))))))))))))))*.)*(...)*/g));
trace("// trace(subject.match(/((((((((((((((((((a+)*))))))))))))))))*.)*(...)*/g));");
trace(subject.match(/((((((((((((((((((a+)*))))))))))))))))*.)*(...)*/g));
trace("// trace(subject.match(\"((((((((((((((((((a+)*))))))))))))))))*.)*(...)*\"));");
trace(subject.match("((((((((((((((((((a+)*))))))))))))))))*.)*(...)*"));
trace("// trace(subject.match(\"((((((((((((((((((a+)*))))))))))))))))*.)*(...)*\"));");
trace(subject.match("((((((((((((((((((a+)*))))))))))))))))*.)*(...)*"));
trace("// trace(subject.match(\"(A)(A)\"));");
trace(subject.match("(A)(A)"));
trace("// trace(subject.match(\"AAA\"));");
trace(subject.match("AAA"));
trace("// trace(subject.match(\"AA\"));");
trace(subject.match("AA"));
trace("// trace(subject.match(\"A\"));");
trace(subject.match("A"));
trace("// trace(str.match(ruffle_object));");
trace(str.match(ruffle_object));

Binary file not shown.

View File

@ -0,0 +1,169 @@
/// slice
// trace("123456789".slice(0, 9));
123456789
// trace("123456789".slice(0, 0));
// trace("123456789".slice(9, 0));
// trace("123456789".slice(0, -1));
12345678
// trace("123456789".slice(-6, -1));
45678
// var s = new String("");
// trace( typeof s.slice(), s.slice());
string
// trace( s.slice(false, true));
// trace( s.slice(25, 29));
// var s = new String("123456789");
// trace( 1, typeof s.slice(), s.slice());
1 string 123456789
// trace( 2, s.slice(false, true));
2 1
// trace( 3, s.slice(4, -3));
3 56
// trace( 4, s.slice(25, 29));
4
// trace( 5, s.slice(-5, 9));
5 56789
// trace( 6, s.slice(2, NaN));
6
// trace( 7, s.slice(NaN, 2));
7 12
// trace( 8, s.slice(2, undefined));
8
// trace( 9, s.slice(undefined, 2));
9 12
// trace( 10, s.slice(-0.01,0));
10
// trace( 11, s.slice(s.length, s.length));
11
// trace( 12, s.slice(s.length+1, 0));
12
// trace( 13, s.slice(Infinity, 5));
13
// trace( 14, s.slice(5, Infinity));
14 6789
// trace( 15, s.slice(Infinity, Infinity));
15
// trace( 16, s.slice(-Infinity, -Infinity));
16
// trace( 17, s.slice(-Infinity, Infinity));
17 123456789
// trace( 18, s.slice(Infinity, -Infinity));
18
// trace( 19, s.slice(NaN, Infinity));
19 123456789
// trace( 20, s.slice(Infinity, NaN));
20
// trace( 21, s.slice(NaN, -Infinity));
21
// trace( 22, s.slice(-Infinity, NaN));
22
/// substr tests
// var s = new String("");
// trace( typeof s.substr(), s.substr());
string
// trace( s.substr(false, true));
// trace( s.substr(25, 29));
// var s = new String("123456789");
// trace( 1, typeof s.substr(), s.substr());
1 string 123456789
// trace( 2, s.substr(false, true));
2 1
// trace( 3, s.substr(4, -3));
3
// trace( 4, s.substr(25, 29));
4
// trace( 5, s.substr(-5, 9));
5 56789
// trace( 6, s.substr(2, NaN));
6
// trace( 7, s.substr(NaN, 2));
7 12
// trace( 8, s.substr(2, undefined));
8
// trace( 9, s.substr(undefined, 2));
9 12
// trace( 10, s.substr(-0.01,0));
10
// trace( 11, s.substr(s.length, s.length));
11
// trace( 12, s.substr(s.length+1, 0));
12
// trace( 13, s.substr(Infinity, 5));
13
// trace( 14, s.substr(5, Infinity));
14 6789
// trace( 15, s.substr(Infinity, Infinity));
15
// trace( 16, s.substr(-Infinity, -Infinity));
16
// trace( 17, s.substr(-Infinity, Infinity));
17 123456789
// trace( 18, s.substr(Infinity, -Infinity));
18
// trace( 19, s.substr(NaN, Infinity));
19 123456789
// trace( 20, s.substr(Infinity, NaN));
20
// trace( 21, s.substr(NaN, -Infinity));
21
// trace( 22, s.substr(-Infinity, NaN));
22
/// substring tests
// var s = new String("");
// trace( typeof s.substring(), s.substring());
string
// trace( s.substring(false, true));
// trace( s.substring(25, 29));
// var s = new String("123456789");
// trace( 1, typeof s.substring(), s.substring());
1 string 123456789
// trace( 2, s.substring(false, true));
2 1
// trace( 3, s.substring(4, -3));
3 1234
// trace( 4, s.substring(25, 29));
4
// trace( 5, s.substring(-5, 9));
5 123456789
// trace( 6, s.substring(2, NaN));
6 12
// trace( 7, s.substring(NaN, 2));
7 12
// trace( 8, s.substring(2, undefined));
8 12
// trace( 9, s.substring(undefined, 2));
9 12
// trace( 10, s.substring(-0.01,0));
10
// trace( 11, s.substring(s.length, s.length));
11
// trace( 12, s.substring(s.length+1, 0));
12 123456789
// trace( 13, s.substring(Infinity, 5));
13 6789
// trace( 14, s.substring(5, Infinity));
14 6789
// trace( 15, s.substring(Infinity, Infinity));
15
// trace( 16, s.substring(-Infinity, -Infinity));
16
// trace( 17, s.substring(-Infinity, Infinity));
17 123456789
// trace( 18, s.substring(Infinity, -Infinity));
18 123456789
// trace( 19, s.substring(NaN, Infinity));
19 123456789
// trace( 20, s.substring(Infinity, NaN));
20 123456789
// trace( 21, s.substring(NaN, -Infinity));
21
// trace( 22, s.substring(-Infinity, NaN));
22

View File

@ -0,0 +1,187 @@
package {
public class test {}
}
/// slice tests
trace("/// slice");
trace("// trace(\"123456789\".slice(0, 9));");
trace("123456789".slice(0, 9));
trace("// trace(\"123456789\".slice(0, 0));");
trace("123456789".slice(0, 0));
trace("// trace(\"123456789\".slice(9, 0));");
trace("123456789".slice(9, 0));
trace("// trace(\"123456789\".slice(0, -1));");
trace("123456789".slice(0, -1));
trace("// trace(\"123456789\".slice(-6, -1));");
trace("123456789".slice(-6, -1));
trace("// var s = new String(\"\");");
var s = new String("");
trace("// trace( typeof s.slice(), s.slice());");
trace( typeof s.slice(), s.slice());
trace("// trace( s.slice(false, true));");
trace( s.slice(false, true));
trace("// trace( s.slice(25, 29));");
trace( s.slice(25, 29));
trace("// var s = new String(\"123456789\");");
var s = new String("123456789");
trace("// trace( 1, typeof s.slice(), s.slice());");
trace( 1, typeof s.slice(), s.slice());
trace("// trace( 2, s.slice(false, true));");
trace( 2, s.slice(false, true));
trace("// trace( 3, s.slice(4, -3));");
trace( 3, s.slice(4, -3));
trace("// trace( 4, s.slice(25, 29));");
trace( 4, s.slice(25, 29));
trace("// trace( 5, s.slice(-5, 9));");
trace( 5, s.slice(-5, 9));
trace("// trace( 6, s.slice(2, NaN));");
trace( 6, s.slice(2, NaN));
trace("// trace( 7, s.slice(NaN, 2));");
trace( 7, s.slice(NaN, 2));
trace("// trace( 8, s.slice(2, undefined));");
trace( 8, s.slice(2, undefined));
trace("// trace( 9, s.slice(undefined, 2));");
trace( 9, s.slice(undefined, 2));
trace("// trace( 10, s.slice(-0.01,0));");
trace( 10, s.slice(-0.01,0));
trace("// trace( 11, s.slice(s.length, s.length));");
trace( 11, s.slice(s.length, s.length));
trace("// trace( 12, s.slice(s.length+1, 0));");
trace( 12, s.slice(s.length+1, 0));
trace("// trace( 13, s.slice(Infinity, 5));");
trace( 13, s.slice(Infinity, 5));
trace("// trace( 14, s.slice(5, Infinity));");
trace( 14, s.slice(5, Infinity));
trace("// trace( 15, s.slice(Infinity, Infinity));");
trace( 15, s.slice(Infinity, Infinity));
trace("// trace( 16, s.slice(-Infinity, -Infinity));");
trace( 16, s.slice(-Infinity, -Infinity));
trace("// trace( 17, s.slice(-Infinity, Infinity));");
trace( 17, s.slice(-Infinity, Infinity));
trace("// trace( 18, s.slice(Infinity, -Infinity));");
trace( 18, s.slice(Infinity, -Infinity));
trace("// trace( 19, s.slice(NaN, Infinity));");
trace( 19, s.slice(NaN, Infinity));
trace("// trace( 20, s.slice(Infinity, NaN));");
trace( 20, s.slice(Infinity, NaN));
trace("// trace( 21, s.slice(NaN, -Infinity));");
trace( 21, s.slice(NaN, -Infinity));
trace("// trace( 22, s.slice(-Infinity, NaN));");
trace( 22, s.slice(-Infinity, NaN));
trace("/// substr tests");
trace("// var s = new String(\"\");");
var s = new String("");
trace("// trace( typeof s.substr(), s.substr());");
trace( typeof s.substr(), s.substr());
trace("// trace( s.substr(false, true));");
trace( s.substr(false, true));
trace("// trace( s.substr(25, 29));");
trace( s.substr(25, 29));
trace("// var s = new String(\"123456789\");");
var s = new String("123456789");
trace("// trace( 1, typeof s.substr(), s.substr());");
trace( 1, typeof s.substr(), s.substr());
trace("// trace( 2, s.substr(false, true));");
trace( 2, s.substr(false, true));
trace("// trace( 3, s.substr(4, -3));");
trace( 3, s.substr(4, -3));
trace("// trace( 4, s.substr(25, 29));");
trace( 4, s.substr(25, 29));
trace("// trace( 5, s.substr(-5, 9));");
trace( 5, s.substr(-5, 9));
trace("// trace( 6, s.substr(2, NaN));");
trace( 6, s.substr(2, NaN));
trace("// trace( 7, s.substr(NaN, 2));");
trace( 7, s.substr(NaN, 2));
trace("// trace( 8, s.substr(2, undefined));");
trace( 8, s.substr(2, undefined));
trace("// trace( 9, s.substr(undefined, 2));");
trace( 9, s.substr(undefined, 2));
trace("// trace( 10, s.substr(-0.01,0));");
trace( 10, s.substr(-0.01,0));
trace("// trace( 11, s.substr(s.length, s.length));");
trace( 11, s.substr(s.length, s.length));
trace("// trace( 12, s.substr(s.length+1, 0));");
trace( 12, s.substr(s.length+1, 0));
trace("// trace( 13, s.substr(Infinity, 5));");
trace( 13, s.substr(Infinity, 5));
trace("// trace( 14, s.substr(5, Infinity));");
trace( 14, s.substr(5, Infinity));
trace("// trace( 15, s.substr(Infinity, Infinity));");
trace( 15, s.substr(Infinity, Infinity));
trace("// trace( 16, s.substr(-Infinity, -Infinity));");
trace( 16, s.substr(-Infinity, -Infinity));
trace("// trace( 17, s.substr(-Infinity, Infinity));");
trace( 17, s.substr(-Infinity, Infinity));
trace("// trace( 18, s.substr(Infinity, -Infinity));");
trace( 18, s.substr(Infinity, -Infinity));
trace("// trace( 19, s.substr(NaN, Infinity));");
trace( 19, s.substr(NaN, Infinity));
trace("// trace( 20, s.substr(Infinity, NaN));");
trace( 20, s.substr(Infinity, NaN));
trace("// trace( 21, s.substr(NaN, -Infinity));");
trace( 21, s.substr(NaN, -Infinity));
trace("// trace( 22, s.substr(-Infinity, NaN));");
trace( 22, s.substr(-Infinity, NaN));
trace("/// substring tests");
trace("// var s = new String(\"\");");
var s = new String("");
trace("// trace( typeof s.substring(), s.substring());");
trace( typeof s.substring(), s.substring());
trace("// trace( s.substring(false, true));");
trace( s.substring(false, true));
trace("// trace( s.substring(25, 29));");
trace( s.substring(25, 29));
trace("// var s = new String(\"123456789\");");
var s = new String("123456789");
trace("// trace( 1, typeof s.substring(), s.substring());");
trace( 1, typeof s.substring(), s.substring());
trace("// trace( 2, s.substring(false, true));");
trace( 2, s.substring(false, true));
trace("// trace( 3, s.substring(4, -3));");
trace( 3, s.substring(4, -3));
trace("// trace( 4, s.substring(25, 29));");
trace( 4, s.substring(25, 29));
trace("// trace( 5, s.substring(-5, 9));");
trace( 5, s.substring(-5, 9));
trace("// trace( 6, s.substring(2, NaN));");
trace( 6, s.substring(2, NaN));
trace("// trace( 7, s.substring(NaN, 2));");
trace( 7, s.substring(NaN, 2));
trace("// trace( 8, s.substring(2, undefined));");
trace( 8, s.substring(2, undefined));
trace("// trace( 9, s.substring(undefined, 2));");
trace( 9, s.substring(undefined, 2));
trace("// trace( 10, s.substring(-0.01,0));");
trace( 10, s.substring(-0.01,0));
trace("// trace( 11, s.substring(s.length, s.length));");
trace( 11, s.substring(s.length, s.length));
trace("// trace( 12, s.substring(s.length+1, 0));");
trace( 12, s.substring(s.length+1, 0));
trace("// trace( 13, s.substring(Infinity, 5));");
trace( 13, s.substring(Infinity, 5));
trace("// trace( 14, s.substring(5, Infinity));");
trace( 14, s.substring(5, Infinity));
trace("// trace( 15, s.substring(Infinity, Infinity));");
trace( 15, s.substring(Infinity, Infinity));
trace("// trace( 16, s.substring(-Infinity, -Infinity));");
trace( 16, s.substring(-Infinity, -Infinity));
trace("// trace( 17, s.substring(-Infinity, Infinity));");
trace( 17, s.substring(-Infinity, Infinity));
trace("// trace( 18, s.substring(Infinity, -Infinity));");
trace( 18, s.substring(Infinity, -Infinity));
trace("// trace( 19, s.substring(NaN, Infinity));");
trace( 19, s.substring(NaN, Infinity));
trace("// trace( 20, s.substring(Infinity, NaN));");
trace( 20, s.substring(Infinity, NaN));
trace("// trace( 21, s.substring(NaN, -Infinity));");
trace( 21, s.substring(NaN, -Infinity));
trace("// trace( 22, s.substring(-Infinity, NaN));");
trace( 22, s.substring(-Infinity, NaN));