Ignore:
Timestamp:
Dec 18, 2015, 6:32:46 PM (10 years ago)
Author:
[email protected]
Message:

Make JSString::SafeView less of a footgun.
<https://webkit.org/b/152376>

Reviewed by Darin Adler.

Remove the "operator StringView()" convenience helper on JSString::SafeString since that
made it possible to casually turn the return value from JSString::view() into an unsafe
StringView local on the stack with this pattern:

StringView view = someJSValue.toString(exec)->view(exec);

The JSString* returned by toString() above will go out of scope by the end of the statement
and does not stick around to protect itself from garbage collection.

It will now look like this instead:

JSString::SafeView view = someJSValue.toString(exec)->view(exec);

To be extra clear, the following is not safe:

StringView view = someJSValue.toString(exec)->view(exec).get();

By the end of that statement, the JSString::SafeView goes out of scope, and the JSString*
is no longer protected from GC.

I added a couple of forwarding helpers to the SafeView class, and if you need a StringView
object from it, you can call .get() just like before.

Finally I also removed the JSString::SafeView() constructor, since nobody was instantiating
empty SafeView objects anyway. This way we don't have to worry about null members.

  • runtime/ArrayPrototype.cpp:

(JSC::arrayProtoFuncJoin):

  • runtime/FunctionConstructor.cpp:

(JSC::constructFunctionSkippingEvalEnabledCheck):

  • runtime/JSGenericTypedArrayViewPrototypeFunctions.h:

(JSC::genericTypedArrayViewProtoFuncJoin):

  • runtime/JSGlobalObjectFunctions.cpp:

(JSC::decode):
(JSC::globalFuncParseInt):
(JSC::globalFuncParseFloat):
(JSC::globalFuncEscape):
(JSC::globalFuncUnescape):

  • runtime/JSONObject.cpp:

(JSC::JSONProtoFuncParse):

  • runtime/JSString.cpp:

(JSC::JSString::getPrimitiveNumber):
(JSC::JSString::toNumber):

  • runtime/JSString.h:

(JSC::JSString::SafeView::is8Bit):
(JSC::JSString::SafeView::length):
(JSC::JSString::SafeView::characters8):
(JSC::JSString::SafeView::characters16):
(JSC::JSString::SafeView::operator[]):
(JSC::JSString::SafeView::SafeView):
(JSC::JSString::SafeView::get):
(JSC::JSString::SafeView::operator StringView): Deleted.

  • runtime/StringPrototype.cpp:

(JSC::stringProtoFuncCharAt):
(JSC::stringProtoFuncCharCodeAt):
(JSC::stringProtoFuncIndexOf):
(JSC::stringProtoFuncNormalize):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp

    r193939 r194310  
    151151static JSValue decode(ExecState* exec, const Bitmap<256>& doNotUnescape, bool strict)
    152152{
    153     StringView str = exec->argument(0).toString(exec)->view(exec);
     153    JSString::SafeView str = exec->argument(0).toString(exec)->view(exec);
    154154   
    155155    if (str.is8Bit())
     
    618618
    619619    // If ToString throws, we shouldn't call ToInt32.
    620     StringView s = value.toString(exec)->view(exec);
     620    JSString::SafeView s = value.toString(exec)->view(exec);
    621621    if (exec->hadException())
    622622        return JSValue::encode(jsUndefined());
    623623
    624     return JSValue::encode(jsNumber(parseInt(s, radixValue.toInt32(exec))));
     624    return JSValue::encode(jsNumber(parseInt(s.get(), radixValue.toInt32(exec))));
    625625}
    626626
    627627EncodedJSValue JSC_HOST_CALL globalFuncParseFloat(ExecState* exec)
    628628{
    629     return JSValue::encode(jsNumber(parseFloat(exec->argument(0).toString(exec)->view(exec))));
     629    return JSValue::encode(jsNumber(parseFloat(exec->argument(0).toString(exec)->view(exec).get())));
    630630}
    631631
     
    690690
    691691    JSStringBuilder builder;
    692     StringView str = exec->argument(0).toString(exec)->view(exec);
     692    JSString::SafeView str = exec->argument(0).toString(exec)->view(exec);
    693693    if (str.is8Bit()) {
    694694        const LChar* c = str.characters8();
     
    728728{
    729729    StringBuilder builder;
    730     StringView str = exec->argument(0).toString(exec)->view(exec);
     730    JSString::SafeView str = exec->argument(0).toString(exec)->view(exec);
    731731    int k = 0;
    732732    int len = str.length();
Note: See TracChangeset for help on using the changeset viewer.