Changeset 209101 in webkit


Ignore:
Timestamp:
Nov 29, 2016 4:06:50 PM (7 years ago)
Author:
mark.lam@apple.com
Message:

Fix exception scope verification failures in runtime/RegExp* files.
https://bugs.webkit.org/show_bug.cgi?id=165054

Reviewed by Saam Barati.

Also replaced returning JSValue() with returning { }.

  • runtime/RegExpConstructor.cpp:

(JSC::toFlags):
(JSC::regExpCreate):
(JSC::constructRegExp):

  • runtime/RegExpObject.cpp:

(JSC::RegExpObject::defineOwnProperty):
(JSC::collectMatches):
(JSC::RegExpObject::matchGlobal):

  • runtime/RegExpObjectInlines.h:

(JSC::getRegExpObjectLastIndexAsUnsigned):
(JSC::RegExpObject::execInline):
(JSC::RegExpObject::matchInline):

  • runtime/RegExpPrototype.cpp:

(JSC::regExpProtoFuncCompile):
(JSC::flagsString):
(JSC::regExpProtoFuncToString):
(JSC::regExpProtoFuncSplitFast):

Location:
trunk/Source/JavaScriptCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r209088 r209101  
     12016-11-29  Mark Lam  <mark.lam@apple.com>
     2
     3        Fix exception scope verification failures in runtime/RegExp* files.
     4        https://bugs.webkit.org/show_bug.cgi?id=165054
     5
     6        Reviewed by Saam Barati.
     7
     8        Also replaced returning JSValue() with returning { }.
     9
     10        * runtime/RegExpConstructor.cpp:
     11        (JSC::toFlags):
     12        (JSC::regExpCreate):
     13        (JSC::constructRegExp):
     14        * runtime/RegExpObject.cpp:
     15        (JSC::RegExpObject::defineOwnProperty):
     16        (JSC::collectMatches):
     17        (JSC::RegExpObject::matchGlobal):
     18        * runtime/RegExpObjectInlines.h:
     19        (JSC::getRegExpObjectLastIndexAsUnsigned):
     20        (JSC::RegExpObject::execInline):
     21        (JSC::RegExpObject::matchInline):
     22        * runtime/RegExpPrototype.cpp:
     23        (JSC::regExpProtoFuncCompile):
     24        (JSC::flagsString):
     25        (JSC::regExpProtoFuncToString):
     26        (JSC::regExpProtoFuncSplitFast):
     27
    1282016-11-29  Andy Estes  <aestes@apple.com>
    229
  • trunk/Source/JavaScriptCore/runtime/RegExpConstructor.cpp

    r206386 r209101  
    215215    if (flags.isUndefined())
    216216        return NoFlags;
    217     JSString* flagsString = flags.toString(exec);
    218     ASSERT(scope.exception() || flagsString);
    219     if (!flagsString) {
     217    JSString* flagsString = flags.toStringOrNull(exec);
     218    ASSERT(!!scope.exception() == !flagsString);
     219    if (UNLIKELY(!flagsString))
    220220        return InvalidFlags;
    221     }
    222221
    223222    RegExpFlags result = regExpFlags(flagsString->value(exec));
     
    237236
    238237    RegExpFlags flags = toFlags(exec, flagsArg);
    239     if (flags == InvalidFlags)
     238    ASSERT(!!scope.exception() == (flags == InvalidFlags));
     239    if (UNLIKELY(flags == InvalidFlags))
    240240        return nullptr;
    241241
     
    258258    bool isPatternRegExp = patternArg.inherits(RegExpObject::info());
    259259    bool constructAsRegexp = isRegExp(vm, exec, patternArg);
     260    RETURN_IF_EXCEPTION(scope, nullptr);
    260261
    261262    if (newTarget.isUndefined() && constructAsRegexp && flagsArg.isUndefined()) {
     
    275276        if (!flagsArg.isUndefined()) {
    276277            RegExpFlags flags = toFlags(exec, flagsArg);
     278            ASSERT(!!scope.exception() == (flags == InvalidFlags));
    277279            if (flags == InvalidFlags)
    278280                return nullptr;
     
    280282        }
    281283
    282         return RegExpObject::create(exec->vm(), structure, regExp);
     284        return RegExpObject::create(vm, structure, regExp);
    283285    }
    284286
    285287    if (constructAsRegexp) {
    286288        JSValue pattern = patternArg.get(exec, vm.propertyNames->source);
    287         if (flagsArg.isUndefined())
     289        RETURN_IF_EXCEPTION(scope, nullptr);
     290        if (flagsArg.isUndefined()) {
    288291            flagsArg = patternArg.get(exec, vm.propertyNames->flags);
     292            RETURN_IF_EXCEPTION(scope, nullptr);
     293        }
    289294        patternArg = pattern;
    290295    }
    291296
     297    scope.release();
    292298    return regExpCreate(exec, globalObject, newTarget, patternArg, flagsArg);
    293299}
  • trunk/Source/JavaScriptCore/runtime/RegExpObject.cpp

    r207859 r209101  
    120120            return true;
    121121        }
    122         if (descriptor.value())
     122        if (descriptor.value()) {
    123123            regExp->setLastIndex(exec, descriptor.value(), false);
     124            RETURN_IF_EXCEPTION(scope, false);
     125        }
    124126        if (descriptor.writablePresent() && !descriptor.writable())
    125127            regExp->m_lastIndexIsWritable = false;
     
    127129    }
    128130
     131    scope.release();
    129132    return Base::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow);
    130133}
     
    180183   
    181184    JSArray* array = constructEmptyArray(exec, nullptr);
    182     RETURN_IF_EXCEPTION(scope, JSValue());
    183 
     185    RETURN_IF_EXCEPTION(scope, { });
     186
     187    bool hasException = false;
    184188    auto iterate = [&] () {
    185189        size_t end = result.end;
    186190        size_t length = end - result.start;
    187191        array->push(exec, JSRopeString::createSubstringOfResolved(vm, string, result.start, length));
     192        if (UNLIKELY(scope.exception())) {
     193            hasException = true;
     194            return;
     195        }
    188196        if (!length)
    189197            end = fixEnd(end);
     
    217225            // OK, we have a sensible number of matches. Now we can create them for reals.
    218226            result = savedResult;
    219             do
     227            do {
    220228                iterate();
    221             while (result);
     229                ASSERT(!!scope.exception() == hasException);
     230                if (UNLIKELY(hasException))
     231                    return { };
     232            } while (result);
    222233           
    223234            return array;
     
    239250
    240251    setLastIndex(exec, 0);
    241     RETURN_IF_EXCEPTION(scope, JSValue());
     252    RETURN_IF_EXCEPTION(scope, { });
    242253
    243254    String s = string->value(exec);
     
    246257    if (regExp->unicode()) {
    247258        unsigned stringLength = s.length();
     259        scope.release();
    248260        return collectMatches(
    249261            vm, exec, string, s, regExpConstructor, regExp,
     
    252264            });
    253265    }
    254    
     266
     267    scope.release();
    255268    return collectMatches(
    256269        vm, exec, string, s, regExpConstructor, regExp,
  • trunk/Source/JavaScriptCore/runtime/RegExpObjectInlines.h

    r208698 r209101  
    3737    ExecState* exec, RegExpObject* regExpObject, const String& input)
    3838{
     39    VM& vm = exec->vm();
     40    auto scope = DECLARE_THROW_SCOPE(vm);
    3941    JSValue jsLastIndex = regExpObject->getLastIndex();
    4042    unsigned lastIndex;
     
    4244        lastIndex = jsLastIndex.asUInt32();
    4345        if (lastIndex > input.length()) {
     46            scope.release();
    4447            regExpObject->setLastIndex(exec, 0);
    4548            return UINT_MAX;
     
    4750    } else {
    4851        double doubleLastIndex = jsLastIndex.toInteger(exec);
     52        RETURN_IF_EXCEPTION(scope, UINT_MAX);
    4953        if (doubleLastIndex < 0 || doubleLastIndex > input.length()) {
     54            scope.release();
    5055            regExpObject->setLastIndex(exec, 0);
    5156            return UINT_MAX;
     
    6469    RegExpConstructor* regExpConstructor = globalObject->regExpConstructor();
    6570    String input = string->value(exec);
    66     RETURN_IF_EXCEPTION(scope, JSValue());
     71    RETURN_IF_EXCEPTION(scope, { });
    6772
    6873    bool globalOrSticky = regExp->globalOrSticky();
     
    7176    if (globalOrSticky) {
    7277        lastIndex = getRegExpObjectLastIndexAsUnsigned(exec, this, input);
     78        ASSERT(!scope.exception() || lastIndex == UINT_MAX);
    7379        if (lastIndex == UINT_MAX)
    7480            return jsNull();
     
    8086        createRegExpMatchesArray(vm, globalObject, string, input, regExp, lastIndex, result);
    8187    if (!array) {
     88        scope.release();
    8289        if (globalOrSticky)
    8390            setLastIndex(exec, 0);
     
    8794    if (globalOrSticky)
    8895        setLastIndex(exec, result.end);
     96    RETURN_IF_EXCEPTION(scope, { });
    8997    regExpConstructor->recordMatch(vm, regExp, string, result);
    9098    return array;
     
    101109    RegExpConstructor* regExpConstructor = globalObject->regExpConstructor();
    102110    String input = string->value(exec);
    103     RETURN_IF_EXCEPTION(scope, MatchResult());
     111    RETURN_IF_EXCEPTION(scope, { });
    104112
    105113    if (!regExp->global() && !regExp->sticky())
     
    107115
    108116    unsigned lastIndex = getRegExpObjectLastIndexAsUnsigned(exec, this, input);
     117    ASSERT(!scope.exception() || (lastIndex == UINT_MAX));
    109118    if (lastIndex == UINT_MAX)
    110119        return MatchResult::failed();
    111120   
    112121    MatchResult result = regExpConstructor->performMatch(vm, regExp, string, input, lastIndex);
     122    scope.release();
    113123    setLastIndex(exec, result.end);
    114124    return result;
  • trunk/Source/JavaScriptCore/runtime/RegExpPrototype.cpp

    r208698 r209101  
    184184
    185185    asRegExpObject(thisValue)->setRegExp(vm, regExp);
     186    scope.release();
    186187    asRegExpObject(thisValue)->setLastIndex(exec, 0);
    187188    return JSValue::encode(thisValue);
     
    198199    auto scope = DECLARE_THROW_SCOPE(vm);
    199200
    200     JSValue globalValue = regexp->get(exec, exec->propertyNames().global);
     201    JSValue globalValue = regexp->get(exec, vm.propertyNames->global);
    201202    RETURN_IF_EXCEPTION(scope, string);
    202     JSValue ignoreCaseValue = regexp->get(exec, exec->propertyNames().ignoreCase);
     203    JSValue ignoreCaseValue = regexp->get(exec, vm.propertyNames->ignoreCase);
    203204    RETURN_IF_EXCEPTION(scope, string);
    204     JSValue multilineValue = regexp->get(exec, exec->propertyNames().multiline);
     205    JSValue multilineValue = regexp->get(exec, vm.propertyNames->multiline);
    205206    RETURN_IF_EXCEPTION(scope, string);
    206     JSValue unicodeValue = regexp->get(exec, exec->propertyNames().unicode);
     207    JSValue unicodeValue = regexp->get(exec, vm.propertyNames->unicode);
    207208    RETURN_IF_EXCEPTION(scope, string);
    208     JSValue stickyValue = regexp->get(exec, exec->propertyNames().sticky);
     209    JSValue stickyValue = regexp->get(exec, vm.propertyNames->sticky);
    209210    RETURN_IF_EXCEPTION(scope, string);
    210211
     
    237238
    238239    StringRecursionChecker checker(exec, thisObject);
     240    ASSERT(!scope.exception() || checker.earlyReturnValue());
    239241    if (JSValue earlyReturnValue = checker.earlyReturnValue())
    240242        return JSValue::encode(earlyReturnValue);
     
    622624        // c. Perform ! CreateDataProperty(A, "0", S).
    623625        // d. Return A.
    624         if (!regexp->match(vm, input, 0))
     626        if (!regexp->match(vm, input, 0)) {
    625627            result->putDirectIndex(exec, 0, inputString);
     628            RETURN_IF_EXCEPTION(scope, encodedJSValue());
     629        }
    626630        return JSValue::encode(result);
    627631    }
     
    644648        [&] (bool isDefined, unsigned start, unsigned length) -> SplitControl {
    645649            result->putDirectIndex(exec, resultLength++, isDefined ? JSRopeString::createSubstringOfResolved(vm, inputString, start, length) : jsUndefined());
     650            RETURN_IF_EXCEPTION(scope, AbortSplit);
    646651            if (resultLength >= limit)
    647652                return AbortSplit;
    648653            return ContinueSplit;
    649654        });
    650    
     655    RETURN_IF_EXCEPTION(scope, encodedJSValue());
     656
    651657    if (resultLength >= limit)
    652658        return JSValue::encode(result);
     
    654660        // 20. Let T be a String value equal to the substring of S consisting of the elements at indices p (inclusive) through size (exclusive).
    655661        // 21. Perform ! CreateDataProperty(A, ! ToString(lengthA), T).
     662        scope.release();
    656663        result->putDirectIndex(exec, resultLength, JSRopeString::createSubstringOfResolved(vm, inputString, position, inputSize - position));
    657664       
     
    680687    if (resultLength + dryRunCount >= MAX_STORAGE_VECTOR_LENGTH) {
    681688        throwOutOfMemoryError(exec, scope);
    682         return JSValue::encode(jsUndefined());
     689        return encodedJSValue();
    683690    }
    684691   
     
    694701        [&] (bool isDefined, unsigned start, unsigned length) -> SplitControl {
    695702            result->putDirectIndex(exec, resultLength++, isDefined ? JSRopeString::createSubstringOfResolved(vm, inputString, start, length) : jsUndefined());
     703            RETURN_IF_EXCEPTION(scope, AbortSplit);
    696704            if (resultLength >= limit)
    697705                return AbortSplit;
    698706            return ContinueSplit;
    699707        });
    700    
     708    RETURN_IF_EXCEPTION(scope, encodedJSValue());
     709
    701710    if (resultLength >= limit)
    702711        return JSValue::encode(result);
     
    704713    // 20. Let T be a String value equal to the substring of S consisting of the elements at indices p (inclusive) through size (exclusive).
    705714    // 21. Perform ! CreateDataProperty(A, ! ToString(lengthA), T).
     715    scope.release();
    706716    result->putDirectIndex(exec, resultLength, JSRopeString::createSubstringOfResolved(vm, inputString, position, inputSize - position));
    707717    // 22. Return A.
Note: See TracChangeset for help on using the changeset viewer.