Title: [204485] trunk/Source/_javascript_Core
Revision
204485
Author
[email protected]
Date
2016-08-15 14:52:22 -0700 (Mon, 15 Aug 2016)

Log 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.

* _javascript_Core.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):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (204484 => 204485)


--- trunk/Source/_javascript_Core/ChangeLog	2016-08-15 21:35:07 UTC (rev 204484)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-08-15 21:52:22 UTC (rev 204485)
@@ -1,3 +1,36 @@
+2016-08-15  Mark Lam  <[email protected]>
+
+        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.
+
+        * _javascript_Core.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):
+
 2016-08-15  Keith Miller  <[email protected]>
 
         Implement WASM Parser and B3 IR generator

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (204484 => 204485)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2016-08-15 21:35:07 UTC (rev 204484)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2016-08-15 21:52:22 UTC (rev 204485)
@@ -962,6 +962,7 @@
 		0FFFC95E14EF90B700C72532 /* DFGPredictionPropagationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FFFC95214EF909500C72532 /* DFGPredictionPropagationPhase.h */; };
 		0FFFC95F14EF90BB00C72532 /* DFGVirtualRegisterAllocationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FFFC95314EF909500C72532 /* DFGVirtualRegisterAllocationPhase.cpp */; };
 		0FFFC96014EF90BD00C72532 /* DFGVirtualRegisterAllocationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FFFC95414EF909500C72532 /* DFGVirtualRegisterAllocationPhase.h */; };
+		13FECE06D3B445FCB6C93461 /* JSModuleLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1879510614C540FFB561C124 /* JSModuleLoader.cpp */; };
 		140566C4107EC255005DBC8D /* JSAPIValueWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC0894D50FAFBA2D00001865 /* JSAPIValueWrapper.cpp */; };
 		140566D6107EC271005DBC8D /* JSFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A85E0255597D01FF60F7 /* JSFunction.cpp */; };
 		140B7D1D0DC69AF7009C42B8 /* JSLexicalEnvironment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14DA818F0D99FD2000B0A4FB /* JSLexicalEnvironment.cpp */; };
@@ -1999,6 +2000,7 @@
 		C4F4B6F41A05C944005CAB76 /* cpp_generator.py in Headers */ = {isa = PBXBuildFile; fileRef = C4F4B6D01A05C76F005CAB76 /* cpp_generator.py */; settings = {ATTRIBUTES = (Private, ); }; };
 		C4F4B6F51A05C984005CAB76 /* generate_objc_protocol_types_implementation.py in Headers */ = {isa = PBXBuildFile; fileRef = C4F4B6D71A05C76F005CAB76 /* generate_objc_protocol_types_implementation.py */; settings = {ATTRIBUTES = (Private, ); }; };
 		C4F4B6F61A05C984005CAB76 /* objc_generator_templates.py in Headers */ = {isa = PBXBuildFile; fileRef = C4F4B6D81A05C76F005CAB76 /* objc_generator_templates.py */; settings = {ATTRIBUTES = (Private, ); }; };
+		D9722752DC54459B9125B539 /* JSModuleLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 77B25CB2C3094A92A38E1DB3 /* JSModuleLoader.h */; };
 		DC00039319D8BE6F00023EB0 /* DFGPreciseLocalClobberize.h in Headers */ = {isa = PBXBuildFile; fileRef = DC00039019D8BE6F00023EB0 /* DFGPreciseLocalClobberize.h */; };
 		DC0184191D10C1890057B053 /* JITWorklist.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0184181D10C1870057B053 /* JITWorklist.h */; };
 		DC01841A1D10C18C0057B053 /* JITWorklist.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC0184171D10C1870057B053 /* JITWorklist.cpp */; };
