Changeset 186920 in webkit


Ignore:
Timestamp:
Jul 16, 2015, 7:27:22 PM (10 years ago)
Author:
mark.lam@apple.com
Message:

RegExp::match() should set m_state to ByteCode if compilation fails.
https://bugs.webkit.org/show_bug.cgi?id=147023

Reviewed by Michael Saboff.

A RegExp has a YarrCodeBlock that has 4 MacroAssemblerCodeRefs for compiled code.
If one of these compilations succeeds, RegExp::m_state will be set to JITCode.
Subsequently, if RegExp tries to compile another one of these but fails, m_state
will be left untouched i.e. it still says JITCode. As a result, when
RegExp::match() later tries to execute the non-existant compiled code, it will
crash.

The fix is to downgrade m_state to ByteCode if RegExp ever fails to compile.
This failure should be rare. We'll do the minimal work here to fix the issue and
keep an eye on the perf bots. If perf regresses, we can do some optimization work then.

This issue is difficult to test for since it either requires a low memory condition
to trigger a failed RegExp compilation at the right moment, or for the RegExp to
succeed compilation in the MatchedOnly mode but fail in IncludeSubpatterns mode.
Instead, I manually tested it by instrumenting RegExp::compile() to fail once in every
10 compilation attempts.

  • runtime/RegExp.cpp:

(JSC::RegExp::compile):
(JSC::RegExp::compileMatchOnly):

Location:
trunk/Source/JavaScriptCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r186880 r186920  
     12015-07-16  Mark Lam  <mark.lam@apple.com>
     2
     3        RegExp::match() should set m_state to ByteCode if compilation fails.
     4        https://bugs.webkit.org/show_bug.cgi?id=147023
     5
     6        Reviewed by Michael Saboff.
     7
     8        A RegExp has a YarrCodeBlock that has 4 MacroAssemblerCodeRefs for compiled code.
     9        If one of these compilations succeeds, RegExp::m_state will be set to JITCode.
     10        Subsequently, if RegExp tries to compile another one of these but fails, m_state
     11        will be left untouched i.e. it still says JITCode.  As a result, when
     12        RegExp::match() later tries to execute the non-existant compiled code, it will
     13        crash.
     14
     15        The fix is to downgrade m_state to ByteCode if RegExp ever fails to compile.
     16        This failure should be rare.  We'll do the minimal work here to fix the issue and
     17        keep an eye on the perf bots.  If perf regresses, we can do some optimization work then.
     18
     19        This issue is difficult to test for since it either requires a low memory condition
     20        to trigger a failed RegExp compilation at the right moment, or for the RegExp to
     21        succeed compilation in the MatchedOnly mode but fail in IncludeSubpatterns mode.
     22        Instead, I manually tested it by instrumenting RegExp::compile() to fail once in every
     23        10 compilation attempts.
     24
     25        * runtime/RegExp.cpp:
     26        (JSC::RegExp::compile):
     27        (JSC::RegExp::compileMatchOnly):
     28
    1292015-07-15  Brent Fulgham  <bfulgham@apple.com>
    230
  • trunk/Source/JavaScriptCore/runtime/RegExp.cpp

    r184291 r186920  
    290290    if (!pattern.m_containsBackreferences && !pattern.containsUnsignedLengthPattern() && vm->canUseRegExpJIT()) {
    291291        Yarr::jitCompile(pattern, charSize, vm, m_regExpJITCode);
    292 #if ENABLE(YARR_JIT_DEBUG)
    293         if (!m_regExpJITCode.isFallBack())
    294             m_state = JITCode;
    295         else
    296             m_state = ByteCode;
    297 #else
    298292        if (!m_regExpJITCode.isFallBack()) {
    299293            m_state = JITCode;
    300294            return;
    301295        }
    302 #endif
    303296    }
    304297#else
     
    306299#endif
    307300
     301    m_state = ByteCode;
    308302    m_regExpBytecode = Yarr::byteCompile(pattern, &vm->m_regExpAllocator);
    309303}
     
    415409    if (!pattern.m_containsBackreferences && !pattern.containsUnsignedLengthPattern() && vm->canUseRegExpJIT()) {
    416410        Yarr::jitCompile(pattern, charSize, vm, m_regExpJITCode, Yarr::MatchOnly);
    417 #if ENABLE(YARR_JIT_DEBUG)
    418         if (!m_regExpJITCode.isFallBack())
    419             m_state = JITCode;
    420         else
    421             m_state = ByteCode;
    422 #else
    423411        if (!m_regExpJITCode.isFallBack()) {
    424412            m_state = JITCode;
    425413            return;
    426414        }
    427 #endif
    428415    }
    429416#else
     
    431418#endif
    432419
     420    m_state = ByteCode;
    433421    m_regExpBytecode = Yarr::byteCompile(pattern, &vm->m_regExpAllocator);
    434422}
Note: See TracChangeset for help on using the changeset viewer.