Changeset 209022 in webkit


Ignore:
Timestamp:
Nov 28, 2016 2:35:39 PM (7 years ago)
Author:
mark.lam@apple.com
Message:

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

Reviewed by Saam Barati.

  • runtime/StringConstructor.cpp:

(JSC::stringFromCodePoint):
(JSC::constructWithStringConstructor):

  • runtime/StringObject.cpp:

(JSC::StringObject::put):
(JSC::StringObject::putByIndex):
(JSC::StringObject::defineOwnProperty):

  • runtime/StringPrototype.cpp:

(JSC::jsSpliceSubstrings):
(JSC::jsSpliceSubstringsWithSeparators):
(JSC::replaceUsingRegExpSearch):
(JSC::replaceUsingStringSearch):
(JSC::repeatCharacter):
(JSC::replace):
(JSC::stringProtoFuncReplaceUsingStringSearch):
(JSC::stringProtoFuncCharAt):
(JSC::stringProtoFuncCodePointAt):
(JSC::stringProtoFuncConcat):
(JSC::stringProtoFuncIndexOf):
(JSC::stringProtoFuncLastIndexOf):
(JSC::splitStringByOneCharacterImpl):
(JSC::stringProtoFuncSplitFast):
(JSC::stringProtoFuncSubstring):
(JSC::stringProtoFuncToLowerCase):
(JSC::stringProtoFuncToUpperCase):
(JSC::toLocaleCase):
(JSC::trimString):
(JSC::stringProtoFuncIncludes):
(JSC::builtinStringIncludesInternal):
(JSC::stringProtoFuncIterator):
(JSC::normalize):
(JSC::stringProtoFuncNormalize):

