Diff
Modified: trunk/Source/WebKit/ChangeLog (268945 => 268946)
--- trunk/Source/WebKit/ChangeLog 2020-10-23 23:09:03 UTC (rev 268945)
+++ trunk/Source/WebKit/ChangeLog 2020-10-24 00:02:45 UTC (rev 268946)
@@ -1,3 +1,32 @@
+2020-10-22 Ryosuke Niwa <[email protected]>
+
+ IPC testing API should expose ArrayBuffer for an unknown decoded argument
+ https://bugs.webkit.org/show_bug.cgi?id=218113
+
+ Reviewed by Darin Adler.
+
+ Expose the decoded argument as an ArrayBuffer when it can't be encoded as a JS value.
+
+ Also make the treatment of a JS array as a tuple or a Vector explicit in argument encoding.
+
+ Test: TestWebKitAPI.IPCTestingAPI.CanInterceptAlert
+
+ * Platform/IPC/Decoder.h:
+ (IPC::Decoder::currentBufferPosition const): Added.
+ * Platform/IPC/JSIPCBinding.cpp:
+ (IPC::putJSValueForDecodedArgumentAtIndexOrArrayBufferIfUndefined): Added.
+ * Platform/IPC/JSIPCBinding.h:
+ (IPC::DecodedArgumentJSValueConverter): Deleted.
+ (IPC::putJSValueForDecodeArgumentInArray): Replaced DecodedArgumentJSValueConverter.
+ Take Decoder and decode each tuple argument and create a JS value at a time.
+ (IPC::jsValueForArgumentTuple): Deleted. Merged into jsValueForDecodedArguments.
+ (IPC::jsValueForDecodedArguments):
+ * WebProcess/WebPage/IPCTestingAPI.cpp:
+ (WebKit::IPCTestingAPI::VectorEncodeHelper::encode const):
+ (WebKit::IPCTestingAPI::encodeArrayArgument): Extracted out of encodeArgument.
+ (WebKit::IPCTestingAPI::encodeArgument): Treat an array as a tuple unless it's explicitly
+ specified that the argument's type is a Vector.
+
2020-10-23 Eric Carlson <[email protected]>
[Media in GPU Process] in-band metadata cues sometimes crash
Modified: trunk/Source/WebKit/Platform/IPC/Decoder.h (268945 => 268946)
--- trunk/Source/WebKit/Platform/IPC/Decoder.h 2020-10-23 23:09:03 UTC (rev 268945)
+++ trunk/Source/WebKit/Platform/IPC/Decoder.h 2020-10-24 00:02:45 UTC (rev 268946)
@@ -73,6 +73,7 @@
static std::unique_ptr<Decoder> unwrapForTesting(Decoder&);
const uint8_t* buffer() const { return m_buffer; }
+ size_t currentBufferPosition() const { return m_bufferPos - m_buffer; }
size_t length() const { return m_bufferEnd - m_buffer; }
WARN_UNUSED_RETURN bool isValid() const { return m_bufferPos != nullptr; }
Modified: trunk/Source/WebKit/Platform/IPC/JSIPCBinding.cpp (268945 => 268946)
--- trunk/Source/WebKit/Platform/IPC/JSIPCBinding.cpp 2020-10-23 23:09:03 UTC (rev 268945)
+++ trunk/Source/WebKit/Platform/IPC/JSIPCBinding.cpp 2020-10-24 00:02:45 UTC (rev 268946)
@@ -189,6 +189,22 @@
return jsValueForDecodedArgumentRect(globalObject, value, "FloatRect");
}
+bool putJSValueForDecodedArgumentAtIndexOrArrayBufferIfUndefined(JSC::JSGlobalObject* globalObject, JSC::JSArray* array, unsigned index, JSC::JSValue value, const uint8_t* buffer, size_t length)
+{
+ auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
+
+ if (value.isUndefined()) {
+ auto arrayBuffer = JSC::ArrayBuffer::create(buffer, length);
+ if (auto* structure = globalObject->arrayBufferStructure(arrayBuffer->sharingMode()))
+ value = JSC::JSArrayBuffer::create(globalObject->vm(), structure, WTFMove(arrayBuffer));
+ }
+
+ array->putDirectIndex(globalObject, index, value);
+ RETURN_IF_EXCEPTION(scope, false);
+
+ return true;
}
+}
+
#endif
Modified: trunk/Source/WebKit/Platform/IPC/JSIPCBinding.h (268945 => 268946)
--- trunk/Source/WebKit/Platform/IPC/JSIPCBinding.h 2020-10-23 23:09:03 UTC (rev 268945)
+++ trunk/Source/WebKit/Platform/IPC/JSIPCBinding.h 2020-10-24 00:02:45 UTC (rev 268946)
@@ -30,6 +30,7 @@
#include "Decoder.h"
#include "HandleMessage.h"
#include <_javascript_Core/JSArray.h>
+#include <_javascript_Core/JSArrayBuffer.h>
#include <_javascript_Core/JSGlobalObject.h>
#include <_javascript_Core/JSObject.h>
#include <_javascript_Core/ObjectConstructor.h>
@@ -107,51 +108,45 @@
return result;
}
-template<size_t remainingSize, typename... Elements>
-struct DecodedArgumentJSValueConverter {
- static bool convert(JSC::JSGlobalObject* globalObject, JSC::JSArray* array, const std::tuple<Elements...>& tuple)
- {
- auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
+bool putJSValueForDecodedArgumentAtIndexOrArrayBufferIfUndefined(JSC::JSGlobalObject*, JSC::JSArray*, unsigned index, JSC::JSValue, const uint8_t* buffer, size_t length);
- auto jsValue = jsValueForDecodedArgumentValue(globalObject, std::get<sizeof...(Elements) - remainingSize>(tuple));
- if (jsValue.isEmpty())
- return false;
+template<typename... Elements>
+Optional<JSC::JSValue> putJSValueForDecodeArgumentInArray(JSC::JSGlobalObject*, IPC::Decoder&, JSC::JSArray*, size_t currentIndex, std::tuple<Elements...>*);
- unsigned index = sizeof...(Elements) - remainingSize;
- array->putDirectIndex(globalObject, index, jsValue);
- RETURN_IF_EXCEPTION(scope, false);
+template<>
+inline Optional<JSC::JSValue> putJSValueForDecodeArgumentInArray(JSC::JSGlobalObject* globalObject, IPC::Decoder& decoder, JSC::JSArray* array, size_t currentIndex, std::tuple<>*)
+{
+ return JSC::JSValue { array };
+}
- return DecodedArgumentJSValueConverter<remainingSize - 1, Elements...>::convert(globalObject, array, tuple);
- }
-};
+template<typename T, typename... Elements>
+Optional<JSC::JSValue> putJSValueForDecodeArgumentInArray(JSC::JSGlobalObject* globalObject, IPC::Decoder& decoder, JSC::JSArray* array, size_t currentIndex, std::tuple<T, Elements...>*)
+{
+ auto startingBufferPosition = decoder.currentBufferPosition();
+ Optional<T> value;
+ decoder >> value;
+ if (!value)
+ return WTF::nullopt;
-template<typename... Elements>
-struct DecodedArgumentJSValueConverter<0, Elements...> {
- static bool convert(JSC::JSGlobalObject*, JSC::JSArray*, const std::tuple<Elements...>&)
- {
- return true;
- }
-};
+ auto jsValue = jsValueForDecodedArgumentValue(globalObject, *value);
+ if (jsValue.isEmpty())
+ return jsValue;
-template<typename... Elements>
-static JSC::JSValue jsValueForArgumentTuple(JSC::JSGlobalObject* globalObject, const std::tuple<Elements...>& tuple)
-{
- auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
- auto* array = JSC::constructEmptyArray(globalObject, nullptr);
- RETURN_IF_EXCEPTION(scope, JSC::JSValue());
- if (!DecodedArgumentJSValueConverter<sizeof...(Elements), Elements...>::convert(globalObject, array, tuple))
- return JSC::JSValue();
- return JSC::JSValue(array);
+ putJSValueForDecodedArgumentAtIndexOrArrayBufferIfUndefined(globalObject, array, currentIndex, jsValue,
+ decoder.buffer() + startingBufferPosition, decoder.currentBufferPosition() - startingBufferPosition);
+
+ std::tuple<Elements...>* dummyArguments = nullptr;
+ return putJSValueForDecodeArgumentInArray<Elements...>(globalObject, decoder, array, currentIndex + 1, dummyArguments);
}
template<typename T>
static Optional<JSC::JSValue> jsValueForDecodedArguments(JSC::JSGlobalObject* globalObject, IPC::Decoder& decoder)
{
- Optional<typename IPC::CodingType<T>::Type> arguments;
- decoder >> arguments;
- if (!arguments)
- return WTF::nullopt;
- return jsValueForArgumentTuple(globalObject, *arguments);
+ auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
+ auto* array = JSC::constructEmptyArray(globalObject, nullptr);
+ RETURN_IF_EXCEPTION(scope, JSC::JSValue());
+ typename IPC::CodingType<T>::Type* dummyArguments = nullptr;
+ return putJSValueForDecodeArgumentInArray<>(globalObject, decoder, array, 0, dummyArguments);
}
}
Modified: trunk/Source/WebKit/WebProcess/WebPage/IPCTestingAPI.cpp (268945 => 268946)
--- trunk/Source/WebKit/WebProcess/WebPage/IPCTestingAPI.cpp 2020-10-23 23:09:03 UTC (rev 268945)
+++ trunk/Source/WebKit/WebProcess/WebPage/IPCTestingAPI.cpp 2020-10-24 00:02:45 UTC (rev 268946)
@@ -364,8 +364,7 @@
return true;
}
-enum class ArrayMode { Tuple, Vector };
-static bool encodeArgument(IPC::Encoder&, JSIPC&, JSContextRef, JSValueRef, JSValueRef* exception, ArrayMode = ArrayMode::Tuple);
+static bool encodeArgument(IPC::Encoder&, JSIPC&, JSContextRef, JSValueRef, JSValueRef* exception);
struct VectorEncodeHelper {
Ref<JSIPC> jsIPC;
@@ -378,13 +377,50 @@
{
if (!success)
return;
- success = encodeArgument(encoder, jsIPC.get(), context, valueRef, exception, ArrayMode::Vector);
+ success = encodeArgument(encoder, jsIPC.get(), context, valueRef, exception);
}
};
-static bool encodeArgument(IPC::Encoder& encoder, JSIPC& jsIPC, JSContextRef context, JSValueRef valueRef, JSValueRef* exception, ArrayMode arrayMode)
+enum class ArrayMode { Tuple, Vector };
+static bool encodeArrayArgument(IPC::Encoder& encoder, JSIPC& jsIPC, ArrayMode arrayMode, JSContextRef context, JSValueRef valueRef, JSValueRef* exception)
{
auto objectRef = JSValueToObject(context, valueRef, exception);
+ ASSERT(objectRef);
+
+ auto* globalObject = toJS(context);
+ auto& vm = globalObject->vm();
+ JSC::JSLockHolder lock(vm);
+ auto scope = DECLARE_CATCH_SCOPE(globalObject->vm());
+ auto* jsObject = toJS(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;
+}
+
+static bool encodeArgument(IPC::Encoder& encoder, JSIPC& jsIPC, JSContextRef context, JSValueRef valueRef, JSValueRef* exception)
+{
+ auto objectRef = JSValueToObject(context, valueRef, exception);
if (!objectRef)
return false;
@@ -391,6 +427,9 @@
if (auto type = JSValueGetTypedArrayType(context, objectRef, exception); type != kJSTypedArrayTypeNone)
return encodeTypedArray(encoder, context, objectRef, type, exception);
+ if (JSValueIsArray(context, objectRef))
+ return encodeArrayArgument(encoder, jsIPC, ArrayMode::Tuple, context, objectRef, exception);
+
auto* globalObject = toJS(context);
auto& vm = globalObject->vm();
JSC::JSLockHolder lock(vm);
@@ -397,32 +436,6 @@
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;
@@ -477,6 +490,14 @@
if (scope.exception())
return false;
+ if (type == "Vector") {
+ if (!jsValue.isObject() || !jsValue.inherits<JSC::JSArray>(vm)) {
+ *exception = createTypeError(context, "Vector value must be an array"_s);
+ return false;
+ }
+ return encodeArrayArgument(encoder, jsIPC, ArrayMode::Vector, context, toRef(globalObject, jsValue), exception);
+ }
+
if (type == "String") {
if (jsValue.isUndefinedOrNull()) {
encoder << String { };
Modified: trunk/Tools/ChangeLog (268945 => 268946)
--- trunk/Tools/ChangeLog 2020-10-23 23:09:03 UTC (rev 268945)
+++ trunk/Tools/ChangeLog 2020-10-24 00:02:45 UTC (rev 268946)
@@ -1,3 +1,15 @@
+2020-10-22 Ryosuke Niwa <[email protected]>
+
+ IPC testing API should expose ArrayBuffer for an unknown decoded argument
+ https://bugs.webkit.org/show_bug.cgi?id=218113
+
+ Reviewed by Darin Adler.
+
+ Updated a test case to check that the unknown type produces an ArrayBuffer.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/IPCTestingAPI.mm:
+ (IPCTestingAPI.CanInterceptAlert):
+
2020-10-22 Darin Adler <[email protected]>
REGRESSION(r266295): DOMSelection's addRange and containsNode behave incorrectly when selection crosses shadow boundaries
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/IPCTestingAPI.mm (268945 => 268946)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/IPCTestingAPI.mm 2020-10-23 23:09:03 UTC (rev 268945)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/IPCTestingAPI.mm 2020-10-24 00:02:45 UTC (rev 268946)
@@ -222,7 +222,12 @@
EXPECT_STREQ([alertMessage UTF8String], "ok");
EXPECT_STREQ([webView stringByEvaluatingJavaScript:@"messages = messages.filter((message) => message.name == IPC.messages.WebPageProxy_RunJavaScriptAlert.name); messages.length"].UTF8String, "1");
EXPECT_STREQ([webView stringByEvaluatingJavaScript:@"messages[0].description"].UTF8String, "WebPageProxy_RunJavaScriptAlert");
- EXPECT_EQ([webView stringByEvaluatingJavaScript:@"messages[0].arguments.length"].intValue, 3);
+ EXPECT_EQ([webView stringByEvaluatingJavaScript:@"args = messages[0].arguments; args.length"].intValue, 3);
+ EXPECT_STREQ([webView stringByEvaluatingJavaScript:@"args[0].type"].UTF8String, "uint64_t");
+ EXPECT_EQ([webView stringByEvaluatingJavaScript:@"args[0].value"].intValue, [webView stringByEvaluatingJavaScript:@"IPC.frameID.toString()"].intValue);
+ EXPECT_EQ([webView stringByEvaluatingJavaScript:@"args[1] instanceof ArrayBuffer"].boolValue, YES);
+ EXPECT_STREQ([webView stringByEvaluatingJavaScript:@"args[2].type"].UTF8String, "String");
+ EXPECT_STREQ([webView stringByEvaluatingJavaScript:@"args[2].value"].UTF8String, "ok");
EXPECT_STREQ([webView stringByEvaluatingJavaScript:@"typeof(messages[0].syncRequestID)"].UTF8String, "number");
EXPECT_EQ([webView stringByEvaluatingJavaScript:@"messages[0].destinationID"].intValue,
[webView stringByEvaluatingJavaScript:@"IPC.webPageProxyID.toString()"].intValue);