Modified: trunk/JSTests/stress/regexp-large-quantifier.js (294410 => 294411)
--- trunk/JSTests/stress/regexp-large-quantifier.js 2022-05-18 18:17:11 UTC (rev 294410)
+++ trunk/JSTests/stress/regexp-large-quantifier.js 2022-05-18 18:33:44 UTC (rev 294411)
@@ -1,6 +1,16 @@
-function testRegExp(pattern, string, expectedMatch) {
+function testRegExp(pattern, string, expectedParseError, expectedMatch) {
const r = new RegExp(pattern);
- const actualResult = r.exec(string);
+ let actualResult = null;
+ let actualParseError = null;
+ try {
+ actualResult = r.exec(string);
+ } catch(e) {
+ actualParseError = e;
+ }
+
+ if (expectedParseError && expectedParseError != actualParseError)
+ throw("Expected \"" + expectedParseError + "\", but got \"" + actualParseError + "\"");
+
if (expectedMatch === undefined) {
if (actualResult !== null)
throw("Expected " + r + ".exec(\"" + string + "\") to be null");
@@ -10,7 +20,8 @@
}
}
-testRegExp("a{0,4294967295}", "a", "a");
-testRegExp("a{0,4294967296}", "a", "a");
-testRegExp("^a{0,4294967296}$", "a{0,4294967296}", undefined);
-testRegExp("(?:a{0,340282366920}?){0,1}a", "aa", "aa");
+testRegExp("a{0,4294967295}", "a", undefined, "a");
+testRegExp("a{0,4294967296}", "a", undefined, "a");
+testRegExp("^a{0,4294967296}$", "a{0,4294967296}", undefined, undefined);
+testRegExp("(?:a{0,340282366920}?){0,1}a", "aa", undefined, "aa");
+testRegExp("((.{100000000})*.{2100000000})+", "x", "SyntaxError: Invalid regular _expression_: pattern exceeds string length limits", undefined);
Modified: trunk/Source/_javascript_Core/yarr/YarrJIT.cpp (294410 => 294411)
--- trunk/Source/_javascript_Core/yarr/YarrJIT.cpp 2022-05-18 18:17:11 UTC (rev 294410)
+++ trunk/Source/_javascript_Core/yarr/YarrJIT.cpp 2022-05-18 18:33:44 UTC (rev 294411)
@@ -3596,7 +3596,16 @@
lastOp.m_checkAdjust = nestedAlternative->m_minimumSize;
if ((term->quantityType == QuantifierType::FixedCount) && (term->type != PatternTerm::Type::ParentheticalAssertion))
lastOp.m_checkAdjust -= disjunction->m_minimumSize;
- lastOp.m_checkedOffset = checkedOffset + lastOp.m_checkAdjust;
+
+ Checked<unsigned, RecordOverflow> checkedOffsetResult(checkedOffset);
+ checkedOffsetResult += lastOp.m_checkAdjust;
+
+ if (UNLIKELY(checkedOffsetResult.hasOverflowed())) {
+ m_failureReason = JITFailureReason::OffsetTooLarge;
+ return;
+ }
+
+ lastOp.m_checkedOffset = checkedOffsetResult;
}
opCompileAlternative(m_ops[lastOpIndex].m_checkedOffset, nestedAlternative);
@@ -4721,6 +4730,9 @@
case JITFailureReason::ExecutableMemoryAllocationFailure:
dataLog("Can't JIT because of failure of allocation of executable memory\n");
break;
+ case JITFailureReason::OffsetTooLarge:
+ dataLog("Can't JIT because pattern exceeds string length limits\n");
+ break;
}
}
Modified: trunk/Source/_javascript_Core/yarr/YarrJIT.h (294410 => 294411)
--- trunk/Source/_javascript_Core/yarr/YarrJIT.h 2022-05-18 18:17:11 UTC (rev 294410)
+++ trunk/Source/_javascript_Core/yarr/YarrJIT.h 2022-05-18 18:33:44 UTC (rev 294411)
@@ -62,6 +62,7 @@
FixedCountParenthesizedSubpattern,
ParenthesisNestedTooDeep,
ExecutableMemoryAllocationFailure,
+ OffsetTooLarge,
};
class BoyerMooreFastCandidates {