Title: [243571] branches/safari-607-branch
Revision
243571
Author
alanc...@apple.com
Date
2019-03-27 16:43:34 -0700 (Wed, 27 Mar 2019)

Log Message

Cherry-pick r242838. rdar://problem/49307991

    REGRESSION (iOS 12.2): Webpage using CoffeeScript crashes
    https://bugs.webkit.org/show_bug.cgi?id=195613

    Reviewed by Mark Lam.

    JSTests:

    New regression test.

    * stress/regexp-backref-inbounds.js: Added.
    (testRegExp):

    Source/_javascript_Core:

    The bug here is in Yarr JIT backreference matching code.  We are incorrectly
    using a checkedOffset / inputPosition correction when checking for the available
    length left in a string.  It is improper to do these corrections as a backreference's
    match length is based on what was matched in the referenced capture group and not
    part of the checkedOffset and inputPosition computed when we compiled the RegExp.
    In some cases, the resulting incorrect calculation would allow us to go past
    the subject string's length.  Removed these adjustments.

    After writing tests for the first bug, found another bug where the non-greedy
    backreference backtracking code didn't do an "are we at the end of the input?" check.
    This caused an infinite loop as we'd jump from the backtracking code back to
    try matching one more backreference, fail and then backtrack.

    * yarr/YarrJIT.cpp:
    (JSC::Yarr::YarrGenerator::generateBackReference):
    (JSC::Yarr::YarrGenerator::backtrackBackReference):

    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242838 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Modified Paths

Added Paths

Diff

Modified: branches/safari-607-branch/JSTests/ChangeLog (243570 => 243571)


--- branches/safari-607-branch/JSTests/ChangeLog	2019-03-27 23:43:28 UTC (rev 243570)
+++ branches/safari-607-branch/JSTests/ChangeLog	2019-03-27 23:43:34 UTC (rev 243571)
@@ -1,3 +1,53 @@
+2019-03-27  Alan Coon  <alanc...@apple.com>
+
+        Cherry-pick r242838. rdar://problem/49307991
+
+    REGRESSION (iOS 12.2): Webpage using CoffeeScript crashes
+    https://bugs.webkit.org/show_bug.cgi?id=195613
+    
+    Reviewed by Mark Lam.
+    
+    JSTests:
+    
+    New regression test.
+    
+    * stress/regexp-backref-inbounds.js: Added.
+    (testRegExp):
+    
+    Source/_javascript_Core:
+    
+    The bug here is in Yarr JIT backreference matching code.  We are incorrectly
+    using a checkedOffset / inputPosition correction when checking for the available
+    length left in a string.  It is improper to do these corrections as a backreference's
+    match length is based on what was matched in the referenced capture group and not
+    part of the checkedOffset and inputPosition computed when we compiled the RegExp.
+    In some cases, the resulting incorrect calculation would allow us to go past
+    the subject string's length.  Removed these adjustments.
+    
+    After writing tests for the first bug, found another bug where the non-greedy
+    backreference backtracking code didn't do an "are we at the end of the input?" check.
+    This caused an infinite loop as we'd jump from the backtracking code back to
+    try matching one more backreference, fail and then backtrack.
+    
+    * yarr/YarrJIT.cpp:
+    (JSC::Yarr::YarrGenerator::generateBackReference):
+    (JSC::Yarr::YarrGenerator::backtrackBackReference):
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242838 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2019-03-12  Michael Saboff  <msab...@apple.com>
+
+            REGRESSION (iOS 12.2): Webpage using CoffeeScript crashes
+            https://bugs.webkit.org/show_bug.cgi?id=195613
+
+            Reviewed by Mark Lam.
+
+            New regression test.
+
+            * stress/regexp-backref-inbounds.js: Added.
+            (testRegExp):
+
 2019-03-13  Babak Shafiei  <bshaf...@apple.com>
 
         Cherry-pick r242810. rdar://problem/48839349

Added: branches/safari-607-branch/JSTests/stress/regexp-backref-inbounds.js (0 => 243571)


