Title: [277238] trunk/Source/_javascript_Core
Revision
277238
Author
[email protected]
Date
2021-05-08 19:18:25 -0700 (Sat, 08 May 2021)

Log Message

[JSC] Fix invalid exception checks after recent ErrorInstance changes
https://bugs.webkit.org/show_bug.cgi?id=225565

Reviewed by Alexey Shvayka.

r277221 and r277224 each introduced issues under validateExceptionChecks=1; this patch fixes them.

Of particular note:
The earlier patch sought to consolidate Error#cause logic under ErrorInstance::finishCreation.
This part must be undone as it is crucial that non-user-thrown errors be able to bypass that logic
(otherwise throwException itself would need to be exception-checked).

* runtime/AggregateError.cpp:
(JSC::createAggregateError):
* runtime/ArrayPrototype.cpp:
(JSC::getProperty):
* runtime/Error.cpp:
(JSC::createError):
(JSC::createEvalError):
(JSC::createRangeError):
(JSC::createReferenceError):
(JSC::createSyntaxError):
(JSC::createTypeError):
(JSC::createURIError):
(JSC::createGetterTypeError):
* runtime/ErrorInstance.cpp:
(JSC::ErrorInstance::create):
(JSC::ErrorInstance::finishCreation):
* runtime/ErrorInstance.h:
(JSC::ErrorInstance::create):
* runtime/JSObject.h:
* runtime/JSObjectInlines.h:
(JSC::JSObject::getIfPropertyExists):
* runtime/NullSetterFunction.cpp:
(JSC::NullSetterFunctionInternal::JSC_DEFINE_HOST_FUNCTION):
* wasm/js/JSWebAssemblyCompileError.cpp:
(JSC::createJSWebAssemblyCompileError):
* wasm/js/JSWebAssemblyLinkError.cpp:
(JSC::createJSWebAssemblyLinkError):
* wasm/js/JSWebAssemblyRuntimeError.cpp:
(JSC::createJSWebAssemblyRuntimeError):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (277237 => 277238)


--- trunk/Source/_javascript_Core/ChangeLog	2021-05-09 01:29:38 UTC (rev 277237)
+++ trunk/Source/_javascript_Core/ChangeLog	2021-05-09 02:18:25 UTC (rev 277238)
@@ -1,3 +1,47 @@
+2021-05-08  Ross Kirsling  <[email protected]>
+
+        [JSC] Fix invalid exception checks after recent ErrorInstance changes
+        https://bugs.webkit.org/show_bug.cgi?id=225565
+
+        Reviewed by Alexey Shvayka.
+
+        r277221 and r277224 each introduced issues under validateExceptionChecks=1; this patch fixes them.
+
+        Of particular note:
+        The earlier patch sought to consolidate Error#cause logic under ErrorInstance::finishCreation.
+        This part must be undone as it is crucial that non-user-thrown errors be able to bypass that logic
+        (otherwise throwException itself would need to be exception-checked).
+
+        * runtime/AggregateError.cpp:
+        (JSC::createAggregateError):
+        * runtime/ArrayPrototype.cpp:
+        (JSC::getProperty):
+        * runtime/Error.cpp:
+        (JSC::createError):
+        (JSC::createEvalError):
+        (JSC::createRangeError):
+        (JSC::createReferenceError):
+        (JSC::createSyntaxError):
+        (JSC::createTypeError):
+        (JSC::createURIError):
+        (JSC::createGetterTypeError):
+        * runtime/ErrorInstance.cpp:
+        (JSC::ErrorInstance::create):
+        (JSC::ErrorInstance::finishCreation):
+        * runtime/ErrorInstance.h:
+        (JSC::ErrorInstance::create):
+        * runtime/JSObject.h:
+        * runtime/JSObjectInlines.h:
+        (JSC::JSObject::getIfPropertyExists):
+        * runtime/NullSetterFunction.cpp:
+        (JSC::NullSetterFunctionInternal::JSC_DEFINE_HOST_FUNCTION):
+        * wasm/js/JSWebAssemblyCompileError.cpp:
+        (JSC::createJSWebAssemblyCompileError):
+        * wasm/js/JSWebAssemblyLinkError.cpp:
+        (JSC::createJSWebAssemblyLinkError):
+        * wasm/js/JSWebAssemblyRuntimeError.cpp:
+        (JSC::createJSWebAssemblyRuntimeError):
+
 2021-05-08  Chris Dumez  <[email protected]>
 
         Port Filesystem::pathByAppendingComponent() & Filesystem:: pathByAppendingComponents() to std::filesystem