@@ -2141,8 +2143,7 @@
 		FED94F2E171E3E2300BE77A4 /* Watchdog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FED94F2B171E3E2300BE77A4 /* Watchdog.cpp */; };
 		FED94F2F171E3E2300BE77A4 /* Watchdog.h in Headers */ = {isa = PBXBuildFile; fileRef = FED94F2C171E3E2300BE77A4 /* Watchdog.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		FEF040511AAE662D00BD28B0 /* CompareAndSwapTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEF040501AAE662D00BD28B0 /* CompareAndSwapTest.cpp */; };
-		D9722752DC54459B9125B539 /* JSModuleLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 77B25CB2C3094A92A38E1DB3 /* JSModuleLoader.h */; };
-		13FECE06D3B445FCB6C93461 /* JSModuleLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1879510614C540FFB561C124 /* JSModuleLoader.cpp */; };
+		FEFD6FC61D5E7992008F2F0B /* JSStringInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = FEFD6FC51D5E7970008F2F0B /* JSStringInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
@@ -3286,6 +3287,7 @@
 		14F7256314EE265E00B1652B /* WeakHandleOwner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WeakHandleOwner.cpp; sourceTree = "<group>"; };
 		14F7256414EE265E00B1652B /* WeakHandleOwner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakHandleOwner.h; sourceTree = "<group>"; };
 		14F97446138C853E00DA1C67 /* HeapRootVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapRootVisitor.h; sourceTree = "<group>"; };
+		1879510614C540FFB561C124 /* JSModuleLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSModuleLoader.cpp; sourceTree = "<group>"; };
 		1A28D4A7177B71C80007FA3C /* JSStringRefPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringRefPrivate.h; sourceTree = "<group>"; };
 		1ACF7376171CA6FB00C9BB1E /* Weak.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Weak.cpp; sourceTree = "<group>"; };
 		1C9051420BA9E8A70081E9D0 /* Version.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Version.xcconfig; sourceTree = "<group>"; };
@@ -3522,6 +3524,7 @@
 		70ECA6041AFDBEA200449739 /* TemplateRegistryKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TemplateRegistryKey.h; sourceTree = "<group>"; };
 		72AAF7CB1D0D318B005E60BE /* JSCustomGetterSetterFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCustomGetterSetterFunction.cpp; sourceTree = "<group>"; };
 		72AAF7CC1D0D318B005E60BE /* JSCustomGetterSetterFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCustomGetterSetterFunction.h; sourceTree = "<group>"; };
+		77B25CB2C3094A92A38E1DB3 /* JSModuleLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSModuleLoader.h; sourceTree = "<group>"; };
 		7905BB661D12050E0019FE57 /* InlineAccess.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InlineAccess.cpp; sourceTree = "<group>"; };
 		7905BB671D12050E0019FE57 /* InlineAccess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InlineAccess.h; sourceTree = "<group>"; };
 		79160DBB1C8E3EC8008C085A /* ProxyRevoke.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProxyRevoke.cpp; sourceTree = "<group>"; };
@@ -4446,8 +4449,7 @@
 		FEDA50D51B97F4D9009A3B4F /* PingPongStackOverflowTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PingPongStackOverflowTest.h; path = API/tests/PingPongStackOverflowTest.h; sourceTree = "<group>"; };
 		FEF040501AAE662D00BD28B0 /* CompareAndSwapTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CompareAndSwapTest.cpp; path = API/tests/CompareAndSwapTest.cpp; sourceTree = "<group>"; };
 		FEF040521AAEC4ED00BD28B0 /* CompareAndSwapTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CompareAndSwapTest.h; path = API/tests/CompareAndSwapTest.h; sourceTree = "<group>"; };
-		77B25CB2C3094A92A38E1DB3 /* JSModuleLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSModuleLoader.h; path = JSModuleLoader.h; sourceTree = "<group>"; };
-		1879510614C540FFB561C124 /* JSModuleLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JSModuleLoader.cpp; path = JSModuleLoader.cpp; sourceTree = "<group>"; };
+		FEFD6FC51D5E7970008F2F0B /* JSStringInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringInlines.h; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -5931,6 +5933,7 @@
 				BC02E9B60E1842FA000F9297 /* JSString.cpp */,
 				F692A8620255597D01FF60F7 /* JSString.h */,
 				86E85538111B9968001AF51E /* JSStringBuilder.h */,
