File indexing completed on 2024-04-28 15:28:38

0001 // invalid regexp
0002 shouldThrow("/(/");
0003 // should not crash
0004 shouldThrow("''.match('(')");
0005 
0006 shouldBe("(new RegExp()).source", "''");
0007 shouldBe("Boolean(new RegExp())", "true");
0008 shouldBeTrue("isNaN(Number(new RegExp()))");
0009 
0010 // RegExp constructor called as a function
0011 shouldBe("RegExp(/x/).source", "'x'");
0012 //shouldBe("RegExp(/x/, 'g').source", "'/x/'"); // can't supply flags when constructing one RegExp from another, says mozilla
0013 shouldBe("RegExp('x', 'g').global", "true");
0014 shouldBe("RegExp('x').source", "'x'");
0015 
0016 // RegExp constructor
0017 shouldBe("new RegExp('x').source", "'x'");
0018 
0019 var ri = /a/i;
0020 var rm = /a/m;
0021 var rg = /a/g;
0022 
0023 shouldBeFalse("(/a/).global");
0024 shouldBe("typeof (/a/).global", "'boolean'");
0025 shouldBeTrue("rg.global");
0026 shouldBeFalse("(/a/).ignoreCase");
0027 shouldBeTrue("ri.ignoreCase");
0028 shouldBeFalse("(/a/).multiline");
0029 shouldBeTrue("rm.multiline");
0030 shouldBe("rg.toString()", "'/a/g'");
0031 shouldBe("ri.toString()", "'/a/i'");
0032 shouldBe("rm.toString()", "'/a/m'");
0033 
0034 // check properety attributes
0035 rg.global = false;
0036 shouldBeTrue("rg.global");
0037 ri.ignoreCase = false;
0038 shouldBeTrue("ri.ignoreCase");
0039 rm.multiline = false;
0040 shouldBeTrue("rm.multiline");
0041 
0042 shouldBe("Boolean(/a/.test)", "true");
0043 shouldBe("/(b)c/.exec('abcd').toString()", "\"bc,b\"");
0044 shouldBe("/(b)c/.exec('abcd').length", "2");
0045 shouldBe("/(b)c/.exec('abcd').index", "1");
0046 shouldBe("/(b)c/.exec('abcd').input", "'abcd'");
0047 
0048 var rs = /foo/;
0049 rs.source = "bar";
0050 shouldBe("rs.source", "'foo'");
0051 
0052 shouldBe("var r = new RegExp(/x/); r.global=true; r.lastIndex = -1; typeof r.test('a')", "'boolean'");
0053 
0054 shouldBe("'abcdefghi'.match(/(abc)def(ghi)/).toString()","'abcdefghi,abc,ghi'");
0055 shouldBe("/(abc)def(ghi)/.exec('abcdefghi').toString()","'abcdefghi,abc,ghi'");
0056 shouldBe("RegExp.$1","'abc'");
0057 shouldBe("with(RegExp) { $1 }","'abc'");
0058 shouldBe("RegExp.$2","'ghi'");
0059 shouldBe("RegExp.$3","''");
0060 
0061 shouldBe("'abcdefghi'.match(/(a(b(c(d(e)f)g)h)i)/).toString()", "'abcdefghi,abcdefghi,bcdefgh,cdefg,def,e'");
0062 shouldBe("RegExp.$1","'abcdefghi'");
0063 shouldBe("RegExp.$2","'bcdefgh'");
0064 shouldBe("RegExp.$3","'cdefg'");
0065 shouldBe("RegExp.$4","'def'");
0066 shouldBe("RegExp.$5","'e'");
0067 shouldBe("RegExp.$6","''");
0068 
0069 shouldBe("'(100px 200px 150px 15px)'.match(/\\((\\d+)(px)* (\\d+)(px)* (\\d+)(px)* (\\d+)(px)*\\)/).toString()","'(100px 200px 150px 15px),100,px,200,px,150,px,15,px'");
0070 shouldBe("RegExp.$1","'100'");
0071 shouldBe("RegExp.$3","'200'");
0072 shouldBe("RegExp.$5","'150'");
0073 shouldBe("RegExp.$7","'15'");
0074 shouldBe("''.match(/\((\\d+)(px)* (\\d+)(px)* (\\d+)(px)* (\\d+)(px)*\)/)","null");
0075 shouldBe("RegExp.$1","''");
0076 shouldBe("RegExp.$3","''");
0077 shouldBe("RegExp.$5","''");
0078 shouldBe("RegExp.$7","''");
0079 
0080 var invalidChars = /[^@\.\w]/g; // #47092
0081 shouldBe("'faure@kde.org'.match(invalidChars) == null", "true");
0082 shouldBe("'faure-kde@kde.org'.match(invalidChars) == null", "false");
0083 
0084 shouldBe("'test1test2'.replace('test','X')","'X1test2'");
0085 shouldBe("'test1test2'.replace(/\\d/,'X')","'testXtest2'");
0086 shouldBe("'1test2test3'.replace(/\\d/,'')","'test2test3'");
0087 shouldBe("'test1test2'.replace(/test/g,'X')","'X1X2'");
0088 shouldBe("'1test2test3'.replace(/\\d/g,'')","'testtest'");
0089 shouldBe("'1test2test3'.replace(/x/g,'')","'1test2test3'");
0090 shouldBe("'test1test2'.replace(/(te)(st)/g,'$2$1')","'stte1stte2'");
0091 shouldBe("'foo+bar'.replace(/\\+/g,'%2B')", "'foo%2Bbar'");
0092 var caught = false; try { new RegExp("+"); } catch (e) { caught = true; }
0093 shouldBeTrue("caught"); // #40435
0094 var caught = false; try { new RegExp("]"); } catch (e) { caught = true; }
0095 shouldBeTrue("caught"); // test 89 of Acid3
0096 var caught = false; try { new RegExp("\\]"); } catch (e) { caught = true; }
0097 shouldBeFalse("caught");
0098 shouldBe("'foo'.replace(/z?/g,'x')", "'xfxoxox'");
0099 shouldBe("'test test'.replace(/\\s*/g,'')","'testtest'"); // #50985
0100 shouldBe("'abc$%@'.replace(/[^0-9a-z]*/gi,'')","'abc'"); // #50848
0101 shouldBe("'ab'.replace(/[^\\d\\.]*/gi,'')","''"); // #75292
0102 shouldBe("'1ab'.replace(/[^\\d\\.]*/gi,'')","'1'"); // #75292
0103 
0104 // Acid3 showed a difference to the Perl regex behavior
0105 var x = /(\3)(\1)(a)/.exec('cat'); // the \3 matches the empty string, qv. ES3:15.10.2.9
0106 shouldBeTrue("!!x"); // or, "/(\\3)(\\1)(a)/ failed to match 'cat'");
0107 shouldBe("x.length", "4"); // or, "/(\\3)(\\1)(a)/ failed to return four components");
0108 shouldBe("x[0]", "'a'"); // or, "/(\\3)(\\1)(a)/ failed to find 'a' in 'cat'");
0109 shouldBe("x[1]", "''"); // or, "/(\\3)(\\1)(a)/ failed to find '' in 'cat' as first part");
0110 shouldBe("x[2]", "''"); // or, "/(\\3)(\\1)(a)/ failed to find '' in 'cat' as second part");
0111 shouldBe("x[3]", "'a'"); // or, "/(\\3)(\\1)(a)/ failed to find 'a' in 'cat' as third part");
0112 
0113 // Empty character class matches nothing
0114 var ok = false;
0115 try { ok = (/[]/.exec('') == null); } catch (e) { }
0116 shouldBeTrue("ok");
0117 
0118 // [^] matches anything
0119 ok = false;
0120 try { ok = (/[^]/.exec('x') != null); } catch (e) { }
0121 shouldBeTrue("ok");
0122 
0123 shouldBe("'1test2test3blah'.split(/test/).toString()","'1,2,3blah'");
0124 var reg = /(\d\d )/g;
0125 var str = new String('98 76 blah');
0126 shouldBe("reg.exec(str).toString()","'98 ,98 '");
0127 shouldBe("reg.lastIndex","3");
0128 shouldBe("RegExp.$1","'98 '");
0129 shouldBe("RegExp.$2","''");
0130 
0131 shouldBe("reg.exec(str).toString()","'76 ,76 '");
0132 shouldBe("reg.lastIndex","6");
0133 shouldBe("RegExp.$1","'76 '");
0134 shouldBe("RegExp.$2","''");
0135 
0136 shouldBe("reg.exec(str)","null");
0137 shouldBe("reg.lastIndex","0");
0138 
0139 // http://www.devguru.com/Technologies/ecmascript/quickref/regexp_lastindex.html
0140 // Looks IE-only though
0141 //shouldBe( "var re=/ships*\s/; re.exec('the hardships of traveling'); re.lastIndex", "14" );
0142 //shouldBe( "var re=/ships*\s/; str='the hardships of traveling'; re.exec(str); re.exec(str); re.lastIndex", "0" );
0143 
0144 // http://devedge.netscape.com/library/manuals/2000/javascript/1.5/guide/regexp.html
0145 shouldBe( "myRe=/d(b+)d/g; myArray = myRe.exec('cdbbdbsbz'); myRe.lastIndex", "5" );
0146 
0147 reg = /^u/i;
0148 shouldBeTrue("reg.ignoreCase == true");
0149 shouldBeTrue("reg.global === false");
0150 shouldBeTrue("reg.multiline === false");
0151 shouldBeTrue("reg.test('UGO')");
0152 
0153 // regexp are writable ?
0154 shouldBe("reg.x = 1; reg.x", "1");
0155 // shared data ?
0156 shouldBe("var r2 = reg; r2.x = 2; reg.x", "2");
0157 
0158 var str = new String("For more information, see Chapter 3.4.5.1");
0159 re = /(chapter \d+(\.\d)*)/i;
0160 // This returns the array containing Chapter 3.4.5.1,Chapter 3.4.5.1,.1
0161 // 'Chapter 3.4.5.1' is the first match and the first value remembered from (Chapter \d+(\.\d)*).
0162 // '.1' is the second value remembered from (\.\d)
0163 shouldBe("str.match(re).toString()","'Chapter 3.4.5.1,Chapter 3.4.5.1,.1'");
0164 
0165 str = "abcDdcba";
0166 // The returned array contains D, d.
0167 shouldBe("str.match(/d/gi).toString()","'D,d'");
0168 
0169 // unicode escape sequence
0170 shouldBe("/\\u0061/.source", "'\\\\u0061'");
0171 shouldBe("'abc'.match(/\\u0062/).toString()", "'b'");
0172 
0173 shouldBe("Object.prototype.toString.apply(RegExp.prototype)",
0174          "'[object RegExp]'");
0175 
0176 // not sure what this should return. most importantly
0177 // it doesn't throw an exception
0178 shouldBe("typeof RegExp.prototype.toString()", "'string'");
0179 
0180 
0181 // Tests for unicode handling inside strings and regexps..
0182 str = "\u304f";
0183 shouldBe("str.replace(/o/ig,'aaa')", "str");
0184 shouldBe("'PASS'.replace(/[\\u0100-\\uFFFF]/g, '?')", "'PASS'");
0185 shouldBe("'\uDBFF\uDFFD'.replace(/\uDBFF/, 'A').replace(/\uDFFD/, 'B')", "'AB'");
0186 shouldBe("'\uDBFF\uDFFD'.replace(/\\uDBFF/, 'A').replace(/\\uDFFD/, 'B')", "'AB'");
0187 shouldBe("'\uDBFF\uDFFD'.replace(/\\W/, '*')", "'*\uDFFD'");
0188 
0189 myName   = "\u041C\u0430\u043A\u0441\u0438\u043C\u0020\u041E"; // Maksim O in Cyrillic
0190 
0191 //If one get rids of the 'im', should get 'Maks O' back
0192 nickName = myName.replace(/\u0438\u043C/, '');
0193 shouldBe("nickName", "'\u041C\u0430\u043A\u0441\u0020\u041E'");
0194 
0195 //If one gets rid of the ' O', should get Maks back
0196 shouldBe("nickName.replace(/ \u041E/,'')", "'\u041C\u0430\u043A\u0441'");
0197  
0198 //Some checks for index handling with unicode-encoded stuff...
0199 multi = "\u0430\u0431\u0432\u0430\u0431\u0432\u0430\u0431\u0432"; //abv 3 times in Cyrillic
0200 matches = multi.match(/\u0430\u0431\u0432/g); //match abv...
0201 shouldBe("matches.length", "3");
0202 shouldBe("matches[0]", "'\u0430\u0431\u0432'");
0203 shouldBe("matches[1]", "'\u0430\u0431\u0432'");
0204 shouldBe("matches[2]", "'\u0430\u0431\u0432'");
0205 
0206 // null bytes handled safely
0207 shouldBe("'a\\u0000b'.search(/\\u0000b/)", "1");
0208 
0209 // escaped pattern characters
0210 shouldBe("'abc'.search(/\\u005Ea/)", "-1"); // unlike /^a/
0211 shouldBe("'abc'.search(/c\\u0024/)", "-1"); // unlike /c$/
0212 shouldBe("'a\\\\bc'.search(/\\u005C/)", "1"); // Unlike /\/
0213 shouldBe("'abc'.search(/b\\u002B/)", "-1"); // unlike /b+/
0214 shouldBe("'abc'.search(/a\\u002Ec/)", "-1"); // unlike /a.c/
0215 shouldBe("'abc'.search(/ax\\u002A/)", "-1"); // unlike /ax*/
0216 shouldBe("'abc'.search(/ab\\u002B/)", "-1"); // unlike /ab+/
0217 shouldBe("'abc'.search(/ax\\u003F/)", "-1"); // unlike /ax?/
0218 shouldBe("'abc'.search(/b\\u007Cx/)", "-1"); // unlike /b|x/
0219 
0220 // incomplete, non-standard \u sequences we model the IE behavior here
0221 // which always treats e.g. \u9 as u9. Mozilla treats (\u9) as (u9)
0222 // but just \u9 like \u0009.
0223 shouldBe("'abc'.replace(/\\u0062/, 'x');", "'axc'");
0224 shouldBe("'au062c'.replace(/\\u062/, 'x');", "'axc'");
0225 shouldBe("'au62c'.replace(/\\u62/, 'x');", "'axc'");
0226 shouldBe("'au2c'.replace(/\\u2/, 'x');", "'axc'");
0227 shouldBe("'auc'.replace(/\\u/, 'x');", "'axc'");
0228 shouldBe("'au62c'.replace(/[\\u62]+/, 'x');", "'axc'");
0229 shouldBe("'au62wc'.search(/\\u62w/);", "1");
0230 shouldBe("'au62c'.search(/(\\u62)/);", "1");
0231 shouldBe("'au62c'.search(/(\\u62)/);", "1");
0232 shouldBe("'au62bc'.search(/(\\u62|q)/);", "1");
0233 
0234 var s = "*";
0235 while (s.length < 100000)
0236     s = s + s;
0237 var re = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;
0238 
0239 shouldThrow('("<scr" + s + "/scr>").match(re);'); // ... and not crash
0240 
0241 // proper .lastIndex updating for .test
0242 var re = /x/g;
0243 var s = "x";
0244 shouldBeFalse("re.test(s) && re.test(s)");
0245 
0246 // Crash test for reentrancy
0247 var re = 0;
0248 function callback(str) {
0249     return crashme("lorem");
0250 }
0251 function crashme(txt) {
0252     if (!re) re = new RegExp('lorem (ipsum)',"gm");
0253     return txt.replace(re, callback);
0254 }
0255 crashme("lorem ipsum");
0256 
0257 debug("Done.");