Modified: trunk/Source/_javascript_Core/runtime/AggregateError.cpp (277237 => 277238)


--- trunk/Source/_javascript_Core/runtime/AggregateError.cpp	2021-05-09 01:29:38 UTC (rev 277237)
+++ trunk/Source/_javascript_Core/runtime/AggregateError.cpp	2021-05-09 02:18:25 UTC (rev 277238)
@@ -49,6 +49,7 @@
     RETURN_IF_EXCEPTION(scope, nullptr);
 
     auto* error = ErrorInstance::create(globalObject, structure, message, options, appender, type, ErrorType::AggregateError, useCurrentFrame);
+    RETURN_IF_EXCEPTION(scope, nullptr);
     error->putDirect(vm, vm.propertyNames->errors, array, static_cast<unsigned>(PropertyAttribute::DontEnum));
     return error;
 }

Modified: trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp (277237 => 277238)


--- trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp	2021-05-09 01:29:38 UTC (rev 277237)
+++ trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp	2021-05-09 02:18:25 UTC (rev 277238)
@@ -145,16 +145,11 @@
 
 static ALWAYS_INLINE JSValue getProperty(JSGlobalObject* globalObject, JSObject* object, uint64_t index)
 {
-    VM& vm = globalObject->vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-
     if (JSValue result = object->tryGetIndexQuickly(index))
         return result;
 
     // Don't return undefined if the property is not found.
-    auto property = object->getIfPropertyExists(globalObject, Identifier::from(vm, index));
-    RETURN_IF_EXCEPTION(scope, { });
-    return property.valueOr(JSValue());
+    return object->getIfPropertyExists(globalObject, Identifier::from(globalObject->vm(), index));
 }
 
 static ALWAYS_INLINE void setLength(JSGlobalObject* globalObject, VM& vm, JSObject* obj, uint64_t value)

Modified: trunk/Source/_javascript_Core/runtime/Error.cpp (277237 => 277238)


--- trunk/Source/_javascript_Core/runtime/Error.cpp	2021-05-09 01:29:38 UTC (rev 277237)
+++ trunk/Source/_javascript_Core/runtime/Error.cpp	2021-05-09 02:18:25 UTC (rev 277238)
@@ -35,37 +35,37 @@
 JSObject* createError(JSGlobalObject* globalObject, const String& message, ErrorInstance::SourceAppender appender)
 {
     ASSERT(!message.isEmpty());
-    return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(), message, jsUndefined(), appender, TypeNothing, ErrorType::Error, true);
+    return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(), message, JSValue(), appender, TypeNothing, ErrorType::Error, true);
 }
 
 JSObject* createEvalError(JSGlobalObject* globalObject, const String& message, ErrorInstance::SourceAppender appender)
 {
     ASSERT(!message.isEmpty());
-    return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::EvalError), message, jsUndefined(), appender, TypeNothing, ErrorType::EvalError, true);
+    return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::EvalError), message, JSValue(), appender, TypeNothing, ErrorType::EvalError, true);
 }
 
 JSObject* createRangeError(JSGlobalObject* globalObject, const String& message, ErrorInstance::SourceAppender appender)
 {
     ASSERT(!message.isEmpty());
-    return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::RangeError), message, jsUndefined(), appender, TypeNothing, ErrorType::RangeError, true);
+    return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::RangeError), message, JSValue(), appender, TypeNothing, ErrorType::RangeError, true);
 }
 
 JSObject* createReferenceError(JSGlobalObject* globalObject, const String& message, ErrorInstance::SourceAppender appender)
 {
     ASSERT(!message.isEmpty());
-    return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::ReferenceError), message, jsUndefined(), appender, TypeNothing, ErrorType::ReferenceError, true);
+    return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::ReferenceError), message, JSValue(), appender, TypeNothing, ErrorType::ReferenceError, true);
 }
 
 JSObject* createSyntaxError(JSGlobalObject* globalObject, const String& message, ErrorInstance::SourceAppender appender)
 {
     ASSERT(!message.isEmpty());
-    return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::SyntaxError), message, jsUndefined(), appender, TypeNothing, ErrorType::SyntaxError, true);
+    return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::SyntaxError), message, JSValue(), appender, TypeNothing, ErrorType::SyntaxError, true);
 }
 
 JSObject* createTypeError(JSGlobalObject* globalObject, const String& message, ErrorInstance::SourceAppender appender, RuntimeType type)
 {
     ASSERT(!message.isEmpty());
-    return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::TypeError), message, jsUndefined(), appender, type, ErrorType::TypeError, true);
+    return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::TypeError), message, JSValue(), appender, type, ErrorType::TypeError, true);
 }
 
 JSObject* createNotEnoughArgumentsError(JSGlobalObject* globalObject, ErrorInstance::SourceAppender appender)