+				FEFD6FC51D5E7970008F2F0B /* JSStringInlines.h */,
 				70EC0EBC1AA0D7DA00B6AAFA /* JSStringIterator.cpp */,
 				70EC0EBD1AA0D7DA00B6AAFA /* JSStringIterator.h */,
 				2600B5A4152BAAA70091EE5F /* JSStringJoiner.cpp */,
@@ -8044,6 +8047,7 @@
 				E124A8F70E555775003091F1 /* OpaqueJSString.h in Headers */,
 				ADDB1F6318D77DBE009B58A8 /* OpaqueRootSet.h in Headers */,
 				969A079B0ED1D3AE00F1F681 /* Opcode.h in Headers */,
+				FEFD6FC61D5E7992008F2F0B /* JSStringInlines.h in Headers */,
 				0F2BDC2C151FDE9100CD8910 /* Operands.h in Headers */,
 				A70447EA17A0BD4600F5898E /* OperandsInlines.h in Headers */,
 				BC18C4480E16F5CD00B34460 /* Operations.h in Headers */,

Modified: trunk/Source/_javascript_Core/jit/JITOperations.cpp (204484 => 204485)


--- trunk/Source/_javascript_Core/jit/JITOperations.cpp	2016-08-15 21:35:07 UTC (rev 204484)
+++ trunk/Source/_javascript_Core/jit/JITOperations.cpp	2016-08-15 21:52:22 UTC (rev 204485)
@@ -1051,7 +1051,7 @@
     VM* vm = &exec->vm();
     NativeCallFrameTracer tracer(vm, exec);
 
-    bool result = WTF::equal(*asString(left)->value(exec).impl(), *asString(right)->value(exec).impl());
+    bool result = asString(left)->equal(exec, asString(right));
 #if USE(JSVALUE64)
     return JSValue::encode(jsBoolean(result));
 #else

Modified: trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp (204484 => 204485)


--- trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp	2016-08-15 21:35:07 UTC (rev 204484)
+++ trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp	2016-08-15 21:52:22 UTC (rev 204485)
@@ -1032,8 +1032,9 @@
     JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec);
     if (!thisObj)
         return JSValue::encode(JSValue());
+    VM& vm = exec->vm();
     unsigned length = getLength(exec, thisObj);
-    if (exec->hadException())
+    if (UNLIKELY(vm.exception()))
         return JSValue::encode(jsUndefined());
 
     unsigned index = argumentClampedIndexFromStartOrEnd(exec, 1, length);
@@ -1040,12 +1041,14 @@
     JSValue searchElement = exec->argument(0);
     for (; index < length; ++index) {
         JSValue e = getProperty(exec, thisObj, index);
-        if (exec->hadException())
+        if (UNLIKELY(vm.exception()))
             return JSValue::encode(jsUndefined());
         if (!e)
             continue;
         if (JSValue::strictEqual(exec, searchElement, e))
             return JSValue::encode(jsNumber(index));
+        if (UNLIKELY(vm.exception()))
+            return JSValue::encode(jsUndefined());
     }
 
     return JSValue::encode(jsNumber(-1));
@@ -1074,16 +1077,19 @@
             index = static_cast<unsigned>(fromDouble);
     }
 
+    VM& vm = exec->vm();
     JSValue searchElement = exec->argument(0);
     do {
         RELEASE_ASSERT(index < length);
         JSValue e = getProperty(exec, thisObj, index);
-        if (exec->hadException())
+        if (UNLIKELY(vm.exception()))
             return JSValue::encode(jsUndefined());
         if (!e)
             continue;
         if (JSValue::strictEqual(exec, searchElement, e))
             return JSValue::encode(jsNumber(index));
+        if (UNLIKELY(vm.exception()))
+            return JSValue::encode(jsUndefined());
     } while (index--);
 
     return JSValue::encode(jsNumber(-1));

