Changeset 204485 in webkit


Ignore:
Timestamp:
Aug 15, 2016 2:52:22 PM (8 years ago)
Author:
mark.lam@apple.com
Message:

Make JSValue::strictEqual() handle failures to resolve JSRopeStrings.
https://bugs.webkit.org/show_bug.cgi?id=160832
<rdar://problem/27577556>

Reviewed by Geoffrey Garen.

Currently, JSValue::strictEqualSlowCaseInline() (and peers) will blindly try to
access the StringImpl of a JSRopeString that fails to resolve its rope. As a
result, we'll crash with null pointer dereferences.

We can fix this by introducing a JSString::equal() method that will do the
equality comparison, but is aware of the potential failures to resolve ropes.
JSValue::strictEqualSlowCaseInline() (and peers) will now call JSString::equal()
instead of accessing the underlying StringImpl directly.

Also added some exception checks.

  • JavaScriptCore.xcodeproj/project.pbxproj:
  • jit/JITOperations.cpp:
  • runtime/ArrayPrototype.cpp:

(JSC::arrayProtoFuncIndexOf):
(JSC::arrayProtoFuncLastIndexOf):

  • runtime/JSCJSValueInlines.h:

(JSC::JSValue::equalSlowCaseInline):
(JSC::JSValue::strictEqualSlowCaseInline):

  • runtime/JSString.cpp:

(JSC::JSString::equalSlowCase):

  • runtime/JSString.h:
  • runtime/JSStringInlines.h: Added.

(JSC::JSString::equal):