@@ -76,7 +76,7 @@
 JSObject* createURIError(JSGlobalObject* globalObject, const String& message, ErrorInstance::SourceAppender appender)
 {
     ASSERT(!message.isEmpty());
-    return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::URIError), message, jsUndefined(), appender, TypeNothing, ErrorType::URIError, true);
+    return ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::URIError), message, JSValue(), appender, TypeNothing, ErrorType::URIError, true);
 }
 
 JSObject* createError(JSGlobalObject* globalObject, ErrorType errorType, const String& message)
@@ -113,7 +113,7 @@
 static JSObject* createGetterTypeError(JSGlobalObject* globalObject, const String& message)
 {
     ASSERT(!message.isEmpty());
-    auto* error = ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::TypeError), message, jsUndefined(), nullptr, TypeNothing, ErrorType::TypeError);
+    auto* error = ErrorInstance::create(globalObject, globalObject->vm(), globalObject->errorStructure(ErrorType::TypeError), message, JSValue(), nullptr, TypeNothing, ErrorType::TypeError);
     error->setNativeGetterTypeError();
     return error;
 }

Modified: trunk/Source/_javascript_Core/runtime/ErrorInstance.cpp (277237 => 277238)


--- trunk/Source/_javascript_Core/runtime/ErrorInstance.cpp	2021-05-09 01:29:38 UTC (rev 277237)
+++ trunk/Source/_javascript_Core/runtime/ErrorInstance.cpp	2021-05-09 02:18:25 UTC (rev 277238)
@@ -52,7 +52,14 @@
     String messageString = message.isUndefined() ? String() : message.toWTFString(globalObject);
     RETURN_IF_EXCEPTION(scope, nullptr);
 
-    return create(globalObject, vm, structure, messageString, options, appender, type, errorType, useCurrentFrame);
+    JSValue cause;
+    if (options.isObject()) {
+        // Since `throw undefined;` is valid, we need to distinguish the case where `cause` is an explicit undefined.
+        cause = asObject(options)->getIfPropertyExists(globalObject, vm.propertyNames->cause);
+        RETURN_IF_EXCEPTION(scope, nullptr);
+    }
+
+    return create(globalObject, vm, structure, messageString, cause, appender, type, errorType, useCurrentFrame);
 }
 
 static String appendSourceToErrorMessage(CallFrame* callFrame, ErrorInstance* exception, BytecodeIndex bytecodeIndex, const String& message)
@@ -107,11 +114,10 @@
     return appender(message, codeBlock->source().provider()->getRange(start, stop).toString(), type, ErrorInstance::FoundApproximateSource);
 }
 
-void ErrorInstance::finishCreation(VM& vm, JSGlobalObject* globalObject, const String& message, JSValue options, SourceAppender appender, RuntimeType type, bool useCurrentFrame)
+void ErrorInstance::finishCreation(VM& vm, JSGlobalObject* globalObject, const String& message, JSValue cause, SourceAppender appender, RuntimeType type, bool useCurrentFrame)
 {
     Base::finishCreation(vm);
     ASSERT(inherits(vm, info()));
-    auto scope = DECLARE_THROW_SCOPE(vm);
 
     m_sourceAppender = appender;
     m_runtimeTypeForCause = type;
@@ -135,13 +141,8 @@
     if (!messageWithSource.isNull())
         putDirect(vm, vm.propertyNames->message, jsString(vm, messageWithSource), static_cast<unsigned>(PropertyAttribute::DontEnum));
 
-    if (options.isObject()) {
-        // Since `throw undefined;` is valid, we need to distinguish the case where `cause` is an explicit undefined.
-        auto cause = asObject(options)->getIfPropertyExists(globalObject, vm.propertyNames->cause);
-        RETURN_IF_EXCEPTION(scope, void());
-        if (cause)
-            putDirect(vm, vm.propertyNames->cause, cause.value(), static_cast<unsigned>(PropertyAttribute::DontEnum));
-    }
+    if (!cause.isEmpty())
+        putDirect(vm, vm.propertyNames->cause, cause, static_cast<unsigned>(PropertyAttribute::DontEnum));
 }
 
 // Based on ErrorPrototype's errorProtoFuncToString(), but is modified to

