mirror of
				https://github.com/tc39/test262.git
				synced 2025-10-27 01:33:59 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			100 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			100 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| //@ skip if $hostOS != "darwin" or $architecture == "arm" or $architecture == "x86" or not $jitTests
 | |
| // 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";
 |