Modified: trunk/Source/_javascript_Core/runtime/JSCJSValueInlines.h (204484 => 204485)


--- trunk/Source/_javascript_Core/runtime/JSCJSValueInlines.h	2016-08-15 21:35:07 UTC (rev 204484)
+++ trunk/Source/_javascript_Core/runtime/JSCJSValueInlines.h	2016-08-15 21:52:22 UTC (rev 204485)
@@ -33,6 +33,7 @@
 #include "JSCellInlines.h"
 #include "JSObject.h"
 #include "JSFunction.h"
+#include "JSStringInlines.h"
 #include "MathCommon.h"
 #include <wtf/text/StringImpl.h>
 
@@ -900,7 +901,7 @@
         bool s1 = v1.isString();
         bool s2 = v2.isString();
         if (s1 && s2)
-            return WTF::equal(*asString(v1)->value(exec).impl(), *asString(v2)->value(exec).impl());
+            return asString(v1)->equal(exec, asString(v2));
 
         if (v1.isUndefinedOrNull()) {
             if (v2.isUndefinedOrNull())
@@ -970,7 +971,7 @@
     ASSERT(v1.isCell() && v2.isCell());
 
     if (v1.asCell()->isString() && v2.asCell()->isString())
-        return WTF::equal(*asString(v1)->value(exec).impl(), *asString(v2)->value(exec).impl());
+        return asString(v1)->equal(exec, asString(v2));
     return v1 == v2;
 }
 

Modified: trunk/Source/_javascript_Core/runtime/JSString.cpp (204484 => 204485)


--- trunk/Source/_javascript_Core/runtime/JSString.cpp	2016-08-15 21:35:07 UTC (rev 204484)
+++ trunk/Source/_javascript_Core/runtime/JSString.cpp	2016-08-15 21:52:22 UTC (rev 204485)
@@ -72,6 +72,15 @@
     out.printf(">");
 }
 
+bool JSString::equalSlowCase(ExecState* exec, JSString* other) const
+{
+    String str1 = value(exec);
+    String str2 = other->value(exec);
+    if (exec->hadException())
+        return false;
+    return WTF::equal(*str1.impl(), *str2.impl());
+}
+
 size_t JSString::estimatedSize(JSCell* cell)
 {
     JSString* thisObject = jsCast<JSString*>(cell);

Modified: trunk/Source/_javascript_Core/runtime/JSString.h (204484 => 204485)


--- trunk/Source/_javascript_Core/runtime/JSString.h	2016-08-15 21:35:07 UTC (rev 204484)
+++ trunk/Source/_javascript_Core/runtime/JSString.h	2016-08-15 21:52:22 UTC (rev 204485)
@@ -155,6 +155,7 @@
     SafeView view(ExecState*) const;
     StringViewWithUnderlyingString viewWithUnderlyingString(ExecState&) const;
 
+    inline bool equal(ExecState*, JSString* other) const;
     const String& value(ExecState*) const;
     const String& tryGetValue() const;
     const StringImpl* tryGetValueImpl() const;
@@ -192,6 +193,7 @@
 protected:
     friend class JSValue;
 
+    JS_EXPORT_PRIVATE bool equalSlowCase(ExecState*, JSString* other) const;
     bool isRope() const { return m_value.isNull(); }
     bool isSubstring() const;
     bool is8Bit() const { return m_flags & Is8Bit; }

Added: trunk/Source/_javascript_Core/runtime/JSStringInlines.h (0 => 204485)


--- trunk/Source/_javascript_Core/runtime/JSStringInlines.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/runtime/JSStringInlines.h	2016-08-15 21:52:22 UTC (rev 204485)
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "JSString.h"
+
+namespace JSC {
+    
+bool JSString::equal(ExecState* exec, JSString* other) const
+{
+    if (isRope() || other->isRope())
+        return equalSlowCase(exec, other);
+    return WTF::equal(*m_value.impl(), *other->m_value.impl());
+}
+
+} // namespace JSC
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to