Modified: trunk/Source/_javascript_Core/runtime/ErrorInstance.h (277237 => 277238)


--- trunk/Source/_javascript_Core/runtime/ErrorInstance.h	2021-05-09 01:29:38 UTC (rev 277237)
+++ trunk/Source/_javascript_Core/runtime/ErrorInstance.h	2021-05-09 02:18:25 UTC (rev 277238)
@@ -54,10 +54,10 @@
         return Structure::create(vm, globalObject, prototype, TypeInfo(ErrorInstanceType, StructureFlags), info());
     }
 
-    static ErrorInstance* create(JSGlobalObject* globalObject, VM& vm, Structure* structure, const String& message, JSValue options, SourceAppender appender = nullptr, RuntimeType type = TypeNothing, ErrorType errorType = ErrorType::Error, bool useCurrentFrame = true)
+    static ErrorInstance* create(JSGlobalObject* globalObject, VM& vm, Structure* structure, const String& message, JSValue cause, SourceAppender appender = nullptr, RuntimeType type = TypeNothing, ErrorType errorType = ErrorType::Error, bool useCurrentFrame = true)
     {
         ErrorInstance* instance = new (NotNull, allocateCell<ErrorInstance>(vm.heap)) ErrorInstance(vm, structure, errorType);
-        instance->finishCreation(vm, globalObject, message, options, appender, type, useCurrentFrame);
+        instance->finishCreation(vm, globalObject, message, cause, appender, type, useCurrentFrame);
         return instance;
     }
 
@@ -94,7 +94,7 @@
 protected:
     explicit ErrorInstance(VM&, Structure*, ErrorType);
 
-    void finishCreation(VM&, JSGlobalObject*, const String& message, JSValue options, SourceAppender = nullptr, RuntimeType = TypeNothing, bool useCurrentFrame = true);
+    void finishCreation(VM&, JSGlobalObject*, const String& message, JSValue cause, SourceAppender = nullptr, RuntimeType = TypeNothing, bool useCurrentFrame = true);
 
     static bool getOwnPropertySlot(JSObject*, JSGlobalObject*, PropertyName, PropertySlot&);
     static void getOwnSpecialPropertyNames(JSObject*, JSGlobalObject*, PropertyNameArray&, DontEnumPropertiesMode);

Modified: trunk/Source/_javascript_Core/runtime/JSObject.h (277237 => 277238)


--- trunk/Source/_javascript_Core/runtime/JSObject.h	2021-05-09 01:29:38 UTC (rev 277237)
+++ trunk/Source/_javascript_Core/runtime/JSObject.h	2021-05-09 02:18:25 UTC (rev 277238)
@@ -162,7 +162,7 @@
     template<typename CallbackWhenNoException> typename std::result_of<CallbackWhenNoException(bool, PropertySlot&)>::type getPropertySlot(JSGlobalObject*, PropertyName, CallbackWhenNoException) const;
     template<typename CallbackWhenNoException> typename std::result_of<CallbackWhenNoException(bool, PropertySlot&)>::type getPropertySlot(JSGlobalObject*, PropertyName, PropertySlot&, CallbackWhenNoException) const;
 
-    Optional<JSValue> getIfPropertyExists(JSGlobalObject*, PropertyName);
+    JSValue getIfPropertyExists(JSGlobalObject*, PropertyName);
 
 private:
     static bool getOwnPropertySlotImpl(JSObject*, JSGlobalObject*, PropertyName, PropertySlot&);

Modified: trunk/Source/_javascript_Core/runtime/JSObjectInlines.h (277237 => 277238)


--- trunk/Source/_javascript_Core/runtime/JSObjectInlines.h	2021-05-09 01:29:38 UTC (rev 277237)
+++ trunk/Source/_javascript_Core/runtime/JSObjectInlines.h	2021-05-09 02:18:25 UTC (rev 277238)
@@ -191,7 +191,7 @@
     return JSObject::getOwnPropertySlot(this, globalObject, propertyName, slot);
 }
 
