mirror of https://github.com/tc39/test262.git
100 lines
3.9 KiB
JavaScript
100 lines
3.9 KiB
JavaScript
//@ skip if $hostOS != "darwin" or $architecture == "arm" or $architecture == "x86"
|
|
// Test that throw an OOM exception when compiling a pathological, but valid nested RegExp.
|
|
|
|
var failures = [];
|
|
|
|
class TestAndExpectedException
|
|
{
|
|
constructor(func, exception)
|
|
{
|
|
this.func = func;
|
|
this.exception = exception;
|
|
}
|
|
|
|
runTest()
|
|
{
|
|
try {
|
|
this.func();
|
|
failures.push("Running " + this.func + ", expected OOM exception, but didn't get one");
|
|
} catch (e) {
|
|
let errStr = e.toString();
|
|
if (errStr != this.exception)
|
|
failures.push("Running " + this.func + ", expected: \"" + this.exception + "\" but got \"" + errStr + "\"");
|
|
}
|
|
}
|
|
}
|
|
|
|
function recurseAndTest(depth, testList)
|
|
{
|
|
// Probe stack depth
|
|
try {
|
|
let result = recurseAndTest(depth + 1, testList);
|
|
if (result == 0) {
|
|
// Call the test functions with a nearly full stack.
|
|
for (const test of testList)
|
|
test.runTest();
|
|
|
|
return 1;
|
|
} else if (result < 0)
|
|
return result + 1;
|
|
else
|
|
return result;
|
|
} catch (e) {
|
|
// Go up a several frames and then call the test functions
|
|
return -24;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
let deepRE = new RegExp("((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((x))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))");
|
|
let deepGlobalRE = new RegExp(deepRE, "g");
|
|
|
|
let matchLen = 401; // The number of parens plus 1 for the whole match.
|
|
|
|
let regExpOOMError = "Error: Out of memory: Invalid regular expression: too many nested disjunctions";
|
|
|
|
testList = [];
|
|
|
|
// Test that all RegExp related APIs that compile RE's properly handle OOM.
|
|
testList.push(new TestAndExpectedException(() => { deepRE.exec("x"); }, regExpOOMError));
|
|
testList.push(new TestAndExpectedException(() => { deepRE.test("x"); }, regExpOOMError));
|
|
testList.push(new TestAndExpectedException(() => { "x".match(deepRE); }, regExpOOMError));
|
|
testList.push(new TestAndExpectedException(() => { "x".match(deepGlobalRE); }, regExpOOMError));
|
|
testList.push(new TestAndExpectedException(() => { "x".replace(deepGlobalRE, ""); }, regExpOOMError));
|
|
testList.push(new TestAndExpectedException(() => { "x".replace(deepGlobalRE, "X"); }, regExpOOMError));
|
|
testList.push(new TestAndExpectedException(() => { "x".replace(deepGlobalRE, () => { return "X" }); }, regExpOOMError));
|
|
testList.push(new TestAndExpectedException(() => { "x".search(deepRE); }, regExpOOMError));
|
|
|
|
recurseAndTest(1, testList);
|
|
|
|
if (failures.length) {
|
|
print("Got the following failures:");
|
|
for (const failure of failures)
|
|
print(failure);
|
|
throw "Got failures";
|
|
}
|
|
|
|
// Test that the RegExp works correctly with RegExp.exec() and RegExp.test() when there is sufficient stack space to compile it.
|
|
let m = deepRE.exec("x");
|
|
let matched = true;
|
|
if (m.length != matchLen)
|
|
matched = false
|
|
else {
|
|
for (i = 0; i < matchLen; i++) {
|
|
if (m[i] != "x")
|
|
matched = false;
|
|
}
|
|
}
|
|
|
|
if (!matched) {
|
|
let expectedMatch = [];
|
|
for (i = 0; i < matchLen; i++)
|
|
expectedMatch[i] = "x";
|
|
|
|
throw "Expected RegExp.exec(...) to be [" + expectedMatch + "] but got [" + m + "]";
|
|
}
|
|
|
|
if (!deepRE.test("x"))
|
|
throw "Expected RegExp.test(...) to be true, but was false";
|