diff options
Diffstat (limited to 'js/src/tests/ecma_5/RegExp')
-rw-r--r-- | js/src/tests/ecma_5/RegExp/15.10.5-01.js | 21 | ||||
-rw-r--r-- | js/src/tests/ecma_5/RegExp/15.10.7.5-01.js | 71 | ||||
-rw-r--r-- | js/src/tests/ecma_5/RegExp/7.8.5-01.js | 35 | ||||
-rw-r--r-- | js/src/tests/ecma_5/RegExp/browser.js | 0 | ||||
-rw-r--r-- | js/src/tests/ecma_5/RegExp/empty-lookahead.js | 8 | ||||
-rw-r--r-- | js/src/tests/ecma_5/RegExp/exec-lastIndex-ToInteger.js | 36 | ||||
-rw-r--r-- | js/src/tests/ecma_5/RegExp/exec.js | 240 | ||||
-rw-r--r-- | js/src/tests/ecma_5/RegExp/instance-property-storage-introspection.js | 131 | ||||
-rw-r--r-- | js/src/tests/ecma_5/RegExp/regexp-space-character-class.js | 45 | ||||
-rw-r--r-- | js/src/tests/ecma_5/RegExp/regress-429241.js | 200 | ||||
-rw-r--r-- | js/src/tests/ecma_5/RegExp/regress-576828.js | 8 | ||||
-rw-r--r-- | js/src/tests/ecma_5/RegExp/regress-613820-1.js | 9 | ||||
-rw-r--r-- | js/src/tests/ecma_5/RegExp/regress-613820-2.js | 9 | ||||
-rw-r--r-- | js/src/tests/ecma_5/RegExp/regress-613820-3.js | 9 | ||||
-rw-r--r-- | js/src/tests/ecma_5/RegExp/regress-617935.js | 42 | ||||
-rw-r--r-- | js/src/tests/ecma_5/RegExp/shell.js | 21 |
16 files changed, 885 insertions, 0 deletions
diff --git a/js/src/tests/ecma_5/RegExp/15.10.5-01.js b/js/src/tests/ecma_5/RegExp/15.10.5-01.js new file mode 100644 index 000000000..2f8429218 --- /dev/null +++ b/js/src/tests/ecma_5/RegExp/15.10.5-01.js @@ -0,0 +1,21 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var BUGNUMBER = 614603; +var summary = "RegExp.length"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +assertEq(RegExp.length, 2); +assertEq(/a/.constructor.length, 2); + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/ecma_5/RegExp/15.10.7.5-01.js b/js/src/tests/ecma_5/RegExp/15.10.7.5-01.js new file mode 100644 index 000000000..ab9d071a7 --- /dev/null +++ b/js/src/tests/ecma_5/RegExp/15.10.7.5-01.js @@ -0,0 +1,71 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var BUGNUMBER = 465199; +var summary = "RegExp lastIndex property set should not coerce type to number"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var called = false; +var o = { valueOf: function() { called = true; return 1; } }; +var r = /a/g; +var desc, m; + +assertEq(r.lastIndex, 0); + +desc = Object.getOwnPropertyDescriptor(r, "lastIndex"); +assertEq(desc.enumerable, false); +assertEq(desc.configurable, false); +assertEq(desc.value, 0); +assertEq(desc.writable, true); + +r.lastIndex = o; + +assertEq(r.lastIndex, o); + +desc = Object.getOwnPropertyDescriptor(r, "lastIndex"); +assertEq(desc.enumerable, false); +assertEq(desc.configurable, false); +assertEq(desc.value, o); +assertEq(desc.writable, true); + +assertEq(called, false); +assertEq(r.exec("aaaa").length, 1); +assertEq(called, true); +assertEq(r.lastIndex, 2); + +desc = Object.getOwnPropertyDescriptor(r, "lastIndex"); +assertEq(desc.enumerable, false); +assertEq(desc.configurable, false); +assertEq(desc.value, 2); +assertEq(desc.writable, true); + + +r.lastIndex = -0.2; +assertEq(r.lastIndex, -0.2); + +m = r.exec("aaaa"); +assertEq(Array.isArray(m), true); +assertEq(m.length, 1); +assertEq(m[0], "a"); +assertEq(r.lastIndex, 1); + +m = r.exec("aaaa"); +assertEq(Array.isArray(m), true); +assertEq(m.length, 1); +assertEq(m[0], "a"); +assertEq(r.lastIndex, 2); + + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/ecma_5/RegExp/7.8.5-01.js b/js/src/tests/ecma_5/RegExp/7.8.5-01.js new file mode 100644 index 000000000..be09bbc14 --- /dev/null +++ b/js/src/tests/ecma_5/RegExp/7.8.5-01.js @@ -0,0 +1,35 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var BUGNUMBER = 615070; +var summary = "Line terminator after backslash is invalid in regexp literals"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var regexps = ["/\\\u000A/", "/\\\u000D/", "/\\\u2028/", "/\\\u2029/", + "/ab\\\n/", "/ab\\\r/", "/ab\\\u2028/", "/ab\\\u2029/", + "/ab[c\\\n]/", "/a[bc\\", "/\\"]; + +for(var i=0; i<regexps.length; i++) { + var src = regexps[i]; + try { + x = eval(src).source; + } catch(e) { + assertEq(e.constructor, SyntaxError); + continue; + } + assertEq(0, 1); +} + +/**************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/ecma_5/RegExp/browser.js b/js/src/tests/ecma_5/RegExp/browser.js new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/js/src/tests/ecma_5/RegExp/browser.js diff --git a/js/src/tests/ecma_5/RegExp/empty-lookahead.js b/js/src/tests/ecma_5/RegExp/empty-lookahead.js new file mode 100644 index 000000000..6e2f709e8 --- /dev/null +++ b/js/src/tests/ecma_5/RegExp/empty-lookahead.js @@ -0,0 +1,8 @@ +//bug 473941 +var regexp; + +regexp = /(?=)/; +assertEq(regexp.test('test'), true); + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/tests/ecma_5/RegExp/exec-lastIndex-ToInteger.js b/js/src/tests/ecma_5/RegExp/exec-lastIndex-ToInteger.js new file mode 100644 index 000000000..4505362d8 --- /dev/null +++ b/js/src/tests/ecma_5/RegExp/exec-lastIndex-ToInteger.js @@ -0,0 +1,36 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * + * Author: Geoffrey Sneddon <geoffers+mozilla@gmail.com> + */ + +var BUGNUMBER = 646490; +var summary = + "RegExp.prototype.exec doesn't get the lastIndex and ToInteger() it for " + + "non-global regular expressions when it should"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +var re = /./, called = 0; +re.lastIndex = {valueOf: function() { called++; return 0; }}; +re.exec("."); +re.lastIndex = {toString: function() { called++; return "0"; }}; +re.exec("."); +re.lastIndex = { + valueOf: function() { called++; return 0; }, + toString: function() { called--; } +}; +re.exec("."); +assertEq(called, 3, "FAIL, got " + called); + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/ecma_5/RegExp/exec.js b/js/src/tests/ecma_5/RegExp/exec.js new file mode 100644 index 000000000..411f348d9 --- /dev/null +++ b/js/src/tests/ecma_5/RegExp/exec.js @@ -0,0 +1,240 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var BUGNUMBER = 646490; +var summary = + "RegExp.prototype.exec doesn't get the lastIndex and ToInteger() it for " + + "non-global regular expressions when it should"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +function expectThrowTypeError(fun) +{ + try + { + var r = fun(); + throw new Error("didn't throw TypeError, returned " + r); + } + catch (e) + { + assertEq(e instanceof TypeError, true, + "didn't throw TypeError, got: " + e); + } +} + +function checkExec(description, regex, args, obj) +{ + var lastIndex = obj.lastIndex; + var index = obj.index; + var input = obj.input; + var indexArray = obj.indexArray; + + var res = regex.exec.apply(regex, args); + + assertEq(Array.isArray(res), true, description + ": not an array"); + assertEq(regex.lastIndex, lastIndex, description + ": wrong lastIndex"); + assertEq(res.index, index, description + ": wrong index"); + assertEq(res.input, input, description + ": wrong input"); + assertEq(res.length, indexArray.length, description + ": wrong length"); + for (var i = 0, sz = indexArray.length; i < sz; i++) + assertEq(res[i], indexArray[i], description + " " + i + ": wrong index value"); +} + +var exec = RegExp.prototype.exec; +var r, res, called, obj; + +/* 1. Let R be this RegExp object. */ +expectThrowTypeError(function() { exec.call(null); }); +expectThrowTypeError(function() { exec.call(""); }); +expectThrowTypeError(function() { exec.call(5); }); +expectThrowTypeError(function() { exec.call({}); }); +expectThrowTypeError(function() { exec.call([]); }); +expectThrowTypeError(function() { exec.call(); }); +expectThrowTypeError(function() { exec.call(true); }); +expectThrowTypeError(function() { exec.call(Object.create(RegExp.prototype)); }); +expectThrowTypeError(function() { exec.call(Object.create(/a/)); }); + + +/* 2. Let S be the value of ToString(string). */ +called = false; +r = /a/; +assertEq(r.lastIndex, 0); + +checkExec("/a/", r, [{ toString: function() { called = true; return 'ba'; } }], + { lastIndex: 0, + index: 1, + input: "ba", + indexArray: ["a"] }); +assertEq(called, true); + +called = false; +try +{ + res = r.exec({ toString: null, valueOf: function() { called = true; throw 17; } }); + throw new Error("didn't throw"); +} +catch (e) +{ + assertEq(e, 17); +} + +assertEq(called, true); + +called = false; +obj = r.lastIndex = { valueOf: function() { assertEq(true, false, "shouldn't have been called"); } }; +try +{ + res = r.exec({ toString: null, valueOf: function() { assertEq(called, false); called = true; throw 17; } }); + throw new Error("didn't throw"); +} +catch (e) +{ + assertEq(e, 17); +} + +assertEq(called, true); +assertEq(r.lastIndex, obj); + +// We don't test lack of an argument because of RegExp statics non-standard +// behaviors overriding what really should happen for lack of an argument, sigh. + + +/* + * 3. Let length be the length of S. + * 4. Let lastIndex be the result of calling the [[Get]] internal method of R with argument "lastIndex". + * 5. Let i be the value of ToInteger(lastIndex). + */ +r = /b/; +r.lastIndex = { valueOf: {}, toString: {} }; +expectThrowTypeError(function() { r.exec("foopy"); }); +r.lastIndex = { valueOf: function() { throw new TypeError(); } }; +expectThrowTypeError(function() { r.exec("foopy"); }); + + +/* + * 6. Let global be the result of calling the [[Get]] internal method of R with argument "global". + * 7. If global is false, then let i = 0. + */ +obj = { valueOf: function() { return 5; } }; +r = /abc/; +r.lastIndex = obj; + +checkExec("/abc/ take one", r, ["abc-------abc"], + { lastIndex: obj, + index: 0, + input: "abc-------abc", + indexArray: ["abc"] }); + +checkExec("/abc/ take two", r, ["abc-------abc"], + { lastIndex: obj, + index: 0, + input: "abc-------abc", + indexArray: ["abc"] }); + + +/* + * 8. Let matchSucceeded be false. + * 9. Repeat, while matchSucceeded is false + * a. If i < 0 or i > length, then + * i. Call the [[Put]] internal method of R with arguments "lastIndex", 0, and true. + * ii. Return null. + * b. Call the [[Match]] internal method of R with arguments S and i. + * c. If [[Match]] returned failure, then + * i. Let i = i+1. + * d. else + * i. Let r be the State result of the call to [[Match]]. + * ii. Set matchSucceeded to true. + * e. Let i = i+1. + */ +r = /abc()?/; +r.lastIndex = -5; +checkExec("/abc()?/ with lastIndex -5", r, ["abc-------abc"], + { lastIndex: -5, + index: 0, + input: "abc-------abc", + indexArray: ["abc", undefined] }); + + +r = /abc/; +r.lastIndex = -17; +res = r.exec("cdefg"); +assertEq(res, null); +assertEq(r.lastIndex, 0); + +r = /abc/g; +r.lastIndex = -42; +res = r.exec("cdefg"); +assertEq(res, null); +assertEq(r.lastIndex, 0); + + +/* + * 10. Let e be r's endIndex value. + * 11. If global is true, + * a. Call the [[Put]] internal method of R with arguments "lastIndex", e, and true. + */ +r = /abc/g; +r.lastIndex = 17; +assertEq(r.exec("sdfs"), null); +assertEq(r.lastIndex, 0); + +r = /abc/g; +r.lastIndex = 2; +checkExec("/abc/g", r, ["00abc"], + { lastIndex: 5, + index: 2, + input: "00abc", + indexArray: ["abc"] }); + + + +r = /a(b)c/g; +r.lastIndex = 2; +checkExec("/a(b)c/g take two", r, ["00abcd"], + { lastIndex: 5, + index: 2, + input: "00abcd", + indexArray: ["abc", "b"] }); + + +/* + * 12. Let n be the length of r's captures array. (This is the same value as + * 15.10.2.1's NCapturingParens.) + * 13. Let A be a new array created as if by the expression new Array() where + * Array is the standard built-in constructor with that name. + * 14. Let matchIndex be the position of the matched substring within the + * complete String S. + * 15. Call the [[DefineOwnProperty]] internal method of A with arguments + * "index", Property Descriptor {[[Value]]: matchIndex, [[Writable]: true, + * [[Enumerable]]: true, [[Configurable]]: true}, and true. + * 16. Call the [[DefineOwnProperty]] internal method of A with arguments + * "input", Property Descriptor {[[Value]]: S, [[Writable]: true, + * [[Enumerable]]: true, [[Configurable]]: true}, and true. + * 17. Call the [[DefineOwnProperty]] internal method of A with arguments + * "length", Property Descriptor {[[Value]]: n + 1}, and true. + * 18. Let matchedSubstr be the matched substring (i.e. the portion of S + * between offset i inclusive and offset e exclusive). + * 19. Call the [[DefineOwnProperty]] internal method of A with arguments "0", + * Property Descriptor {[[Value]]: matchedSubstr, [[Writable]: true, + * [[Enumerable]]: true, [[Configurable]]: true}, and true. + * 20. For each integer i such that I > 0 and I ≤ n + * a. Let captureI be i th element of r's captures array. + * b. Call the [[DefineOwnProperty]] internal method of A with arguments + * ToString(i), Property Descriptor {[[Value]]: captureI, [[Writable]: + * true, [[Enumerable]]: true, [[Configurable]]: true}, and true. + * 21. Return A. + */ +// throughout, above (and in other tests) + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/ecma_5/RegExp/instance-property-storage-introspection.js b/js/src/tests/ecma_5/RegExp/instance-property-storage-introspection.js new file mode 100644 index 000000000..1f7c7042f --- /dev/null +++ b/js/src/tests/ecma_5/RegExp/instance-property-storage-introspection.js @@ -0,0 +1,131 @@ +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + */ + +var BUGNUMBER = 640072; +var summary = + "Represent /a/.{lastIndex,global,source,multiline,sticky,ignoreCase} with " + + "plain old data properties"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +function checkDataProperty(obj, p, expect, msg) +{ + var d = Object.getOwnPropertyDescriptor(obj, p); + + assertEq(d.value, expect.value, msg + ": bad value for " + p); + assertEq(d.writable, expect.writable, msg + ": bad writable for " + p); + assertEq(d.enumerable, expect.enumerable, msg + ": bad enumerable for " + p); + assertEq(d.configurable, expect.configurable, msg + ": bad configurable for " + p); + + // Try redefining the property using its initial values: these should all be + // silent no-ops. + Object.defineProperty(obj, p, { value: expect.value }); + Object.defineProperty(obj, p, { writable: expect.writable }); + Object.defineProperty(obj, p, { enumerable: expect.enumerable }); + Object.defineProperty(obj, p, { configurable: expect.configurable }); + + var d2 = Object.getOwnPropertyDescriptor(obj, p); + assertEq(d.value, d2.value, msg + ": value changed on redefinition of " + p + "?"); + assertEq(d.writable, d2.writable, msg + ": writable changed on redefinition of " + p + "?"); + assertEq(d.enumerable, d2.enumerable, msg + ": enumerable changed on redefinition of " + p + "?"); + assertEq(d.configurable, d2.configurable, msg + ": configurable changed on redefinition of " + p + "?"); +} + + +// Check a bunch of "empty" regular expressions first. + +var choices = [{ msg: "RegExp.prototype", + get: function() { return RegExp.prototype; } }, + { msg: "new RegExp()", + get: function() { return new RegExp(); } }, + { msg: "/(?:)/", + get: Function("return /(?:)/;") }]; + +function checkRegExp(r, msg, lastIndex) +{ + var expect; + + expect = { value: lastIndex, enumerable: false, configurable: false, writable: true }; + checkDataProperty(r, "lastIndex", expect, msg); +} + +checkRegExp(RegExp.prototype, "RegExp.prototype", 0); +checkRegExp(new RegExp(), "new RegExp()", 0); +checkRegExp(/(?:)/, "/(?:)/", 0); +checkRegExp(Function("return /(?:)/;")(), 'Function("return /(?:)/;")()', 0); + +for (var i = 0; i < choices.length; i++) +{ + var choice = choices[i]; + var msg = choice.msg; + var r = choice.get(); + + checkRegExp(r, msg, 0); +} + +// Now test less generic regular expressions + +checkRegExp(/a/gim, "/a/gim", 0); + +var r; + +do +{ + r = /abcd/mg; + checkRegExp(r, "/abcd/mg initially", 0); + r.exec("abcdefg"); + checkRegExp(r, "/abcd/mg step 1", 4); + r.exec("abcdabcd"); + checkRegExp(r, "/abcd/mg step 2", 8); + r.exec("abcdabcd"); + checkRegExp(r, "/abcd/mg end", 0); + + r = /cde/ig; + checkRegExp(r, "/cde/ig initially", 0); + var obj = r.lastIndex = { valueOf: function() { return 2; } }; + checkRegExp(r, "/cde/ig after lastIndex", obj); + r.exec("aaacdef"); + checkRegExp(r, "/cde/ig after exec", 6); + Object.defineProperty(r, "lastIndex", { value: 3 }); + checkRegExp(r, "/cde/ig after define 3", 3); + Object.defineProperty(r, "lastIndex", { value: obj }); + checkRegExp(r, "/cde/ig after lastIndex", obj); + + + // Tricky bits of testing: make sure that redefining lastIndex doesn't change + // the slot where the lastIndex property is initially stored, even if + // the redefinition also changes writability. + r = /a/g; + checkRegExp(r, "/a/g initially", 0); + Object.defineProperty(r, "lastIndex", { value: 2 }); + r.exec("aabbbba"); + checkRegExp(r, "/a/g after first exec", 7); + assertEq(r.lastIndex, 7); + r.lastIndex = 2; + checkRegExp(r, "/a/g after assign", 2); + r.exec("aabbbba"); + assertEq(r.lastIndex, 7); // check in reverse order + checkRegExp(r, "/a/g after second exec", 7); + + r = /c/g; + r.lastIndex = 2; + checkRegExp(r, "/c/g initially", 2); + Object.defineProperty(r, "lastIndex", { writable: false }); + assertEq(Object.getOwnPropertyDescriptor(r, "lastIndex").writable, false); + try { r.exec("aabbbba"); } catch (e) { /* swallow error if thrown */ } + assertEq(Object.getOwnPropertyDescriptor(r, "lastIndex").writable, false); +} +while (Math.random() > 17); // fake loop to discourage RegExp object caching + +/******************************************************************************/ + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("All tests passed!"); diff --git a/js/src/tests/ecma_5/RegExp/regexp-space-character-class.js b/js/src/tests/ecma_5/RegExp/regexp-space-character-class.js new file mode 100644 index 000000000..19d79859c --- /dev/null +++ b/js/src/tests/ecma_5/RegExp/regexp-space-character-class.js @@ -0,0 +1,45 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public +* License, v. 2.0. If a copy of the MPL was not distributed with this +* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +var gTestfile = 'regexp-space-character-class.js'; +//----------------------------------------------------------------------------- +var BUGNUMBER = 514808; +var summary = 'Correct space character class in regexes'; +var actual = ''; +var expect = ''; + + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ +enterFunc ('test'); +printBugNumber(BUGNUMBER); +printStatus (summary); + +var spaces = [ "\u0009", "\u000b", "\u000c", "\u0020", "\u00a0", "\u1680", +"\u180e", "\u2000", "\u2001", "\u2002", "\u2003", "\u2004", +"\u2005", "\u2006", "\u2007", "\u2008", "\u2009", "\u200a", +"\u202f", "\u205f", "\u3000", "\ufeff" ]; +var line_terminators = [ "\u2028", "\u2029", "\u000a", "\u000d" ]; +var space_chars = [].concat(spaces, line_terminators); + +var non_space_chars = [ "\u200b", "\u200c", "\u200d" ]; + +var chars = [].concat(space_chars, non_space_chars); +var is_space = [].concat(space_chars.map(function(ch) { return true; }), +non_space_chars.map(function(ch) { return false; })); +var expect = is_space.join(','); + +var actual = chars.map(function(ch) { return /\s/.test(ch); }).join(','); +reportCompare(expect, actual, summary); + +var actual = chars.map(function(ch) { return /\s/.test(ch); }).join(','); +reportCompare(expect, actual, summary); + +exitFunc ('test'); +} diff --git a/js/src/tests/ecma_5/RegExp/regress-429241.js b/js/src/tests/ecma_5/RegExp/regress-429241.js new file mode 100644 index 000000000..a4b588fea --- /dev/null +++ b/js/src/tests/ecma_5/RegExp/regress-429241.js @@ -0,0 +1,200 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +var gTestfile = 'regress-429241.js'; +var BUGNUMBER = 429241; +var summary = '\\x or \\u followed by too few hex digits'; +var r; + +reportCompare( + "x", + (r = /[\x]+/.exec("\\x\0")) && r[0], + "Section 1" +); + +reportCompare( + "xy", + (r = /[\xy]+/.exec("\\xy\0")) && r[0], + "Section 2" +); + +reportCompare( + "x0", + (r = /[\x0]+/.exec("\\x0\0")) && r[0], + "Section 3" +); + +reportCompare( + "x0y", + (r = /[\x0y]+/.exec("\\x0y\0")) && r[0], + "Section 4" +); + +reportCompare( + "\0", + (r = /[\x00]+/.exec("\\x\0")) && r[0], + "Section 5" +); + +reportCompare( + "0\0", + (r = /[\x000]+/.exec("0\0")) && r[0], + "Section 6" +); + +reportCompare( + "x", + (r = /^\x$/.exec("x")) && r[0], + "Section 7" +); + +reportCompare( + "xy", + (r = /^\xy$/.exec("xy")) && r[0], + "Section 8" +); + +reportCompare( + "x0", + (r = /^\x0$/.exec("x0")) && r[0], + "Section 9" +); + +reportCompare( + "x0y", + (r = /^\x0y$/.exec("x0y")) && r[0], + "Section 10" +); + +reportCompare( + null, + /^\x00$/.exec("\0" + "0"), + "Section 11" +); + +reportCompare( + "\0" + "0", + (r = /^\x000$/.exec("\0" + "0")) && r[0], + "Section 12" +); + +reportCompare( + "u", + (r = /[\u]+/.exec("\\u\0")) && r[0], + "Section 13" +); + +reportCompare( + "uy", + (r = /[\uy]+/.exec("\\uy\0")) && r[0], + "Section 14" +); + +reportCompare( + "u0", + (r = /[\u0]+/.exec("\\u0\0")) && r[0], + "Section 15" +); + +reportCompare( + "u0", + (r = /[\u00]+/.exec("\\u0\0")) && r[0], + "Section 16" +); + +reportCompare( + "u0", + (r = /[\u000]+/.exec("\\u0\0")) && r[0], + "Section 17" +); + +reportCompare( + "u0y", + (r = /[\u0y]+/.exec("\\u0y\0")) && r[0], + "Section 18" +); + +reportCompare( + "u0y", + (r = /[\u00y]+/.exec("\\u0y\0")) && r[0], + "Section 19" +); + +reportCompare( + "u0y", + (r = /[\u000y]+/.exec("\\u0y\0")) && r[0], + "Section 20" +); + +reportCompare( + "\0", + (r = /[\u0000]+/.exec("\\u\0")) && r[0], + "Section 21" +); + +reportCompare( + "0\0", + (r = /[\u00000]+/.exec("0\0")) && r[0], + "Section 22" +); + +reportCompare( + "u", + (r = /^\u$/.exec("u")) && r[0], + "Section 23" +); + +reportCompare( + "uy", + (r = /^\uy$/.exec("uy")) && r[0], + "Section 24" +); + +reportCompare( + "u0", + (r = /^\u0$/.exec("u0")) && r[0], + "Section 25" +); + +reportCompare( + "u00", + (r = /^\u00$/.exec("u00")) && r[0], + "Section 26" +); + +reportCompare( + "u000", + (r = /^\u000$/.exec("u000")) && r[0], + "Section 27" +); + +reportCompare( + "u0y", + (r = /^\u0y$/.exec("u0y")) && r[0], + "Section 28" +); + +reportCompare( + "u00y", + (r = /^\u00y$/.exec("u00y")) && r[0], + "Section 29" +); + +reportCompare( + "u000y", + (r = /^\u000y$/.exec("u000y")) && r[0], + "Section 30" +); + +reportCompare( + null, + /^\u0000$/.exec("\0" + "0"), + "Section 31" +); + +reportCompare( + "\0" + "0", + (r = /^\u00000$/.exec("\0" + "0")) && r[0], + "Section 32" +); diff --git a/js/src/tests/ecma_5/RegExp/regress-576828.js b/js/src/tests/ecma_5/RegExp/regress-576828.js new file mode 100644 index 000000000..45e97dc3b --- /dev/null +++ b/js/src/tests/ecma_5/RegExp/regress-576828.js @@ -0,0 +1,8 @@ +var re = /(z\1){3}/; +var str = 'zzz'; +var actual = re.exec(str); +var expected = makeExpectedMatch(['zzz', 'z'], 0, str); +checkRegExpMatch(actual, expected); + +if (typeof reportCompare == 'function') + reportCompare(true, true); diff --git a/js/src/tests/ecma_5/RegExp/regress-613820-1.js b/js/src/tests/ecma_5/RegExp/regress-613820-1.js new file mode 100644 index 000000000..e5e755b24 --- /dev/null +++ b/js/src/tests/ecma_5/RegExp/regress-613820-1.js @@ -0,0 +1,9 @@ +/* Back reference is actually a forwards reference. */ +var re = /(\2(a)){2}/; +var str = 'aaa'; +var actual = re.exec(str); +var expected = makeExpectedMatch(['aa', 'a', 'a'], 0, str); +checkRegExpMatch(actual, expected); + +if (typeof reportCompare === 'function') + reportCompare(true, true); diff --git a/js/src/tests/ecma_5/RegExp/regress-613820-2.js b/js/src/tests/ecma_5/RegExp/regress-613820-2.js new file mode 100644 index 000000000..5db7244ba --- /dev/null +++ b/js/src/tests/ecma_5/RegExp/regress-613820-2.js @@ -0,0 +1,9 @@ +/* Resetting of inner capture groups across quantified capturing parens. */ +var re = /(?:(f)(o)(o)|(b)(a)(r))*/; +var str = 'foobar'; +var actual = re.exec(str); +var expected = makeExpectedMatch(['foobar', undefined, undefined, undefined, 'b', 'a', 'r'], 0, str); +checkRegExpMatch(actual, expected); + +if (typeof reportCompare === 'function') + reportCompare(true, true); diff --git a/js/src/tests/ecma_5/RegExp/regress-613820-3.js b/js/src/tests/ecma_5/RegExp/regress-613820-3.js new file mode 100644 index 000000000..126e838ff --- /dev/null +++ b/js/src/tests/ecma_5/RegExp/regress-613820-3.js @@ -0,0 +1,9 @@ +/* Capture group reset to undefined during second iteration, so backreference doesn't see prior result. */ +var re = /(?:^(a)|\1(a)|(ab)){2}/; +var str = 'aab'; +var actual = re.exec(str); +var expected = makeExpectedMatch(['aa', undefined, 'a', undefined], 0, str); +checkRegExpMatch(actual, expected); + +if (typeof reportCompare === 'function') + reportCompare(true, true); diff --git a/js/src/tests/ecma_5/RegExp/regress-617935.js b/js/src/tests/ecma_5/RegExp/regress-617935.js new file mode 100644 index 000000000..3764d81b0 --- /dev/null +++ b/js/src/tests/ecma_5/RegExp/regress-617935.js @@ -0,0 +1,42 @@ +// |reftest| skip-if(!xulRuntime.shell&&(Android||xulRuntime.OS=="WINNT")) silentfail +/* + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/licenses/publicdomain/ + * + * Author: Christian Holler <decoder@own-hero.net> + */ + +expectExitCode(0); +expectExitCode(5); + +/* Length of 32 */ +var foo = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + +/* Make len(foo) 32768 */ +for (i = 0; i < 10; ++i) { + foo += foo; +} + +/* Add one "a" to cause overflow later */ +foo += "a"; + +var bar = "bbbbbbbbbbbbbbbb"; + +/* Make len(bar) 8192 */ +for (i = 0; i < 9; ++i) { + bar += bar; +} + +/* + * Resulting string should be + * len(foo) * len(bar) = (2**10 * 32 + 1) * 8192 = 268443648 + * which will be larger than the max string length (2**28, or 268435456). + */ +try { + foo.replace(/[a]/g, bar); +} catch (e) { + reportCompare(e instanceof InternalError, true, "Internal error due to overallocation is ok."); +} +reportCompare(true, true, "No crash occurred."); + +print("Tests complete"); diff --git a/js/src/tests/ecma_5/RegExp/shell.js b/js/src/tests/ecma_5/RegExp/shell.js new file mode 100644 index 000000000..0ce9f087d --- /dev/null +++ b/js/src/tests/ecma_5/RegExp/shell.js @@ -0,0 +1,21 @@ +function makeExpectedMatch(arr, index, input) { + var expectedMatch = { + index: index, + input: input, + length: arr.length, + }; + + for (var i = 0; i < arr.length; ++i) + expectedMatch[i] = arr[i]; + + return expectedMatch; +} + +function checkRegExpMatch(actual, expected) { + assertEq(actual.length, expected.length); + for (var i = 0; i < actual.length; ++i) + assertEq(actual[i], expected[i]); + + assertEq(actual.index, expected.index); + assertEq(actual.input, expected.input); +} |