-inline Optional<JSValue> JSObject::getIfPropertyExists(JSGlobalObject* globalObject, PropertyName propertyName)
+inline JSValue JSObject::getIfPropertyExists(JSGlobalObject* globalObject, PropertyName propertyName)
 {
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
@@ -198,14 +198,15 @@
 
     PropertySlot slot(this, PropertySlot::InternalMethodType::HasProperty);
     bool hasProperty = getPropertySlot(globalObject, propertyName, slot);
-    EXCEPTION_ASSERT_UNUSED(scope, !scope.exception() || !hasProperty);
-
+    RETURN_IF_EXCEPTION(scope, { });
     if (!hasProperty)
-        return WTF::nullopt;
+        return { };
 
-    return UNLIKELY(slot.isTaintedByOpaqueObject())
-        ? get(globalObject, propertyName)
-        : slot.getValue(globalObject, propertyName);
+    scope.release();
+    if (UNLIKELY(slot.isTaintedByOpaqueObject()))
+        return get(globalObject, propertyName);
+
+    return slot.getValue(globalObject, propertyName);
 }
 
 inline bool JSObject::mayInterceptIndexedAccesses(VM& vm)

Modified: trunk/Source/_javascript_Core/runtime/NullSetterFunction.cpp (277237 => 277238)


--- trunk/Source/_javascript_Core/runtime/NullSetterFunction.cpp	2021-05-09 01:29:38 UTC (rev 277237)
+++ trunk/Source/_javascript_Core/runtime/NullSetterFunction.cpp	2021-05-09 02:18:25 UTC (rev 277238)
@@ -94,7 +94,7 @@
     auto scope = DECLARE_THROW_SCOPE(vm);
     // This function is only called from IC. And we do not want to include this frame in Error's stack.
     constexpr bool useCurrentFrame = false;
-    throwException(globalObject, scope, ErrorInstance::create(globalObject, vm, globalObject->errorStructure(ErrorType::TypeError), ReadonlyPropertyWriteError, jsUndefined(), nullptr, TypeNothing, ErrorType::TypeError, useCurrentFrame));
+    throwException(globalObject, scope, ErrorInstance::create(globalObject, vm, globalObject->errorStructure(ErrorType::TypeError), ReadonlyPropertyWriteError, JSValue(), nullptr, TypeNothing, ErrorType::TypeError, useCurrentFrame));
     return { };
 }
 

Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyCompileError.cpp (277237 => 277238)


--- trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyCompileError.cpp	2021-05-09 01:29:38 UTC (rev 277237)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyCompileError.cpp	2021-05-09 02:18:25 UTC (rev 277238)
@@ -35,7 +35,7 @@
 JSObject* createJSWebAssemblyCompileError(JSGlobalObject* globalObject, VM& vm, const String& message)
 {
     ASSERT(!message.isEmpty());
-    return ErrorInstance::create(globalObject, vm, globalObject->webAssemblyCompileErrorStructure(), message, jsUndefined(), defaultSourceAppender, TypeNothing, ErrorType::Error, true);
+    return ErrorInstance::create(globalObject, vm, globalObject->webAssemblyCompileErrorStructure(), message, JSValue(), defaultSourceAppender, TypeNothing, ErrorType::Error, true);
 }
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyLinkError.cpp (277237 => 277238)


--- trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyLinkError.cpp	2021-05-09 01:29:38 UTC (rev 277237)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyLinkError.cpp	2021-05-09 02:18:25 UTC (rev 277238)
@@ -35,7 +35,7 @@
 JSObject* createJSWebAssemblyLinkError(JSGlobalObject* globalObject, VM& vm, const String& message)
 {
     ASSERT(!message.isEmpty());
-    return ErrorInstance::create(globalObject, vm, globalObject->webAssemblyLinkErrorStructure(), message, jsUndefined(), defaultSourceAppender, TypeNothing, ErrorType::Error, true);
+    return ErrorInstance::create(globalObject, vm, globalObject->webAssemblyLinkErrorStructure(), message, JSValue(), defaultSourceAppender, TypeNothing, ErrorType::Error, true);
 }
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyRuntimeError.cpp (277237 => 277238)


--- trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyRuntimeError.cpp	2021-05-09 01:29:38 UTC (rev 277237)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyRuntimeError.cpp	2021-05-09 02:18:25 UTC (rev 277238)
@@ -35,7 +35,7 @@
 JSObject* createJSWebAssemblyRuntimeError(JSGlobalObject* globalObject, VM& vm, const String& message)
 {
     ASSERT(!message.isEmpty());
-    return ErrorInstance::create(globalObject, vm, globalObject->webAssemblyRuntimeErrorStructure(), message, jsUndefined(), defaultSourceAppender, TypeNothing, ErrorType::Error, true);
+    return ErrorInstance::create(globalObject, vm, globalObject->webAssemblyRuntimeErrorStructure(), message, JSValue(), defaultSourceAppender, TypeNothing, ErrorType::Error, true);
 }
     
 } // namespace JSC
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to