Location:
trunk/Source/JavaScriptCore
Files:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r204484 r204485  
     12016-08-15  Mark Lam  <mark.lam@apple.com>
     2
     3        Make JSValue::strictEqual() handle failures to resolve JSRopeStrings.
     4        https://bugs.webkit.org/show_bug.cgi?id=160832
     5        <rdar://problem/27577556>
     6
     7        Reviewed by Geoffrey Garen.
     8
     9        Currently, JSValue::strictEqualSlowCaseInline() (and peers) will blindly try to
     10        access the StringImpl of a JSRopeString that fails to resolve its rope.  As a
     11        result, we'll crash with null pointer dereferences.
     12
     13        We can fix this by introducing a JSString::equal() method that will do the
     14        equality comparison, but is aware of the potential failures to resolve ropes.
     15        JSValue::strictEqualSlowCaseInline() (and peers) will now call JSString::equal()
     16        instead of accessing the underlying StringImpl directly.
     17
     18        Also added some exception checks.
     19
     20        * JavaScriptCore.xcodeproj/project.pbxproj:
     21        * jit/JITOperations.cpp:
     22        * runtime/ArrayPrototype.cpp:
     23        (JSC::arrayProtoFuncIndexOf):
     24        (JSC::arrayProtoFuncLastIndexOf):
     25        * runtime/JSCJSValueInlines.h:
     26        (JSC::JSValue::equalSlowCaseInline):
     27        (JSC::JSValue::strictEqualSlowCaseInline):
     28        * runtime/JSString.cpp:
     29        (JSC::JSString::equalSlowCase):
     30        * runtime/JSString.h:
     31        * runtime/JSStringInlines.h: Added.
     32        (JSC::JSString::equal):
     33
    1342016-08-15  Keith Miller  <keith_miller@apple.com>
    235
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r204484 r204485  
    963963                0FFFC95F14EF90BB00C72532 /* DFGVirtualRegisterAllocationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FFFC95314EF909500C72532 /* DFGVirtualRegisterAllocationPhase.cpp */; };
    964964                0FFFC96014EF90BD00C72532 /* DFGVirtualRegisterAllocationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FFFC95414EF909500C72532 /* DFGVirtualRegisterAllocationPhase.h */; };
     965                13FECE06D3B445FCB6C93461 /* JSModuleLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1879510614C540FFB561C124 /* JSModuleLoader.cpp */; };
    965966                140566C4107EC255005DBC8D /* JSAPIValueWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC0894D50FAFBA2D00001865 /* JSAPIValueWrapper.cpp */; };
    966967                140566D6107EC271005DBC8D /* JSFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A85E0255597D01FF60F7 /* JSFunction.cpp */; };
     
    20002001                C4F4B6F51A05C984005CAB76 /* generate_objc_protocol_types_implementation.py in Headers */ = {isa = PBXBuildFile; fileRef = C4F4B6D71A05C76F005CAB76 /* generate_objc_protocol_types_implementation.py */; settings = {ATTRIBUTES = (Private, ); }; };
    20012002                C4F4B6F61A05C984005CAB76 /* objc_generator_templates.py in Headers */ = {isa = PBXBuildFile; fileRef = C4F4B6D81A05C76F005CAB76 /* objc_generator_templates.py */; settings = {ATTRIBUTES = (Private, ); }; };
     2003                D9722752DC54459B9125B539 /* JSModuleLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 77B25CB2C3094A92A38E1DB3 /* JSModuleLoader.h */; };
    20022004                DC00039319D8BE6F00023EB0 /* DFGPreciseLocalClobberize.h in Headers */ = {isa = PBXBuildFile; fileRef = DC00039019D8BE6F00023EB0 /* DFGPreciseLocalClobberize.h */; };
    20032005                DC0184191D10C1890057B053 /* JITWorklist.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0184181D10C1870057B053 /* JITWorklist.h */; };
     
    21422144                FED94F2F171E3E2300BE77A4 /* Watchdog.h in Headers */ = {isa = PBXBuildFile; fileRef = FED94F2C171E3E2300BE77A4 /* Watchdog.h */; settings = {ATTRIBUTES = (Private, ); }; };
    21432145                FEF040511AAE662D00BD28B0 /* CompareAndSwapTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEF040501AAE662D00BD28B0 /* CompareAndSwapTest.cpp */; };
    2144                 D9722752DC54459B9125B539 /* JSModuleLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 77B25CB2C3094A92A38E1DB3 /* JSModuleLoader.h */; };
    2145                 13FECE06D3B445FCB6C93461 /* JSModuleLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1879510614C540FFB561C124 /* JSModuleLoader.cpp */; };
     2146                FEFD6FC61D5E7992008F2F0B /* JSStringInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = FEFD6FC51D5E7970008F2F0B /* JSStringInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
    21462147/* End PBXBuildFile section */
    21472148
     
    32873288                14F7256414EE265E00B1652B /* WeakHandleOwner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakHandleOwner.h; sourceTree = "<group>"; };
    32883289                14F97446138C853E00DA1C67 /* HeapRootVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapRootVisitor.h; sourceTree = "<group>"; };
     3290                1879510614C540FFB561C124 /* JSModuleLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSModuleLoader.cpp; sourceTree = "<group>"; };
    32893291                1A28D4A7177B71C80007FA3C /* JSStringRefPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringRefPrivate.h; sourceTree = "<group>"; };
    32903292                1ACF7376171CA6FB00C9BB1E /* Weak.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Weak.cpp; sourceTree = "<group>"; };
     
    35233525                72AAF7CB1D0D318B005E60BE /* JSCustomGetterSetterFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCustomGetterSetterFunction.cpp; sourceTree = "<group>"; };
    35243526                72AAF7CC1D0D318B005E60BE /* JSCustomGetterSetterFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCustomGetterSetterFunction.h; sourceTree = "<group>"; };
     3527                77B25CB2C3094A92A38E1DB3 /* JSModuleLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSModuleLoader.h; sourceTree = "<group>"; };
    35253528                7905BB661D12050E0019FE57 /* InlineAccess.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InlineAccess.cpp; sourceTree = "<group>"; };
    35263529                7905BB671D12050E0019FE57 /* InlineAccess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InlineAccess.h; sourceTree = "<group>"; };
     
    44474450                FEF040501AAE662D00BD28B0 /* CompareAndSwapTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CompareAndSwapTest.cpp; path = API/tests/CompareAndSwapTest.cpp; sourceTree = "<group>"; };
    44484451                FEF040521AAEC4ED00BD28B0 /* CompareAndSwapTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CompareAndSwapTest.h; path = API/tests/CompareAndSwapTest.h; sourceTree = "<group>"; };
    4449                 77B25CB2C3094A92A38E1DB3 /* JSModuleLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSModuleLoader.h; path = JSModuleLoader.h; sourceTree = "<group>"; };
    4450                 1879510614C540FFB561C124 /* JSModuleLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JSModuleLoader.cpp; path = JSModuleLoader.cpp; sourceTree = "<group>"; };
     4452                FEFD6FC51D5E7970008F2F0B /* JSStringInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringInlines.h; sourceTree = "<group>"; };
    44514453/* End PBXFileReference section */
    44524454
     
    59325934                                F692A8620255597D01FF60F7 /* JSString.h */,
    59335935                                86E85538111B9968001AF51E /* JSStringBuilder.h */,
     5936                                FEFD6FC51D5E7970008F2F0B /* JSStringInlines.h */,
    59345937                                70EC0EBC1AA0D7DA00B6AAFA /* JSStringIterator.cpp */,
    59355938                                70EC0EBD1AA0D7DA00B6AAFA /* JSStringIterator.h */,
     
    80458048                                ADDB1F6318D77DBE009B58A8 /* OpaqueRootSet.h in Headers */,
    80468049                                969A079B0ED1D3AE00F1F681 /* Opcode.h in Headers */,
     8050                                FEFD6FC61D5E7992008F2F0B /* JSStringInlines.h in Headers */,
    80478051                                0F2BDC2C151FDE9100CD8910 /* Operands.h in Headers */,
    80488052                                A70447EA17A0BD4600F5898E /* OperandsInlines.h in Headers */,
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r204470 r204485  
    10521052    NativeCallFrameTracer tracer(vm, exec);
    10531053
    1054     bool result = WTF::equal(*asString(left)->value(exec).impl(), *asString(right)->value(exec).impl());
     1054    bool result = asString(left)->equal(exec, asString(right));
    10551055#if USE(JSVALUE64)
    10561056    return JSValue::encode(jsBoolean(result));
  • trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp

    r204466 r204485  
    10331033    if (!thisObj)
    10341034        return JSValue::encode(JSValue());
     1035    VM& vm = exec->vm();
    10351036    unsigned length = getLength(exec, thisObj);
    1036     if (exec->hadException())
     1037    if (UNLIKELY(vm.exception()))
    10371038        return JSValue::encode(jsUndefined());
    10381039
     
    10411042    for (; index < length; ++index) {
    10421043        JSValue e = getProperty(exec, thisObj, index);
    1043         if (exec->hadException())
     1044        if (UNLIKELY(vm.exception()))
    10441045            return JSValue::encode(jsUndefined());
    10451046        if (!e)
     
    10471048        if (JSValue::strictEqual(exec, searchElement, e))
    10481049            return JSValue::encode(jsNumber(index));
     1050        if (UNLIKELY(vm.exception()))
     1051            return JSValue::encode(jsUndefined());
    10491052    }
    10501053
     
    10751078    }
    10761079
     1080    VM& vm = exec->vm();
    10771081    JSValue searchElement = exec->argument(0);
    10781082    do {
    10791083        RELEASE_ASSERT(index < length);
    10801084        JSValue e = getProperty(exec, thisObj, index);
    1081         if (exec->hadException())
     1085        if (UNLIKELY(vm.exception()))
    10821086            return JSValue::encode(jsUndefined());
    10831087        if (!e)
     
    10851089        if (JSValue::strictEqual(exec, searchElement, e))
    10861090            return JSValue::encode(jsNumber(index));
     1091        if (UNLIKELY(vm.exception()))
     1092            return JSValue::encode(jsUndefined());
    10871093    } while (index--);
    10881094
  • trunk/Source/JavaScriptCore/runtime/JSCJSValueInlines.h

    r203925 r204485  
    3434#include "JSObject.h"
    3535#include "JSFunction.h"
     36#include "JSStringInlines.h"
    3637#include "MathCommon.h"
    3738#include <wtf/text/StringImpl.h>
     
    901902        bool s2 = v2.isString();
    902903        if (s1 && s2)
    903             return WTF::equal(*asString(v1)->value(exec).impl(), *asString(v2)->value(exec).impl());
     904            return asString(v1)->equal(exec, asString(v2));
    904905
    905906        if (v1.isUndefinedOrNull()) {
     
    971972
    972973    if (v1.asCell()->isString() && v2.asCell()->isString())
    973         return WTF::equal(*asString(v1)->value(exec).impl(), *asString(v2)->value(exec).impl());
     974        return asString(v1)->equal(exec, asString(v2));
    974975    return v1 == v2;
    975976}
  • trunk/Source/JavaScriptCore/runtime/JSString.cpp

    r201782 r204485  
    7373}
    7474
     75bool JSString::equalSlowCase(ExecState* exec, JSString* other) const
     76{
     77    String str1 = value(exec);
     78    String str2 = other->value(exec);
     79    if (exec->hadException())
     80        return false;
     81    return WTF::equal(*str1.impl(), *str2.impl());
     82}
     83
    7584size_t JSString::estimatedSize(JSCell* cell)
    7685{
  • trunk/Source/JavaScriptCore/runtime/JSString.h

    r202585 r204485  
    156156    StringViewWithUnderlyingString viewWithUnderlyingString(ExecState&) const;
    157157
     158    inline bool equal(ExecState*, JSString* other) const;
    158159    const String& value(ExecState*) const;
    159160    const String& tryGetValue() const;
     
    193194    friend class JSValue;
    194195
     196    JS_EXPORT_PRIVATE bool equalSlowCase(ExecState*, JSString* other) const;
    195197    bool isRope() const { return m_value.isNull(); }
    196198    bool isSubstring() const;
Note: See TracChangeset for help on using the changeset viewer.