--- branches/safari-607-branch/JSTests/stress/regexp-backref-inbounds.js	                        (rev 0)
+++ branches/safari-607-branch/JSTests/stress/regexp-backref-inbounds.js	2019-03-27 23:43:34 UTC (rev 243571)
@@ -0,0 +1,46 @@
+// This test should pass without crashing.
+
+function testRegExp(re, str, expected)
+{
+    let match = re.exec(str);
+
+    let errors = "";
+    
+    if (match) {
+        if (!expected)
+            errors += "\nExpected no match, but got: " + match;
+        else {
+            if (match.length != expected.length)
+                errors += "\nExpected to match " + expected.length - 1 + " groups, but matched " + match.length - 1 +  " groups.\n";
+            if (match[0] != expected[0])
+                errors += "\nExpected results \"" + expected[0] + "\", but got \"" + match[0] + "\"";
+
+            let checkLength = Math.min(match.length, expected.length);
+            for (i = 1; i < checkLength; ++i) {
+                if (match[i] != expected[i])
+                    errors += "\nExpected group " + (i - 1) + " to be \"" + expected[i] + "\", but got \"" + match[i] + "\"";
+            }
+        }
+    } else if (expected)
+        errors += "\nExpected a match of " + expected + ", but didn't match";
+
+    if (errors.length)
+        throw errors.substring(1);
+}
+
+testRegExp(/^(.)\1*(\1.)/, "    ", ["    ", " ", "  "]);
+testRegExp(/^(.)\1*(\1+?)a/, "    ", undefined);
+
+testRegExp(/^(.)\1*?(.+)/, "xxxx", ["xxxx", "x", "xxx"]);
+
+testRegExp(/^(.{2})\1*(.+)/, "xxxx", ["xxxx", "xx", "xx"]);
+testRegExp(/^(.{2})\1*?(.+)/, "xxxx", ["xxxx", "xx", "xx"]);
+
+testRegExp(/^(.{2})\1*(.+)/, "xxx", ["xxx", "xx", "x"]);
+testRegExp(/^(.{2})\1*?(.+)/, "xxx", ["xxx", "xx", "x"]);
+
+testRegExp(/^(.)\1*(.+)/s, "=======", ["=======", "=", "="]);
+testRegExp(/^(.)\1*?(.+)/s, "=======", ["=======", "=", "======"]);
+
+testRegExp(/^(.)\1*(X)/s, "======X", ["======X", "=", "X"]);
+testRegExp(/^(.)\1*?(X)/s, "======X", ["======X", "=", "X"]);

Modified: branches/safari-607-branch/Source/_javascript_Core/ChangeLog (243570 => 243571)