Location:
trunk/Source/JavaScriptCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r209020 r209022  
     12016-11-28  Mark Lam  <mark.lam@apple.com>
     2
     3        Fix exception scope verification failures in runtime/String* files.
     4        https://bugs.webkit.org/show_bug.cgi?id=165067
     5
     6        Reviewed by Saam Barati.
     7
     8        * runtime/StringConstructor.cpp:
     9        (JSC::stringFromCodePoint):
     10        (JSC::constructWithStringConstructor):
     11        * runtime/StringObject.cpp:
     12        (JSC::StringObject::put):
     13        (JSC::StringObject::putByIndex):
     14        (JSC::StringObject::defineOwnProperty):
     15        * runtime/StringPrototype.cpp:
     16        (JSC::jsSpliceSubstrings):
     17        (JSC::jsSpliceSubstringsWithSeparators):
     18        (JSC::replaceUsingRegExpSearch):
     19        (JSC::replaceUsingStringSearch):
     20        (JSC::repeatCharacter):
     21        (JSC::replace):
     22        (JSC::stringProtoFuncReplaceUsingStringSearch):
     23        (JSC::stringProtoFuncCharAt):
     24        (JSC::stringProtoFuncCodePointAt):
     25        (JSC::stringProtoFuncConcat):
     26        (JSC::stringProtoFuncIndexOf):
     27        (JSC::stringProtoFuncLastIndexOf):
     28        (JSC::splitStringByOneCharacterImpl):
     29        (JSC::stringProtoFuncSplitFast):
     30        (JSC::stringProtoFuncSubstring):
     31        (JSC::stringProtoFuncToLowerCase):
     32        (JSC::stringProtoFuncToUpperCase):
     33        (JSC::toLocaleCase):
     34        (JSC::trimString):
     35        (JSC::stringProtoFuncIncludes):
     36        (JSC::builtinStringIncludesInternal):
     37        (JSC::stringProtoFuncIterator):
     38        (JSC::normalize):
     39        (JSC::stringProtoFuncNormalize):
     40
    1412016-11-28  Mark Lam  <mark.lam@apple.com>
    242
  • trunk/Source/JavaScriptCore/runtime/StringConstructor.cpp

    r208063 r209022  
    115115    }
    116116
     117    scope.release();
    117118    return JSValue::encode(jsString(exec, builder.toString()));
    118119}
     
    129130    if (!exec->argumentCount())
    130131        return JSValue::encode(StringObject::create(vm, structure));
    131     return JSValue::encode(StringObject::create(vm, structure, exec->uncheckedArgument(0).toString(exec)));
     132    JSString* str = exec->uncheckedArgument(0).toString(exec);
     133    RETURN_IF_EXCEPTION(scope, encodedJSValue());
     134    return JSValue::encode(StringObject::create(vm, structure, str));
    132135}
    133136
  • trunk/Source/JavaScriptCore/runtime/StringObject.cpp

    r208985 r209022  
    6868    StringObject* thisObject = jsCast<StringObject*>(cell);
    6969
    70     if (UNLIKELY(isThisValueAltered(slot, thisObject)))
     70    if (UNLIKELY(isThisValueAltered(slot, thisObject))) {
     71        scope.release();
    7172        return ordinarySetSlow(exec, thisObject, propertyName, value, slot.thisValue(), slot.isStrictMode());
     73    }
    7274
    7375    if (propertyName == vm.propertyNames->length)
    7476        return typeError(exec, scope, slot.isStrictMode(), ASCIILiteral(ReadonlyPropertyWriteError));
    75     if (std::optional<uint32_t> index = parseIndex(propertyName))
     77    if (std::optional<uint32_t> index = parseIndex(propertyName)) {
     78        scope.release();
    7679        return putByIndex(cell, exec, index.value(), value, slot.isStrictMode());
     80    }
     81    scope.release();
    7782    return JSObject::put(cell, exec, propertyName, value, slot);
    7883}
     
    8691    if (thisObject->internalValue()->canGetIndex(propertyName))
    8792        return typeError(exec, scope, shouldThrow, ASCIILiteral(ReadonlyPropertyWriteError));
     93    scope.release();
    8894    return JSObject::putByIndex(cell, exec, propertyName, value, shouldThrow);
    8995}
     
    117123        bool isExtensible = thisObject->isExtensible(exec);
    118124        RETURN_IF_EXCEPTION(scope, false);
     125        scope.release();
    119126        return validateAndApplyPropertyDescriptor(exec, nullptr, propertyName, isExtensible, descriptor, isCurrentDefined, current, throwException);
    120127    }
    121128
     129    scope.release();
    122130    return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
    123131}
  • trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp

    r208767 r209022  
    298298            return sourceVal;
    299299        // We could call String::substringSharingImpl(), but this would result in redundant checks.
     300        scope.release();
    300301        return jsString(exec, StringImpl::createSubstringSharingImpl(*source.impl(), std::max(0, position), std::min(sourceSize, length)));
    301302    }
     
    323324        }
    324325
     326        scope.release();
    325327        return jsString(exec, WTFMove(impl));
    326328    }
     
    341343    }
    342344
     345    scope.release();
    343346    return jsString(exec, WTFMove(impl));
    344347}
     
    356359            return sourceVal;
    357360        // We could call String::substringSharingImpl(), but this would result in redundant checks.
     361        scope.release();
    358362        return jsString(exec, StringImpl::createSubstringSharingImpl(*source.impl(), std::max(0, position), std::min(sourceSize, length)));
    359363    }
     
    399403        }       
    400404
     405        scope.release();
    401406        return jsString(exec, WTFMove(impl));
    402407    }
     
    430435    }
    431436
     437    scope.release();
    432438    return jsString(exec, WTFMove(impl));
    433439}
     
    628634                args.append(string);
    629635
    630                 JSValue value = call(exec, replaceValue, callType, callData, jsUndefined(), args);
     636                JSValue replacement = call(exec, replaceValue, callType, callData, jsUndefined(), args);
    631637                RETURN_IF_EXCEPTION(scope, encodedJSValue());
    632                 replacements.append(value.toString(exec)->value(exec));
     638                String replacementString = replacement.toString(exec)->value(exec);
     639                RETURN_IF_EXCEPTION(scope, encodedJSValue());
     640                replacements.append(replacementString);
    633641                RETURN_IF_EXCEPTION(scope, encodedJSValue());
    634642            } else {
     
    664672            OUT_OF_MEMORY(exec, scope);
    665673    }
     674    scope.release();
    666675    return JSValue::encode(jsSpliceSubstringsWithSeparators(exec, string, source, sourceRanges.data(), sourceRanges.size(), replacements.data(), replacements.size()));
    667676}
     
    755764    size_t leftLength = stringImpl->length() - matchEnd;
    756765    String rightPart(StringImpl::createSubstringSharingImpl(*stringImpl, matchEnd, leftLength));
     766    scope.release();
    757767    return JSValue::encode(JSC::jsString(exec, leftPart, middlePart, rightPart));
    758768}
     
    787797    std::fill_n(buffer, repeatCount, character);
    788798
     799    scope.release();
    789800    return jsString(&exec, WTFMove(impl));
    790801}
     
    840851    JSString* string = thisValue.toString(exec);
    841852    RETURN_IF_EXCEPTION(scope, encodedJSValue());
     853    scope.release();
    842854    return replace(vm, exec, string, searchValue, replaceValue);
    843855}
     
    867879    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    868880
     881    scope.release();
    869882    return replaceUsingStringSearch(vm, exec, string, exec->argument(0), exec->argument(1));
    870883}
     
    910923    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    911924    StringView view = viewWithString.view;
     925    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    912926    JSValue a0 = exec->argument(0);
    913927    if (a0.isUInt32()) {
     
    967981
    968982    String string = thisValue.toWTFString(exec);
     983    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    969984    unsigned length = string.length();
    970985
     
    980995
    981996    double doublePosition = argument0.toInteger(exec);
     997    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    982998    if (doublePosition >= 0 && doublePosition < length)
    983999        return JSValue::encode(jsNumber(codePointAt(string, static_cast<unsigned>(doublePosition), length)));
     
    9911007
    9921008    JSValue thisValue = exec->thisValue();
    993     if (thisValue.isString() && exec->argumentCount() == 1)
    994         return JSValue::encode(jsString(exec, asString(thisValue), exec->uncheckedArgument(0).toString(exec)));
    995 
    996     if (!checkObjectCoercible(thisValue))
    997         return throwVMTypeError(exec, scope);
     1009    if (thisValue.isString() && exec->argumentCount() == 1) {
     1010        JSString* str = exec->uncheckedArgument(0).toString(exec);
     1011        RETURN_IF_EXCEPTION(scope, encodedJSValue());
     1012        scope.release();
     1013        return JSValue::encode(jsString(exec, asString(thisValue), str));
     1014    }
     1015
     1016    if (!checkObjectCoercible(thisValue))
     1017        return throwVMTypeError(exec, scope);
     1018    scope.release();
    9981019    return JSValue::encode(jsStringFromArguments(exec, thisValue));
    9991020}
     
    10121033
    10131034    JSString* thisJSString = thisValue.toString(exec);
     1035    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    10141036    JSString* otherJSString = a0.toString(exec);
     1037    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    10151038
    10161039    unsigned pos = 0;
     
    10561079
    10571080    JSString* thisJSString = thisValue.toString(exec);
     1081    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    10581082    unsigned len = thisJSString->length();
    10591083    JSString* otherJSString = a0.toString(exec);
     1084    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    10601085
    10611086    double dpos = a1.toIntegerPreserveNaN(exec);
     
    11201145static ALWAYS_INLINE bool splitStringByOneCharacterImpl(ExecState* exec, JSArray* result, JSValue originalValue, const String& input, StringImpl* string, UChar separatorCharacter, size_t& position, unsigned& resultLength, unsigned limitLength)
    11211146{
     1147    VM& vm = exec->vm();
     1148    auto scope = DECLARE_THROW_SCOPE(vm);
     1149
    11221150    // 12. Let q = p.
    11231151    size_t matchPosition;
     
    11331161        //    Property Descriptor {[[Value]]: T, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false.
    11341162        result->putDirectIndex(exec, resultLength, jsSubstring(exec, originalValue, input, position, matchPosition - position));
     1163        RETURN_IF_EXCEPTION(scope, false);
    11351164        // 3. Increment lengthA by 1.
    11361165        // 4. If lengthA == lim, return A.
     
    11871216    if (separatorValue.isUndefined()) {
    11881217        // a. Call the [[DefineOwnProperty]] internal method of A with arguments "0",
     1218        scope.release();
    11891219        result->putDirectIndex(exec, 0, jsStringWithReuse(exec, thisValue, input));
    11901220        // b. Return A.
     
    11981228        // c. Call CreateDataProperty(A, "0", S).
    11991229        // d. Return A.
    1200         if (!separator.isEmpty())
     1230        if (!separator.isEmpty()) {
     1231            scope.release();
    12011232            result->putDirectIndex(exec, 0, jsStringWithReuse(exec, thisValue, input));
     1233        }
    12021234        return JSValue::encode(result);
    12031235    }
     
    12111243        do {
    12121244            result->putDirectIndex(exec, position, jsSingleCharacterString(exec, input[position]));
     1245            RETURN_IF_EXCEPTION(scope, encodedJSValue());
    12131246        } while (++position < limit);
    12141247
     
    12321265
    12331266        if (stringImpl->is8Bit()) {
    1234             if (splitStringByOneCharacterImpl<LChar>(exec, result, thisValue, input, stringImpl, separatorCharacter, position, resultLength, limit))
     1267            if (splitStringByOneCharacterImpl<LChar>(exec, result, thisValue, input, stringImpl, separatorCharacter, position, resultLength, limit)) {
     1268                scope.release();
    12351269                return JSValue::encode(result);
     1270            }
    12361271        } else {
    1237             if (splitStringByOneCharacterImpl<UChar>(exec, result, thisValue, input, stringImpl, separatorCharacter, position, resultLength, limit))
     1272            if (splitStringByOneCharacterImpl<UChar>(exec, result, thisValue, input, stringImpl, separatorCharacter, position, resultLength, limit)) {
     1273                scope.release();
    12381274                return JSValue::encode(result);
     1275            }
    12391276        }
     1277        RETURN_IF_EXCEPTION(scope, encodedJSValue());
    12401278    } else {
    12411279        // 13. Let q = p.
     
    12501288            // 2. Call CreateDataProperty(A, ToString(lengthA), T).
    12511289            result->putDirectIndex(exec, resultLength, jsSubstring(exec, thisValue, input, position, matchPosition - position));
     1290            RETURN_IF_EXCEPTION(scope, encodedJSValue());
    12521291            // 3. Increment lengthA by 1.
    12531292            // 4. If lengthA == lim, return A.
     
    12641303    //     through s (exclusive).
    12651304    // 16. Call CreateDataProperty(A, ToString(lengthA), T).
     1305    scope.release();
    12661306    result->putDirectIndex(exec, resultLength++, jsSubstring(exec, thisValue, input, position, input.length() - position));
    12671307
     
    13461386
    13471387    double start = a0.toNumber(exec);
     1388    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    13481389    double end;
    13491390    if (!(start >= 0)) // check for negative values or NaN
     
    13551396    else {
    13561397        end = a1.toNumber(exec);
     1398        RETURN_IF_EXCEPTION(scope, encodedJSValue());
    13571399        if (!(end >= 0)) // check for negative values or NaN
    13581400            end = 0;
     
    13791421        return throwVMTypeError(exec, scope);
    13801422    JSString* sVal = thisValue.toString(exec);
     1423    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    13811424    const String& s = sVal->value(exec);
    13821425    String lowercasedString = s.convertToLowercaseWithoutLocale();
    13831426    if (lowercasedString.impl() == s.impl())
    13841427        return JSValue::encode(sVal);
     1428    scope.release();
    13851429    return JSValue::encode(jsString(exec, lowercasedString));
    13861430}
     
    13951439        return throwVMTypeError(exec, scope);
    13961440    JSString* sVal = thisValue.toString(exec);
     1441    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    13971442    const String& s = sVal->value(exec);
    13981443    String uppercasedString = s.convertToUppercaseWithoutLocale();
    13991444    if (uppercasedString.impl() == s.impl())
    14001445        return JSValue::encode(sVal);
     1446    scope.release();
    14011447    return JSValue::encode(jsString(exec, uppercasedString));
    14021448}
     
    14321478    // 2. Let S be ToString(O).
    14331479    JSString* sVal = thisValue.toString(state);
     1480    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    14341481    const String& s = sVal->value(state);
    14351482
     
    15001547
    15011548    // 18. Return L.
     1549    scope.release();
    15021550    return JSValue::encode(jsString(state, lower));
    15031551}
     
    17941842        return throwTypeError(exec, scope);
    17951843    String str = thisValue.toString(exec)->value(exec);
    1796     RETURN_IF_EXCEPTION(scope, JSValue());
     1844    RETURN_IF_EXCEPTION(scope, { });
    17971845
    17981846    unsigned left = 0;
     
    18111859        return thisValue;
    18121860
     1861    scope.release();
    18131862    return jsString(exec, str.substringSharingImpl(left, right - left));
    18141863}
     
    19481997    JSValue positionArg = exec->argument(1);
    19491998
     1999    scope.release();
    19502000    return stringIncludesImpl(vm, exec, stringToSearchIn, searchString, positionArg);
    19512001}
     
    19682018    JSValue positionArg = exec->argument(1);
    19692019
     2020    scope.release();
    19702021    return stringIncludesImpl(vm, exec, stringToSearchIn, searchString, positionArg);
    19712022}
     
    19802031        return throwVMTypeError(exec, scope);
    19812032    JSString* string = thisValue.toString(exec);
     2033    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    19822034    return JSValue::encode(JSStringIterator::create(exec, exec->callee()->globalObject()->stringIteratorStructure(), string));
    19832035}
     
    20072059        return throwTypeError(exec, scope);
    20082060
     2061    scope.release();
    20092062    return jsString(exec, WTFMove(impl));
    20102063}
     
    20402093    }
    20412094
     2095    scope.release();
    20422096    return JSValue::encode(normalize(exec, view.upconvertedCharacters(), view.length(), form));
    20432097}
Note: See TracChangeset for help on using the changeset viewer.