Ignore:
Timestamp:
Mar 12, 2019, 6:26:29 PM (6 years ago)
Author:
[email protected]
Message:

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/JavaScriptCore:

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):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/yarr/YarrJIT.cpp

    r241634 r242838  
    11991199            // PatternTemp should contain pattern end index at this point
    12001200            sub32(patternIndex, patternTemp);
    1201             if (m_checkedOffset - term->inputPosition)
    1202                 sub32(Imm32((m_checkedOffset - term->inputPosition).unsafeGet()), patternTemp);
    12031201            op.m_jumps.append(checkNotEnoughInput(patternTemp));
    12041202
     
    12251223            // PatternTemp should contain pattern end index at this point
    12261224            sub32(patternIndex, patternTemp);
    1227             if (m_checkedOffset - term->inputPosition)
    1228                 sub32(Imm32((m_checkedOffset - term->inputPosition).unsafeGet()), patternTemp);
    12291225            matches.append(checkNotEnoughInput(patternTemp));
    12301226
     
    12711267            // Check if we have input remaining to match
    12721268            sub32(patternIndex, patternTemp);
    1273             if (m_checkedOffset - term->inputPosition)
    1274                 sub32(Imm32((m_checkedOffset - term->inputPosition).unsafeGet()), patternTemp);
    12751269            matches.append(checkNotEnoughInput(patternTemp));
    12761270
     
    13291323            const RegisterID matchAmount = regT0;
    13301324
     1325            failures.append(atEndOfInput());
    13311326            loadFromFrame(parenthesesFrameLocation + BackTrackInfoBackReference::matchAmountIndex(), matchAmount);
    13321327            if (term->quantityMaxCount != quantifyInfinite)
Note: See TracChangeset for help on using the changeset viewer.