--- branches/safari-607-branch/Source/_javascript_Core/ChangeLog	2019-03-27 23:43:28 UTC (rev 243570)
+++ branches/safari-607-branch/Source/_javascript_Core/ChangeLog	2019-03-27 23:43:34 UTC (rev 243571)
@@ -1,3 +1,65 @@
+2019-03-27  Alan Coon  <alanc...@apple.com>
+
+        Cherry-pick r242838. rdar://problem/49307991
+
+    REGRESSION (iOS 12.2): Webpage using CoffeeScript crashes
+    https://bugs.webkit.org/show_bug.cgi?id=195613
+    
+    Reviewed by Mark Lam.
+    
+    JSTests:
+    
+    New regression test.
+    
+    * stress/regexp-backref-inbounds.js: Added.
+    (testRegExp):
+    
+    Source/_javascript_Core:
+    
+    The bug here is in Yarr JIT backreference matching code.  We are incorrectly
+    using a checkedOffset / inputPosition correction when checking for the available
+    length left in a string.  It is improper to do these corrections as a backreference's
+    match length is based on what was matched in the referenced capture group and not
+    part of the checkedOffset and inputPosition computed when we compiled the RegExp.
+    In some cases, the resulting incorrect calculation would allow us to go past
+    the subject string's length.  Removed these adjustments.
+    
+    After writing tests for the first bug, found another bug where the non-greedy
+    backreference backtracking code didn't do an "are we at the end of the input?" check.
+    This caused an infinite loop as we'd jump from the backtracking code back to
+    try matching one more backreference, fail and then backtrack.
+    
+    * yarr/YarrJIT.cpp:
+    (JSC::Yarr::YarrGenerator::generateBackReference):
+    (JSC::Yarr::YarrGenerator::backtrackBackReference):
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242838 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2019-03-12  Michael Saboff  <msab...@apple.com>
+
+            REGRESSION (iOS 12.2): Webpage using CoffeeScript crashes
+            https://bugs.webkit.org/show_bug.cgi?id=195613
+
+            Reviewed by Mark Lam.
+
+            The bug here is in Yarr JIT backreference matching code.  We are incorrectly
+            using a checkedOffset / inputPosition correction when checking for the available
+            length left in a string.  It is improper to do these corrections as a backreference's
+            match length is based on what was matched in the referenced capture group and not
+            part of the checkedOffset and inputPosition computed when we compiled the RegExp.
+            In some cases, the resulting incorrect calculation would allow us to go past
+            the subject string's length.  Removed these adjustments.
+
+            After writing tests for the first bug, found another bug where the non-greedy
+            backreference backtracking code didn't do an "are we at the end of the input?" check.
+            This caused an infinite loop as we'd jump from the backtracking code back to
+            try matching one more backreference, fail and then backtrack.
+
+            * yarr/YarrJIT.cpp:
+            (JSC::Yarr::YarrGenerator::generateBackReference):
+            (JSC::Yarr::YarrGenerator::backtrackBackReference):
+
 2019-03-13  Babak Shafiei  <bshaf...@apple.com>
 
         Cherry-pick r242810. rdar://problem/48839349

Modified: branches/safari-607-branch/Source/_javascript_Core/yarr/YarrJIT.cpp (243570 => 243571)


--- branches/safari-607-branch/Source/_javascript_Core/yarr/YarrJIT.cpp	2019-03-27 23:43:28 UTC (rev 243570)
+++ branches/safari-607-branch/Source/_javascript_Core/yarr/YarrJIT.cpp	2019-03-27 23:43:34 UTC (rev 243571)
@@ -1200,8 +1200,6 @@
 
             // PatternTemp should contain pattern end index at this point
             sub32(patternIndex, patternTemp);
-            if (m_checkedOffset - term->inputPosition)
-                sub32(Imm32((m_checkedOffset - term->inputPosition).unsafeGet()), patternTemp);
             op.m_jumps.append(checkNotEnoughInput(patternTemp));
 
             matchBackreference(opIndex, op.m_jumps, characterOrTemp, patternIndex, patternTemp);
@@ -1226,8 +1224,6 @@
 
             // PatternTemp should contain pattern end index at this point
             sub32(patternIndex, patternTemp);
-            if (m_checkedOffset - term->inputPosition)
-                sub32(Imm32((m_checkedOffset - term->inputPosition).unsafeGet()), patternTemp);
             matches.append(checkNotEnoughInput(patternTemp));
 
             matchBackreference(opIndex, incompleteMatches, characterOrTemp, patternIndex, patternTemp);
@@ -1272,8 +1268,6 @@
 
             // Check if we have input remaining to match
             sub32(patternIndex, patternTemp);
-            if (m_checkedOffset - term->inputPosition)
-                sub32(Imm32((m_checkedOffset - term->inputPosition).unsafeGet()), patternTemp);
             matches.append(checkNotEnoughInput(patternTemp));
 
             storeToFrame(index, parenthesesFrameLocation + BackTrackInfoBackReference::beginIndex());
@@ -1330,6 +1324,7 @@
         case QuantifierNonGreedy: {
             const RegisterID matchAmount = regT0;
 
+            failures.append(atEndOfInput());
             loadFromFrame(parenthesesFrameLocation + BackTrackInfoBackReference::matchAmountIndex(), matchAmount);
             if (term->quantityMaxCount != quantifyInfinite)
                 failures.append(branch32(AboveOrEqual, Imm32(term->quantityMaxCount.unsafeGet()), matchAmount));
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to