Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (268238 => 268239)
--- trunk/Source/_javascript_Core/ChangeLog 2020-10-09 00:45:29 UTC (rev 268238)
+++ trunk/Source/_javascript_Core/ChangeLog 2020-10-09 00:48:35 UTC (rev 268239)
@@ -1,3 +1,18 @@
+2020-10-08 Ryosuke Niwa <rn...@webkit.org>
+
+ Make it possible to send an arbitrary IPC message from _javascript_
+ https://bugs.webkit.org/show_bug.cgi?id=217423
+ <rdar://problem/69969351>
+
+ Reviewed by Geoffrey Garen.
+
+ Added a helper function to get uint64_t out of BigInt.
+
+ * runtime/JSBigInt.cpp:
+ (JSC::JSBigInt::toUint64Heap): Added.
+ * runtime/JSBigInt.h:
+ (JSC::JSBigInt::toUint64): Added.
+
2020-10-07 Yusuke Suzuki <ysuz...@apple.com>
[JSC] Restrict more ptr-tagging and avoid using OperationPtrTag for JIT code
Modified: trunk/Source/_javascript_Core/runtime/JSBigInt.cpp (268238 => 268239)
--- trunk/Source/_javascript_Core/runtime/JSBigInt.cpp 2020-10-09 00:45:29 UTC (rev 268238)
+++ trunk/Source/_javascript_Core/runtime/JSBigInt.cpp 2020-10-09 00:48:35 UTC (rev 268239)
@@ -3049,6 +3049,29 @@
}
#endif
+Optional<uint64_t> JSBigInt::toUint64Heap(JSBigInt* bigInt)
+{
+ auto length = bigInt->length();
+ if (!length)
+ return 0;
+ if (bigInt->sign())
+ return WTF::nullopt;
+
+ static_assert(sizeof(uint64_t) == sizeof(Digit) || sizeof(uint64_t) == sizeof(Digit) * 2, "Digit must be either 32-bit or 64-bit");
+ if (sizeof(uint64_t) == sizeof(Digit)) {
+ if (length > 1)
+ return WTF::nullopt;
+ return bigInt->digit(0);
+ }
+
+ if (length > 2)
+ return WTF::nullopt;
+ uint64_t result = bigInt->digit(0);
+ if (length == 1)
+ result += static_cast<uint64_t>(bigInt->digit(0)) << 32;
+ return result;
+}
+
static ALWAYS_INLINE unsigned computeHash(JSBigInt::Digit* digits, unsigned length, bool sign)
{
Hasher hasher;
Modified: trunk/Source/_javascript_Core/runtime/JSBigInt.h (268238 => 268239)
--- trunk/Source/_javascript_Core/runtime/JSBigInt.h 2020-10-09 00:45:29 UTC (rev 268238)
+++ trunk/Source/_javascript_Core/runtime/JSBigInt.h 2020-10-09 00:48:35 UTC (rev 268239)
@@ -73,7 +73,7 @@
static JSBigInt* tryCreateFrom(VM&, int32_t value);
static JSBigInt* createFrom(JSGlobalObject*, uint32_t value);
static JSBigInt* createFrom(JSGlobalObject*, int64_t value);
- static JSBigInt* createFrom(JSGlobalObject*, uint64_t value);
+ JS_EXPORT_PRIVATE static JSBigInt* createFrom(JSGlobalObject*, uint64_t value);
static JSBigInt* createFrom(JSGlobalObject*, bool value);
static JSBigInt* createFrom(JSGlobalObject*, double value);
@@ -422,6 +422,20 @@
static JSValue asUintN(JSGlobalObject*, uint64_t numberOfBits, int32_t bigIntAsInt32);
#endif
+ static Optional<uint64_t> toUint64(JSValue bigInt)
+ {
+ ASSERT(bigInt.isBigInt());
+#if USE(BIGINT32)
+ if (bigInt.isBigInt32()) {
+ auto value = bigInt.bigInt32AsInt32();
+ if (value < 0)
+ return WTF::nullopt;
+ return value;
+ }
+#endif
+ return toUint64Heap(jsCast<JSBigInt*>(bigInt));
+ }
+
Digit digit(unsigned);
void setDigit(unsigned, Digit); // Use only when initializing.
JS_EXPORT_PRIVATE JSBigInt* rightTrim(JSGlobalObject*);
@@ -576,6 +590,8 @@
template <typename BigIntImpl>
static ImplResult truncateAndSubFromPowerOfTwo(JSGlobalObject*, int32_t, BigIntImpl, bool resultSign);
+ JS_EXPORT_PRIVATE static Optional<uint64_t> toUint64Heap(JSBigInt*);
+
inline static size_t offsetOfData()
{
return OBJECT_OFFSETOF(JSBigInt, m_data);
Modified: trunk/Source/WTF/ChangeLog (268238 => 268239)
--- trunk/Source/WTF/ChangeLog 2020-10-09 00:45:29 UTC (rev 268238)
+++ trunk/Source/WTF/ChangeLog 2020-10-09 00:48:35 UTC (rev 268239)
@@ -1,3 +1,19 @@
+2020-10-08 Ryosuke Niwa <rn...@webkit.org>
+
+ Make it possible to send an arbitrary IPC message from _javascript_
+ https://bugs.webkit.org/show_bug.cgi?id=217423
+ <rdar://problem/69969351>
+
+ Reviewed by Geoffrey Garen.
+
+ Added a compile time flag (ENABLE_IPC_TESTING_API) and a runtime flag (IPCTestingAPIEnabled)
+ for the _javascript_ API to test IPC.
+
+ * Scripts/GeneratePreferences.rb:
+ (Preference::nameLower): Keep IPC uppercase.
+ * Scripts/Preferences/WebPreferencesInternal.yaml: Added IPCTestingAPIEnabled.
+ * wtf/PlatformEnable.h: Added ENABLE_IPC_TESTING_API.
+
2020-10-08 Alex Christensen <achristen...@webkit.org>
REGRESSION (r267763): [ iOS wk2 ] http/tests/in-app-browser-privacy/non-app-bound-domain-does-not-get-app-bound-session.html is a constant failure
Modified: trunk/Source/WTF/Scripts/GeneratePreferences.rb (268238 => 268239)
--- trunk/Source/WTF/Scripts/GeneratePreferences.rb 2020-10-09 00:45:29 UTC (rev 268238)
+++ trunk/Source/WTF/Scripts/GeneratePreferences.rb 2020-10-09 00:48:35 UTC (rev 268239)
@@ -120,7 +120,7 @@
@getter
elsif @name.start_with?("VP")
@name[0..1].downcase + @name[2..@name.length]
- elsif @name.start_with?("CSS", "XSS", "FTP", "DOM", "DNS", "PDF", "ICE")
+ elsif @name.start_with?("CSS", "DOM", "DNS", "FTP", "ICE", "IPC", "PDF", "XSS")
@name[0..2].downcase + @name[3..@name.length]
elsif @name.start_with?("HTTP")
@name[0..3].downcase + @name[4..@name.length]
Modified: trunk/Source/WTF/Scripts/Preferences/WebPreferencesInternal.yaml (268238 => 268239)
--- trunk/Source/WTF/Scripts/Preferences/WebPreferencesInternal.yaml 2020-10-09 00:45:29 UTC (rev 268238)
+++ trunk/Source/WTF/Scripts/Preferences/WebPreferencesInternal.yaml 2020-10-09 00:48:35 UTC (rev 268239)
@@ -279,6 +279,17 @@
WebKit:
default: true
+IPCTestingAPIEnabled:
+ type: bool
+ humanReadableName: "IPC Testing API"
+ humanReadableDescription: "Enable IPC Testing API for _javascript_"
+ webcoreBinding: none
+ condition: ENABLE(IPC_TESTING_API)
+ exposed: [ WebKit ]
+ defaultValue:
+ WebKit:
+ default: false
+
InputTypeColorEnabled:
type: bool
humanReadableName: "Color Inputs"
Modified: trunk/Source/WTF/wtf/PlatformEnable.h (268238 => 268239)
--- trunk/Source/WTF/wtf/PlatformEnable.h 2020-10-09 00:45:29 UTC (rev 268238)
+++ trunk/Source/WTF/wtf/PlatformEnable.h 2020-10-09 00:48:35 UTC (rev 268239)
@@ -315,6 +315,13 @@
#define ENABLE_INPUT_TYPE_WEEK 0
#endif
+#if !defined(ENABLE_IPC_TESTING_API)
+/* Enable IPC testing on all ASAN builds and debug builds. */
+#if ASAN_ENABLED || !defined(NDEBUG)
+#define ENABLE_IPC_TESTING_API 1
+#endif
+#endif
+
#if ENABLE(INPUT_TYPE_DATE) || ENABLE(INPUT_TYPE_DATETIMELOCAL) || ENABLE(INPUT_TYPE_MONTH) || ENABLE(INPUT_TYPE_TIME) || ENABLE(INPUT_TYPE_WEEK)
#if !defined(ENABLE_DATE_AND_TIME_INPUT_TYPES)
#define ENABLE_DATE_AND_TIME_INPUT_TYPES 1
Modified: trunk/Source/WebKit/ChangeLog (268238 => 268239)
--- trunk/Source/WebKit/ChangeLog 2020-10-09 00:45:29 UTC (rev 268238)
+++ trunk/Source/WebKit/ChangeLog 2020-10-09 00:48:35 UTC (rev 268239)
@@ -1,3 +1,78 @@
+2020-10-08 Ryosuke Niwa <rn...@webkit.org>
+
+ Make it possible to send an arbitrary IPC message from _javascript_
+ https://bugs.webkit.org/show_bug.cgi?id=217423
+ <rdar://problem/69969351>
+
+ Reviewed by Geoffrey Garen.
+
+ This patch introduces the _javascript_ API (window.IPC) to send IPC out of WebContent process.
+ The feature is compiled in under ASAN and Debug builds and can be enabled at runtime.
+
+ window.IPC has two methods: sendMessage and sendSyncMessage which sends an async and sync IPC respectively.
+ It takes the destination process name (UI, GPU, or Networking), the destination ID (e.g. WebPageProxy ID),
+ message ID, timeout for sendSyncMessage, and optionally IPC message arguments. The message arguments can be
+ passed in as a TypedArray or ArrayBuffer, or a _javascript_ array that recursively describes encoded objects.
+
+ Each object can be either a TypedArray or ArrayBuffer, which will be treated as encoded message, an array
+ which will be encoded as a Vector with each item within the array encoded recursively, or a dictionary which
+ describes a specific type.
+
+ When a specific type is described via a dictionary, "value" is encoed based on "type" as follows:
+ - When "type" is "String", "value" is encoded as a WTF::String, treating null or undefined as a null string.
+ - When "type" is "bool", "int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t",
+ or "uint64_t", "value" (which can be BigInt or a number) is encoded as the respective C++ type.
+ - When "type" is "RGBA", "value" is used as PackedColor::RGBA to construct WebCore::Color to be encoded.
+ - When "type" is "IntRect" or "FloatRect", "x", "y", "width", and "height" are treated as respective values
+ of IntRect or FloatRect C++ objects, and the constructed *Rect is encoded.
+ - When "type" is "FrameInfoData", the context object's WebFrame's FrameInfoData is encoded.
+
+ The list of IPC messages are exposed on window.IPC.messages, and VisitedLinkStore ID, WebPageProxy ID,
+ and frame identifiers are also exposed as static variables on window.IPC.
+
+ * Sources.txt:
+ * WebKit.xcodeproj/project.pbxproj:
+ * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
+ (WebKit::WebFrameLoaderClient::dispatchDidClearWindowObjectInWorld): Inject the API if enabled.
+ * WebProcess/WebPage/IPCTestingAPI.cpp: Added.
+ (WebKit::IPCTestingAPI::JSIPC::create): Added.
+ (WebKit::IPCTestingAPI::JSIPC::webFrame): Added.
+ (WebKit::IPCTestingAPI::JSIPC::JSIPC): Added.
+ (WebKit::IPCTestingAPI::JSIPC::wrapperClass): Added.
+ (WebKit::IPCTestingAPI::JSIPC::unwrap): Added.
+ (WebKit::IPCTestingAPI::JSIPC::toWrapped): Added.
+ (WebKit::IPCTestingAPI::JSIPC::initialize): Added.
+ (WebKit::IPCTestingAPI::JSIPC::finalize): Added.
+ (WebKit::IPCTestingAPI::JSIPC::staticFunctions): Added.
+ (WebKit::IPCTestingAPI::JSIPC::staticValues): Added.
+ (WebKit::IPCTestingAPI::convertToUint64): Added.
+ (WebKit::IPCTestingAPI::processTargetFromArgument): Added.
+ (WebKit::IPCTestingAPI::destinationIDFromArgument): Added.
+ (WebKit::IPCTestingAPI::messageIDFromArgument): Added.
+ (WebKit::IPCTestingAPI::encodeTypedArray): Added.
+ (WebKit::IPCTestingAPI::createTypeError): Added.
+ (WebKit::IPCTestingAPI::encodeRectType): Added.
+ (WebKit::IPCTestingAPI::encodeIntegralType): Added.
+ (WebKit::IPCTestingAPI::VectorEncodeHelper::encode const): Added.
+ (WebKit::IPCTestingAPI::encodeArgument): Added.
+ (WebKit::IPCTestingAPI::JSIPC::sendMessage): Added.
+ (WebKit::IPCTestingAPI::JSIPC::sendSyncMessage): Added.
+ (WebKit::IPCTestingAPI::JSIPC::visitedLinkStoreID): Added.
+ (WebKit::IPCTestingAPI::JSIPC::webPageProxyID): Added.
+ (WebKit::IPCTestingAPI::JSIPC::frameIdentifier): Added.
+ (WebKit::IPCTestingAPI::JSIPC::retrieveID): Added.
+ (WebKit::IPCTestingAPI::JSIPC::messages): Added.
+ (WebKit::IPCTestingAPI::inject):
+ * WebProcess/WebPage/IPCTestingAPI.h: Added.
+ * WebProcess/WebPage/WebFrame.h:
+ * WebProcess/WebPage/WebPage.cpp:
+ (WebKit::m_limitsNavigationsToAppBoundDomains):
+ (WebKit::WebPage::updatePreferences):
+ * WebProcess/WebPage/WebPage.h:
+ (WebKit::WebPage::ipcTestingAPIEnabled const):
+ (WebKit::WebPage::webPageProxyID const):
+ (WebKit::WebPage::visitedLinkTableID const):
+
2020-10-08 Peng Liu <peng.l...@apple.com>
[Media in GPU Process] Cannot activate or deactivate an audio session
Modified: trunk/Source/WebKit/Sources.txt (268238 => 268239)
--- trunk/Source/WebKit/Sources.txt 2020-10-09 00:45:29 UTC (rev 268238)
+++ trunk/Source/WebKit/Sources.txt 2020-10-09 00:48:35 UTC (rev 268239)
@@ -652,6 +652,7 @@
WebProcess/WebPage/DrawingArea.cpp
WebProcess/WebPage/EventDispatcher.cpp
WebProcess/WebPage/FindController.cpp
+WebProcess/WebPage/IPCTestingAPI.cpp
WebProcess/WebPage/PageBanner.cpp
WebProcess/WebPage/VisitedLinkTableController.cpp
WebProcess/WebPage/WebBackForwardListProxy.cpp
Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (268238 => 268239)
--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2020-10-09 00:45:29 UTC (rev 268238)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2020-10-09 00:48:35 UTC (rev 268239)
@@ -4487,6 +4487,8 @@
9B02E0CD235EB967004044B2 /* _WKTextManipulationToken.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _WKTextManipulationToken.h; sourceTree = "<group>"; };
9B02E0CE235EBB14004044B2 /* _WKTextManipulationToken.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = _WKTextManipulationToken.mm; sourceTree = "<group>"; };
9B02E0D0235EBCCA004044B2 /* _WKTextManipulationItem.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = _WKTextManipulationItem.mm; sourceTree = "<group>"; };
+ 9B033E71252580F300501071 /* IPCTestingAPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IPCTestingAPI.h; sourceTree = "<group>"; };
+ 9B033E72252580F300501071 /* IPCTestingAPI.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = IPCTestingAPI.cpp; sourceTree = "<group>"; };
9B1229CB23FF25F2008CA751 /* RemoteAudioDestinationManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RemoteAudioDestinationManager.h; sourceTree = "<group>"; };
9B1229CC23FF25F2008CA751 /* RemoteAudioDestinationManager.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = RemoteAudioDestinationManager.cpp; sourceTree = "<group>"; };
9B1229CF23FF2814008CA751 /* RemoteAudioDestinationManager.messages.in */ = {isa = PBXFileReference; lastKnownFileType = text; path = RemoteAudioDestinationManager.messages.in; sourceTree = "<group>"; };
@@ -8866,6 +8868,8 @@
1AA575FD1496B6F300A4EE06 /* EventDispatcher.messages.in */,
1A90C1F31264FD71003E44D4 /* FindController.cpp */,
1A90C1F21264FD71003E44D4 /* FindController.h */,
+ 9B033E72252580F300501071 /* IPCTestingAPI.cpp */,
+ 9B033E71252580F300501071 /* IPCTestingAPI.h */,
7C387433172F5615001BD88A /* PageBanner.cpp */,
7CF47FF917275C57008ACB91 /* PageBanner.h */,
2D819B99186275B3001F03D1 /* ViewGestureGeometryCollector.cpp */,
Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp (268238 => 268239)
--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp 2020-10-09 00:45:29 UTC (rev 268238)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp 2020-10-09 00:48:35 UTC (rev 268239)
@@ -32,6 +32,7 @@
#include "FindController.h"
#include "FormDataReference.h"
#include "FrameInfoData.h"
+#include "IPCTestingAPI.h"
#include "InjectedBundle.h"
#include "InjectedBundleDOMWindowExtension.h"
#include "InjectedBundleNavigationAction.h"
@@ -1743,6 +1744,11 @@
if (!webPage)
return;
+#if ENABLE(IPC_TESTING_API)
+ if (world.isNormal() && webPage->ipcTestingAPIEnabled())
+ IPCTestingAPI::inject(*webPage, m_frame.get(), world);
+#endif
+
webPage->injectedBundleLoaderClient().didClearWindowObjectForFrame(*webPage, m_frame, world);
WebAutomationSessionProxy* automationSessionProxy = WebProcess::singleton().automationSessionProxy();
Added: trunk/Source/WebKit/WebProcess/WebPage/IPCTestingAPI.cpp (0 => 268239)
--- trunk/Source/WebKit/WebProcess/WebPage/IPCTestingAPI.cpp (rev 0)
+++ trunk/Source/WebKit/WebProcess/WebPage/IPCTestingAPI.cpp 2020-10-09 00:48:35 UTC (rev 268239)
@@ -0,0 +1,604 @@
+/*
+ * Copyright (C) 2020 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#include "config.h"
+#include "IPCTestingAPI.h"
+
+#if ENABLE(IPC_TESTING_API)
+
+#include "Encoder.h"
+#include "FrameInfoData.h"
+#include "GPUProcessConnection.h"
+#include "MessageNames.h"
+#include "NetworkProcessConnection.h"
+#include "WebCoreArgumentCoders.h"
+#include "WebFrame.h"
+#include "WebPage.h"
+#include "WebProcess.h"
+#include <_javascript_Core/APICast.h>
+#include <_javascript_Core/BuiltinNames.h>
+#include <_javascript_Core/JSBigInt.h>
+#include <_javascript_Core/JSClassRef.h>
+#include <_javascript_Core/JSLock.h>
+#include <_javascript_Core/JSObject.h>
+#include <_javascript_Core/JSValueRef.h>
+#include <_javascript_Core/_javascript_.h>
+#include <_javascript_Core/OpaqueJSString.h>
+#include <WebCore/DOMWrapperWorld.h>
+#include <WebCore/Frame.h>
+#include <WebCore/ScriptController.h>
+
+namespace WebKit {
+
+namespace IPCTestingAPI {
+
+class JSIPC : public RefCounted<JSIPC> {
+public:
+ static Ref<JSIPC> create(WebPage& webPage, WebFrame& webFrame)
+ {
+ return adoptRef(*new JSIPC(webPage, webFrame));
+ }
+
+ static JSClassRef wrapperClass();
+
+ WebFrame* webFrame() { return m_webFrame.get(); }
+
+private:
+ JSIPC(WebPage& webPage, WebFrame& webFrame)
+ : m_webPage(makeWeakPtr(webPage))
+ , m_webFrame(makeWeakPtr(webFrame))
+ { }
+
+ static JSIPC* unwrap(JSObjectRef);
+ static JSIPC* toWrapped(JSContextRef, JSValueRef);
+ static void initialize(JSContextRef, JSObjectRef);
+ static void finalize(JSObjectRef);
+ static const JSStaticFunction* staticFunctions();
+ static const JSStaticValue* staticValues();
+
+ static JSValueRef sendMessage(JSContextRef, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
+ static JSValueRef sendSyncMessage(JSContextRef, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);
+
+ static JSValueRef visitedLinkStoreID(JSContextRef, JSObjectRef, JSStringRef, JSValueRef* exception);
+ static JSValueRef webPageProxyID(JSContextRef, JSObjectRef, JSStringRef, JSValueRef* exception);
+ static JSValueRef frameIdentifier(JSContextRef, JSObjectRef, JSStringRef, JSValueRef* exception);
+ static JSValueRef retrieveID(JSContextRef, JSObjectRef thisObject, JSValueRef* exception, const WTF::Function<uint64_t(JSIPC&)>&);
+
+ static JSValueRef messages(JSContextRef, JSObjectRef, JSStringRef, JSValueRef* exception);
+
+ WeakPtr<WebPage> m_webPage;
+ WeakPtr<WebFrame> m_webFrame;
+};
+
+JSClassRef JSIPC::wrapperClass()
+{
+ static JSClassRef jsClass;
+ if (!jsClass) {
+ JSClassDefinition definition = kJSClassDefinitionEmpty;
+ definition.className = "UIProcess";
+ definition.parentClass = 0;
+ definition.staticValues = staticValues();
+ definition.staticFunctions = staticFunctions();
+ definition.initialize = initialize;
+ definition.finalize = finalize;
+ jsClass = JSClassCreate(&definition);
+ }
+ return jsClass;
+}
+
+inline JSIPC* JSIPC::unwrap(JSObjectRef object)
+{
+ return static_cast<JSIPC*>(JSObjectGetPrivate(object));
+}
+
+JSIPC* JSIPC::toWrapped(JSContextRef context, JSValueRef value)
+{
+ if (!context || !value || !JSValueIsObjectOfClass(context, value, wrapperClass()))
+ return nullptr;
+ return unwrap(JSValueToObject(context, value, 0));
+}
+
+void JSIPC::initialize(JSContextRef, JSObjectRef object)
+{
+ unwrap(object)->ref();
+}
+
+void JSIPC::finalize(JSObjectRef object)
+{
+ unwrap(object)->deref();
+}
+
+const JSStaticFunction* JSIPC::staticFunctions()
+{
+ static const JSStaticFunction functions[] = {
+ { "sendMessage", sendMessage, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
+ { "sendSyncMessage", sendSyncMessage, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
+ { 0, 0, 0 }
+ };
+ return functions;
+}
+
+const JSStaticValue* JSIPC::staticValues()
+{
+ static const JSStaticValue values[] = {
+ { "visitedLinkStoreID", visitedLinkStoreID, 0, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
+ { "webPageProxyID", webPageProxyID, 0, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
+ { "frameIdentifier", frameIdentifier, 0, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
+ { "messages", messages, 0, kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly },
+ { 0, 0, 0, 0 }
+ };
+ return values;
+}
+
+static Optional<uint64_t> convertToUint64(JSC::JSValue jsValue)
+{
+ if (jsValue.isNumber()) {
+ double value = jsValue.asNumber();
+ if (value < 0 || trunc(value) != value)
+ return WTF::nullopt;
+ return value;
+ }
+ if (jsValue.isBigInt())
+ return JSC::JSBigInt::toUint64(jsValue);
+ return WTF::nullopt;
+}
+
+static RefPtr<IPC::Connection> processTargetFromArgument(JSC::JSGlobalObject* globalObject, JSValueRef valueRef, JSValueRef* exception)
+{
+ auto scope = DECLARE_CATCH_SCOPE(globalObject->vm());
+ auto name = toJS(globalObject, valueRef).toWTFString(globalObject);
+ if (scope.exception())
+ return nullptr;
+
+ if (name == "UI")
+ return WebProcess::singleton().parentProcessConnection();
+#if ENABLE(GPU_PROCESS)
+ if (name == "GPU")
+ return &WebProcess::singleton().ensureGPUProcessConnection().connection();
+#endif
+ if (name == "Networking")
+ return &WebProcess::singleton().ensureNetworkProcessConnection().connection();
+
+ *exception = toRef(JSC::createTypeError(globalObject, "Target process must be UI, GPU, or Networking"_s));
+ return nullptr;
+}
+
+static Optional<uint64_t> destinationIDFromArgument(JSC::JSGlobalObject* globalObject, JSValueRef valueRef, JSValueRef* exception)
+{
+ auto jsValue = toJS(globalObject, valueRef);
+ auto result = convertToUint64(jsValue);
+ if (!result)
+ *exception = toRef(JSC::createTypeError(globalObject, "destinationID must be an integer"_s));
+ return result;
+}
+
+static Optional<uint64_t> messageIDFromArgument(JSC::JSGlobalObject* globalObject, JSValueRef valueRef, JSValueRef* exception)
+{
+ auto jsValue = toJS(globalObject, valueRef);
+ auto result = convertToUint64(jsValue);
+ if (!result)
+ *exception = toRef(JSC::createTypeError(globalObject, "messageID must be an integer"_s));
+ return result;
+}
+
+static bool encodeTypedArray(IPC::Encoder& encoder, JSContextRef context, JSValueRef valueRef, JSTypedArrayType type, JSValueRef* exception)
+{
+ ASSERT(type != kJSTypedArrayTypeNone);
+
+ auto objectRef = JSValueToObject(context, valueRef, exception);
+ if (!objectRef)
+ return false;
+
+ void* buffer;
+ if (type == kJSTypedArrayTypeArrayBuffer)
+ buffer = JSObjectGetArrayBufferBytesPtr(context, objectRef, exception);
+ else
+ buffer = JSObjectGetTypedArrayBytesPtr(context, objectRef, exception);
+ if (!buffer)
+ return false;
+
+ size_t bufferSize;
+ if (type == kJSTypedArrayTypeArrayBuffer)
+ bufferSize = JSObjectGetArrayBufferByteLength(context, objectRef, exception);
+ else
+ bufferSize = JSObjectGetTypedArrayByteLength(context, objectRef, exception);
+ if (!bufferSize)
+ return false;
+
+ encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(buffer), bufferSize, 1);
+ return true;
+}
+
+static JSValueRef createTypeError(JSContextRef context, const String& message)
+{
+ JSC::JSLockHolder lock(toJS(context)->vm());
+ return toRef(JSC::createTypeError(toJS(context), message));
+}
+
+template<typename RectType> bool encodeRectType(IPC::Encoder& encoder, JSC::JSGlobalObject* globalObject, JSC::JSObject* jsObject)
+{
+ auto& vm = globalObject->vm();
+ auto jsX = jsObject->get(globalObject, JSC::Identifier::fromString(vm, "x"_s));
+ if (!jsX.isNumber())
+ return false;
+ auto jsY = jsObject->get(globalObject, JSC::Identifier::fromString(vm, "y"_s));
+ if (!jsY.isNumber())
+ return false;
+ auto jsWidth = jsObject->get(globalObject, JSC::Identifier::fromString(vm, "width"_s));
+ if (!jsWidth.isNumber())
+ return false;
+ auto jsHeight = jsObject->get(globalObject, JSC::Identifier::fromString(vm, "height"_s));
+ if (!jsHeight.isNumber())
+ return false;
+ encoder << RectType(jsX.asNumber(), jsY.asNumber(), jsWidth.asNumber(), jsHeight.asNumber());
+ return true;
+}
+
+template<typename IntegralType> bool encodeIntegralType(IPC::Encoder& encoder, JSC::JSValue jsValue)
+{
+ if (jsValue.isBigInt()) {
+ // FIXME: Support negative BigInt.
+ auto result = JSC::JSBigInt::toUint64(jsValue);
+ if (!result)
+ return false;
+ encoder << static_cast<IntegralType>(*result);
+ return true;
+ }
+ if (!jsValue.isNumber())
+ return false;
+ double value = jsValue.asNumber();
+ encoder << static_cast<IntegralType>(value);
+ return true;
+}
+
+enum class ArrayMode { Tuple, Vector };
+static bool encodeArgument(IPC::Encoder&, JSIPC&, JSContextRef, JSValueRef, JSValueRef* exception, ArrayMode = ArrayMode::Tuple);
+
+struct VectorEncodeHelper {
+ Ref<JSIPC> jsIPC;
+ JSContextRef context;
+ JSValueRef valueRef;
+ JSValueRef* exception;
+ bool& success;
+
+ void encode(IPC::Encoder& encoder) const
+ {
+ if (!success)
+ return;
+ success = encodeArgument(encoder, jsIPC.get(), context, valueRef, exception, ArrayMode::Vector);
+ }
+};
+
+static bool encodeArgument(IPC::Encoder& encoder, JSIPC& jsIPC, JSContextRef context, JSValueRef valueRef, JSValueRef* exception, ArrayMode arrayMode)
+{
+ auto objectRef = JSValueToObject(context, valueRef, exception);
+ if (!objectRef)
+ return false;
+
+ if (auto type = JSValueGetTypedArrayType(context, objectRef, exception); type != kJSTypedArrayTypeNone)
+ return encodeTypedArray(encoder, context, objectRef, type, exception);
+
+ auto* globalObject = toJS(context);
+ auto& vm = globalObject->vm();
+ JSC::JSLockHolder lock(vm);
+ auto scope = DECLARE_CATCH_SCOPE(globalObject->vm());
+ auto* jsObject = toJS(globalObject, objectRef).getObject();
+ ASSERT(jsObject);
+ if (JSValueIsArray(context, objectRef)) {
+ auto jsLength = jsObject->get(globalObject, JSC::Identifier::fromString(vm, "length"_s));
+ if (scope.exception())
+ return false;
+ if (!jsLength.isNumber()) {
+ *exception = createTypeError(context, "Array length is not a number"_s);
+ return false;
+ }
+ auto length = jsLength.asNumber();
+
+ Vector<VectorEncodeHelper> vector;
+ bool success = true;
+ for (unsigned i = 0; i < length; ++i) {
+ auto itemRef = JSObjectGetPropertyAtIndex(context, objectRef, i, exception);
+ if (!itemRef)
+ return false;
+ vector.append(VectorEncodeHelper { jsIPC, context, itemRef, exception, success });
+ }
+ if (arrayMode == ArrayMode::Tuple) {
+ for (auto& item : vector)
+ item.encode(encoder);
+ } else
+ encoder << vector;
+ return success;
+ }
+
+ auto jsType = jsObject->get(globalObject, JSC::Identifier::fromString(vm, "type"_s));
+ if (scope.exception())
+ return false;
+
+ auto type = jsType.toWTFString(globalObject);
+ if (scope.exception())
+ return false;
+
+ if (type == "IntRect") {
+ if (!encodeRectType<WebCore::IntRect>(encoder, globalObject, jsObject)) {
+ *exception = createTypeError(context, "Failed to convert IntRect"_s);
+ return false;
+ }
+ return true;
+ }
+
+ if (type == "FloatRect") {
+ if (!encodeRectType<WebCore::FloatRect>(encoder, globalObject, jsObject)) {
+ *exception = createTypeError(context, "Failed to convert FloatRect"_s);
+ return false;
+ }
+ return true;
+ }
+
+ if (type == "FrameInfoData") {
+ auto webFrame = makeRefPtr(jsIPC.webFrame());
+ if (!webFrame) {
+ *exception = createTypeError(context, "Failed to get the frame"_s);
+ return false;
+ }
+ encoder << webFrame->info();
+ return true;
+ }
+
+ auto jsValue = jsObject->get(globalObject, JSC::Identifier::fromString(vm, "value"_s));
+ if (scope.exception())
+ return false;
+
+ if (type == "String") {
+ if (jsValue.isUndefinedOrNull()) {
+ encoder << String { };
+ return true;
+ }
+ auto string = jsValue.toWTFString(globalObject);
+ if (scope.exception())
+ return false;
+ encoder << string;
+ return true;
+ }
+
+ if (type == "RGBA") {
+ if (!jsValue.isNumber()) {
+ *exception = createTypeError(context, "RGBA value should be a number"_s);
+ return false;
+ }
+ uint32_t rgba = jsValue.asNumber();
+ encoder << WebCore::Color { WebCore::asSRGBA(WebCore::PackedColor::RGBA(rgba)) };
+ return true;
+ }
+
+ bool integralResult;
+ if (type == "bool")
+ integralResult = encodeIntegralType<bool>(encoder, jsValue);
+ else if (type == "int8_t")
+ integralResult = encodeIntegralType<int8_t>(encoder, jsValue);
+ else if (type == "int16_t")
+ integralResult = encodeIntegralType<int16_t>(encoder, jsValue);
+ else if (type == "int32_t")
+ integralResult = encodeIntegralType<int32_t>(encoder, jsValue);
+ else if (type == "int64_t")
+ integralResult = encodeIntegralType<int64_t>(encoder, jsValue);
+ else if (type == "uint8_t")
+ integralResult = encodeIntegralType<uint8_t>(encoder, jsValue);
+ else if (type == "uint16_t")
+ integralResult = encodeIntegralType<uint16_t>(encoder, jsValue);
+ else if (type == "uint32_t")
+ integralResult = encodeIntegralType<uint32_t>(encoder, jsValue);
+ else if (type == "uint64_t")
+ integralResult = encodeIntegralType<uint64_t>(encoder, jsValue);
+ else {
+ *exception = createTypeError(context, "Bad type name"_s);
+ return false;
+ }
+ if (!integralResult) {
+ *exception = createTypeError(context, "Failed to encode an integer"_s);
+ return false;
+ }
+ return true;
+}
+
+JSValueRef JSIPC::sendMessage(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ auto* globalObject = toJS(context);
+ JSC::JSLockHolder lock(globalObject->vm());
+ auto jsIPC = makeRefPtr(toWrapped(context, thisObject));
+ if (!jsIPC) {
+ *exception = toRef(JSC::createTypeError(toJS(context), "Wrong type"_s));
+ return JSValueMakeUndefined(context);
+ }
+
+ if (argumentCount < 3) {
+ *exception = toRef(JSC::createTypeError(toJS(context), "Must specify the target process, desination ID, and message ID as the first three arguments"_s));
+ return JSValueMakeUndefined(context);
+ }
+
+ auto connection = processTargetFromArgument(globalObject, arguments[0], exception);
+ if (!connection)
+ return JSValueMakeUndefined(context);
+
+ auto destinationID = destinationIDFromArgument(globalObject, arguments[1], exception);
+ if (!destinationID)
+ return JSValueMakeUndefined(context);
+
+ auto messageID = messageIDFromArgument(globalObject, arguments[2], exception);
+ if (!messageID)
+ return JSValueMakeUndefined(context);
+
+ auto encoder = makeUnique<IPC::Encoder>(static_cast<IPC::MessageName>(static_cast<uint64_t>(*messageID)), *destinationID);
+
+ if (argumentCount > 3) {
+ if (!encodeArgument(*encoder, *jsIPC, context, arguments[3], exception))
+ return JSValueMakeUndefined(context);
+ }
+
+ // FIXME: Add the support for specifying IPC options.
+
+ connection->sendMessage(WTFMove(encoder), { });
+
+ return JSValueMakeUndefined(context);
+}
+
+JSValueRef JSIPC::sendSyncMessage(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ auto* globalObject = toJS(context);
+ JSC::JSLockHolder lock(globalObject->vm());
+ auto jsIPC = makeRefPtr(toWrapped(context, thisObject));
+ if (!jsIPC) {
+ *exception = toRef(JSC::createTypeError(toJS(context), "Wrong type"_s));
+ return JSValueMakeUndefined(context);
+ }
+
+ if (argumentCount < 4) {
+ *exception = toRef(JSC::createTypeError(toJS(context), "Must specify the target process, desination ID, message ID, and timeout as the first four arguments"_s));
+ return JSValueMakeUndefined(context);
+ }
+
+ auto connection = processTargetFromArgument(globalObject, arguments[0], exception);
+ if (!connection)
+ return JSValueMakeUndefined(context);
+
+ auto destinationID = destinationIDFromArgument(globalObject, arguments[1], exception);
+ if (!destinationID)
+ return JSValueMakeUndefined(context);
+
+ auto messageID = messageIDFromArgument(globalObject, arguments[2], exception);
+ if (!messageID)
+ return JSValueMakeUndefined(context);
+
+ Seconds timeout;
+ {
+ auto jsValue = toJS(globalObject, arguments[3]);
+ if (!jsValue.isNumber()) {
+ *exception = toRef(JSC::createTypeError(globalObject, "timeout must be a number"_s));
+ return JSValueMakeUndefined(context);
+ }
+ timeout = Seconds { jsValue.asNumber() };
+ }
+
+ // FIXME: Support the options.
+
+ uint64_t syncRequestID = 0;
+ auto encoder = connection->createSyncMessageEncoder(static_cast<IPC::MessageName>(static_cast<uint64_t>(*messageID)), *destinationID, syncRequestID);
+
+ if (argumentCount > 4) {
+ if (!encodeArgument(*encoder, *jsIPC, context, arguments[4], exception))
+ return JSValueMakeUndefined(context);
+ }
+
+ auto replyDecoder = connection->sendSyncMessage(syncRequestID, WTFMove(encoder), timeout, { });
+ // FIXME: Decode the reply.
+
+ return JSValueMakeUndefined(context);
+}
+
+JSValueRef JSIPC::visitedLinkStoreID(JSContextRef context, JSObjectRef thisObject, JSStringRef, JSValueRef* exception)
+{
+ return retrieveID(context, thisObject, exception, [](JSIPC& wrapped) {
+ auto webPage = makeRef(*wrapped.m_webPage);
+ return webPage->visitedLinkTableID();
+ });
+}
+
+JSValueRef JSIPC::webPageProxyID(JSContextRef context, JSObjectRef thisObject, JSStringRef, JSValueRef* exception)
+{
+ return retrieveID(context, thisObject, exception, [](JSIPC& wrapped) {
+ return wrapped.m_webPage->webPageProxyID();
+ });
+}
+
+JSValueRef JSIPC::frameIdentifier(JSContextRef context, JSObjectRef thisObject, JSStringRef, JSValueRef* exception)
+{
+ return retrieveID(context, thisObject, exception, [](JSIPC& wrapped) {
+ return wrapped.m_webFrame->frameID().toUInt64();
+ });
+}
+
+JSValueRef JSIPC::retrieveID(JSContextRef context, JSObjectRef thisObject, JSValueRef* exception, const WTF::Function<uint64_t(JSIPC&)>& callback)
+{
+ auto* globalObject = toJS(context);
+ auto& vm = globalObject->vm();
+ JSC::JSLockHolder lock(vm);
+
+ RefPtr<JSIPC> wrapped = toWrapped(context, thisObject);
+ if (!wrapped) {
+ *exception = toRef(JSC::createTypeError(toJS(context), "Wrong type"_s));
+ return JSValueMakeUndefined(context);
+ }
+
+ auto id = callback(*wrapped);
+ JSC::JSCell* jsValue = JSC::JSBigInt::createFrom(globalObject, id);
+ return toRef(vm, jsValue);
+}
+
+JSValueRef JSIPC::messages(JSContextRef context, JSObjectRef thisObject, JSStringRef, JSValueRef* exception)
+{
+ auto* globalObject = toJS(context);
+ auto& vm = globalObject->vm();
+ JSC::JSLockHolder lock(vm);
+
+ auto* impl = toWrapped(context, thisObject);
+ if (!impl) {
+ *exception = toRef(JSC::createTypeError(toJS(context), "Wrong type"_s));
+ return JSValueMakeUndefined(context);
+ }
+
+ JSC::JSObject* messagesObject = constructEmptyObject(globalObject, globalObject->objectPrototype());
+ auto nameIdent = JSC::Identifier::fromString(vm, "name");
+ for (unsigned i = 0; i < static_cast<unsigned>(IPC::MessageName::Last); ++i) {
+ auto* messageName = description(static_cast<IPC::MessageName>(i));
+
+ JSC::JSObject* dictionary = constructEmptyObject(globalObject, globalObject->objectPrototype());
+ dictionary->putDirect(vm, nameIdent, JSC::JSValue(i));
+
+ // FIXME: Add argument names.
+
+ messagesObject->putDirect(vm, JSC::Identifier::fromString(vm, messageName), dictionary);
+ }
+
+ return toRef(vm, messagesObject);
+}
+
+void inject(WebPage& webPage, WebFrame& webFrame, WebCore::DOMWrapperWorld& world)
+{
+ auto* globalObject = webFrame.coreFrame()->script().globalObject(world);
+
+ auto& vm = globalObject->vm();
+ JSC::JSLockHolder lock(vm);
+ auto scope = DECLARE_CATCH_SCOPE(vm);
+ auto wrapped = JSIPC::create(webPage, webFrame);
+ JSObjectRef wrapperObject = JSObjectMake(toGlobalRef(globalObject), JSIPC::wrapperClass(), wrapped.ptr());
+ globalObject->putDirect(vm, JSC::Identifier::fromString(vm, "IPC"), toJS(globalObject, wrapperObject));
+
+ scope.clearException();
+}
+
+} // namespace IPCTestingAPI
+
+} // namespace WebKit
+
+#endif
Added: trunk/Source/WebKit/WebProcess/WebPage/IPCTestingAPI.h (0 => 268239)
--- trunk/Source/WebKit/WebProcess/WebPage/IPCTestingAPI.h (rev 0)
+++ trunk/Source/WebKit/WebProcess/WebPage/IPCTestingAPI.h 2020-10-09 00:48:35 UTC (rev 268239)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2020 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. AND ITS CONTRIBUTORS ``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 ITS 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
+
+#if ENABLE(IPC_TESTING_API)
+
+namespace WebCore {
+
+class DOMWrapperWorld;
+class Frame;
+
+};
+
+namespace WebKit {
+
+class WebFrame;
+class WebPage;
+
+namespace IPCTestingAPI {
+
+void inject(WebPage&, WebFrame&, WebCore::DOMWrapperWorld&);
+
+}
+
+} // namespace WebKit
+
+#endif
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebFrame.h (268238 => 268239)
--- trunk/Source/WebKit/WebProcess/WebPage/WebFrame.h 2020-10-09 00:45:29 UTC (rev 268238)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebFrame.h 2020-10-09 00:48:35 UTC (rev 268239)
@@ -63,7 +63,7 @@
struct FrameInfoData;
struct WebsitePoliciesData;
-class WebFrame : public API::ObjectImpl<API::Object::Type::BundleFrame> {
+class WebFrame : public API::ObjectImpl<API::Object::Type::BundleFrame>, public CanMakeWeakPtr<WebFrame> {
public:
static Ref<WebFrame> create() { return adoptRef(*new WebFrame); }
static Ref<WebFrame> createSubframe(WebPage*, const String& frameName, WebCore::HTMLFrameOwnerElement*);
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (268238 => 268239)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2020-10-09 00:45:29 UTC (rev 268238)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2020-10-09 00:48:35 UTC (rev 268239)
@@ -789,6 +789,10 @@
WebProcess::singleton().ensureGPUProcessConnection().updateParameters(parameters);
#endif
+#if ENABLE(IPC_TESTING_API)
+ m_visitedLinkTableID = parameters.visitedLinkTableID;
+#endif
+
#if ENABLE(VP9)
if (parameters.shouldEnableVP9Decoder)
WebProcess::singleton().enableVP9Decoder();
@@ -3784,6 +3788,10 @@
WebProcess::singleton().supplement<RemoteMediaPlayerManager>()->updatePreferences(settings);
WebProcess::singleton().setUseGPUProcessForMedia(settings.useGPUProcessForMediaEnabled());
#endif
+
+#if ENABLE(IPC_TESTING_API)
+ m_ipcTestingAPIEnabled = store.getBoolValueForKey(WebPreferencesKey::ipcTestingAPIEnabledKey());
+#endif
}
#if ENABLE(DATA_DETECTION)
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (268238 => 268239)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2020-10-09 00:45:29 UTC (rev 268238)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2020-10-09 00:48:35 UTC (rev 268239)
@@ -1339,6 +1339,12 @@
void updateCORSDisablingPatterns(Vector<String>&&);
+#if ENABLE(IPC_TESTING_API)
+ bool ipcTestingAPIEnabled() const { return m_ipcTestingAPIEnabled; }
+ uint64_t webPageProxyID() const { return messageSenderDestinationID(); }
+ uint64_t visitedLinkTableID() const { return m_visitedLinkTableID; }
+#endif
+
void getProcessDisplayName(CompletionHandler<void(String&&)>&&);
WebCore::AllowsContentJavaScript allowsContentJavaScriptFromMostRecentNavigation() const { return m_allowsContentJavaScriptFromMostRecentNavigation; }
@@ -2171,6 +2177,11 @@
bool m_canUseCredentialStorage { true };
Vector<String> m_corsDisablingPatterns;
+
+#if ENABLE(IPC_TESTING_API)
+ bool m_ipcTestingAPIEnabled { false };
+ uint64_t m_visitedLinkTableID;
+#endif
};
#if !PLATFORM(IOS_FAMILY)
Modified: trunk/Tools/ChangeLog (268238 => 268239)
--- trunk/Tools/ChangeLog 2020-10-09 00:45:29 UTC (rev 268238)
+++ trunk/Tools/ChangeLog 2020-10-09 00:48:35 UTC (rev 268239)
@@ -1,3 +1,16 @@
+2020-10-08 Ryosuke Niwa <rn...@webkit.org>
+
+ Make it possible to send an arbitrary IPC message from _javascript_
+ https://bugs.webkit.org/show_bug.cgi?id=217423
+ <rdar://problem/69969351>
+
+ Reviewed by Geoffrey Garen.
+
+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+ * TestWebKitAPI/Tests/WebKitCocoa/IPCTestingAPI.mm: Added.
+ (-[IPCTestingAPIDelegate webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:]):
+ (TEST):
+
2020-10-08 Sam Weinig <wei...@apple.com>
Refactor TestOptions code in WebKitTestRunner to make it easier to rationalize and extend
Modified: trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (268238 => 268239)
--- trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2020-10-09 00:45:29 UTC (rev 268238)
+++ trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2020-10-09 00:48:35 UTC (rev 268239)
@@ -847,6 +847,7 @@
9B4F8FA7159D52DD002D9F94 /* HTMLCollectionNamedItem.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B4F8FA6159D52CA002D9F94 /* HTMLCollectionNamedItem.html */; };
9B59F12A2034086F009E63D5 /* mso-list-compat-mode.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B59F12920340854009E63D5 /* mso-list-compat-mode.html */; };
9B62630C1F8C25C8007EE29B /* copy-url.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B62630B1F8C2510007EE29B /* copy-url.html */; };
+ 9B6D9FF9252EFDE500A51640 /* IPCTestingAPI.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9B6D9FF8252EFDE500A51640 /* IPCTestingAPI.mm */; };
9B7A37C41F8AEBA5004AA228 /* CopyURL.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9B7A37C21F8AEBA5004AA228 /* CopyURL.mm */; };
9B7D740F1F8378770006C432 /* paste-rtfd.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B7D740E1F8377E60006C432 /* paste-rtfd.html */; };
9B9332CE2320C745002D50E8 /* cocoa-writer-markup-with-lists.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 9B9332CD2320C73E002D50E8 /* cocoa-writer-markup-with-lists.html */; };
@@ -2459,6 +2460,7 @@
9B4F8FA6159D52CA002D9F94 /* HTMLCollectionNamedItem.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = HTMLCollectionNamedItem.html; sourceTree = "<group>"; };
9B59F12920340854009E63D5 /* mso-list-compat-mode.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "mso-list-compat-mode.html"; sourceTree = "<group>"; };
9B62630B1F8C2510007EE29B /* copy-url.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "copy-url.html"; sourceTree = "<group>"; };
+ 9B6D9FF8252EFDE500A51640 /* IPCTestingAPI.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = IPCTestingAPI.mm; sourceTree = "<group>"; };
9B79164F1BD89D0D00D50B8F /* FirstResponderScrollingPosition.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FirstResponderScrollingPosition.mm; sourceTree = "<group>"; };
9B7A37C21F8AEBA5004AA228 /* CopyURL.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = CopyURL.mm; sourceTree = "<group>"; };
9B7D740E1F8377E60006C432 /* paste-rtfd.html */ = {isa = PBXFileReference; lastKnownFileType = text.html; path = "paste-rtfd.html"; sourceTree = "<group>"; };
@@ -3270,6 +3272,7 @@
CED73D35246F204C00DAE327 /* InsertTextAlternatives.mm */,
2DB0232E1E4E871800707123 /* InteractionDeadlockAfterCrash.mm */,
2D116E1223E0CB3900208900 /* iOSMouseSupport.mm */,
+ 9B6D9FF8252EFDE500A51640 /* IPCTestingAPI.mm */,
5C69BDD41F82A7EB000F4F4B /* _javascript_DuringNavigation.mm */,
5C0160C021A132320077FA32 /* JITEnabled.mm */,
C25CCA051E51380B0026CB8A /* LineBreaking.mm */,
@@ -5226,6 +5229,7 @@
7A909A821D877480007E10F8 /* IntRectTests.cpp in Sources */,
7A909A831D877480007E10F8 /* IntSizeTests.cpp in Sources */,
2D116E1323E0CB3A00208900 /* iOSMouseSupport.mm in Sources */,
+ 9B6D9FF9252EFDE500A51640 /* IPCTestingAPI.mm in Sources */,
5C0BF8931DD599BD00B00328 /* IsNavigationActionTrusted.mm in Sources */,
CD5FF49F2162E943004BD86F /* ISOBox.cpp in Sources */,
5C69BDD51F82A7EF000F4F4B /* _javascript_DuringNavigation.mm in Sources */,
Added: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/IPCTestingAPI.mm (0 => 268239)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/IPCTestingAPI.mm (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/IPCTestingAPI.mm 2020-10-09 00:48:35 UTC (rev 268239)
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2020 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#import "config.h"
+
+#import "TestWKWebView.h"
+#import "Utilities.h"
+#import <WebKit/WKNavigationDelegatePrivate.h>
+#import <WebKit/WKPreferencesPrivate.h>
+#import <WebKit/WKWebView.h>
+#import <WebKit/_WKInternalDebugFeature.h>
+#import <wtf/RetainPtr.h>
+
+static bool done = false;
+static RetainPtr<NSString> alertMessage;
+
+@interface IPCTestingAPIDelegate : NSObject <WKUIDelegate>
+@end
+
+@implementation IPCTestingAPIDelegate
+
+- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler
+{
+ alertMessage = message;
+ done = true;
+ completionHandler();
+}
+
+@end
+
+TEST(IPCTestingAPI, IsDisabledByDefault)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
+
+ auto delegate = adoptNS([[IPCTestingAPIDelegate alloc] init]);
+ [webView setUIDelegate:delegate.get()];
+
+ done = false;
+ [webView synchronouslyLoadHTMLString:@"<!DOCTYPE html><script>alert(typeof(IPC));</script>"];
+ TestWebKitAPI::Util::run(&done);
+ EXPECT_STREQ([alertMessage UTF8String], "undefined");
+}
+
+#if ENABLE(IPC_TESTING_API)
+
+TEST(IPCTestingAPI, CanSendAlert)
+{
+ RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ for (_WKInternalDebugFeature *feature in [WKPreferences _internalDebugFeatures]) {
+ if ([feature.key isEqualToString:@"IPCTestingAPIEnabled"]) {
+ [[configuration preferences] _setEnabled:YES forInternalDebugFeature:feature];
+ break;
+ }
+ }
+ RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:configuration.get()]);
+
+ auto delegate = adoptNS([[IPCTestingAPIDelegate alloc] init]);
+ [webView setUIDelegate:delegate.get()];
+
+ done = false;
+ [webView synchronouslyLoadHTMLString:@"<!DOCTYPE html><script>IPC.sendSyncMessage('UI', IPC.webPageProxyID, IPC.messages.WebPageProxy_RunJavaScriptAlert.name, 100,"
+ "[{type: 'uint64_t', value: IPC.frameIdentifier}, {type: 'FrameInfoData'}, {'type': 'String', 'value': 'hi'}]);</script>"];
+ TestWebKitAPI::Util::run(&done);
+
+ EXPECT_STREQ([alertMessage UTF8String], "hi");
+}
+
+#endif