Title: [294411] trunk
Revision
294411
Author
[email protected]
Date
2022-05-18 11:33:44 -0700 (Wed, 18 May 2022)

Log Message

WTF::CrashOnOverflow::crash() with /((a{100000000})*b{2100000000})+/.test();
https://bugs.webkit.org/show_bug.cgi?id=240552

Reviewed by Yusuke Suzuki and Alex Christensen.

Replaced a crashing checked add in the YARR JIT code generator with a reporting add so we can
catch the overflow.  When we do overflow, we terminate the JIT genration with an error.
We'll fallback to the YARR interpreter, which already exits with an error on a similar overflow.

* JSTests/stress/regexp-large-quantifier.js:
(testRegExp):
* Source/_javascript_Core/yarr/YarrJIT.cpp:
(JSC::Yarr::dumpCompileFailure):
* Source/_javascript_Core/yarr/YarrJIT.h:

Canonical link: https://commits.webkit.org/250703@main

Modified Paths

Diff

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 {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to