Modified: trunk/Source/WebKit/ChangeLog (261154 => 261155)
--- trunk/Source/WebKit/ChangeLog 2020-05-05 06:27:38 UTC (rev 261154)
+++ trunk/Source/WebKit/ChangeLog 2020-05-05 06:51:42 UTC (rev 261155)
@@ -1,3 +1,21 @@
+2020-05-04 Tim Horton <[email protected]>
+
+ Relax WKRemoteObjectRegistry signature validation for bool-equivalent types
+ https://bugs.webkit.org/show_bug.cgi?id=211419
+
+ Reviewed by Saam Barati.
+
+ * Shared/API/Cocoa/_WKRemoteObjectRegistry.mm:
+ (blockSignaturesAreCompatible):
+ (replyBlockSignature):
+ (-[_WKRemoteObjectRegistry _invokeMethod:]):
+ (validateReplyBlockSignature): Deleted.
+ Relax reply block signature validation slightly, considering signed char and BOOL,
+ which are equivalent and sometimes substituted for each other, to be equal.
+
+ This is still stricter than NSXPC's validation, but this is one of the
+ exceptions that they make.
+
2020-05-04 Darin Adler <[email protected]>
[Mac] Remove __MAC_OS_X_VERSION_MIN_REQUIRED checks for versions older than 10.14
Modified: trunk/Source/WebKit/Shared/API/Cocoa/_WKRemoteObjectRegistry.mm (261154 => 261155)
--- trunk/Source/WebKit/Shared/API/Cocoa/_WKRemoteObjectRegistry.mm 2020-05-05 06:27:38 UTC (rev 261154)
+++ trunk/Source/WebKit/Shared/API/Cocoa/_WKRemoteObjectRegistry.mm 2020-05-05 06:51:42 UTC (rev 261155)
@@ -187,8 +187,31 @@
return *_remoteObjectRegistry;
}
-static bool validateReplyBlockSignature(NSMethodSignature *wireBlockSignature, Protocol *protocol, SEL selector, NSUInteger blockIndex)
+static bool blockSignaturesAreCompatible(const String& wire, const String& local)
{
+ if (local == wire)
+ return true;
+
+ if (local.length() != wire.length())
+ return false;
+
+ unsigned length = local.length();
+ for (unsigned i = 0; i < length; i++) {
+ char localType = local[i];
+ char wireType = wire[i];
+
+ if (localType != wireType) {
+ // `bool` and `signed char` are interchangeable.
+ if (strchr("Bc", localType) && strchr("Bc", wireType))
+ continue;
+ return false;
+ }
+ }
+ return true;
+}
+
+static String replyBlockSignature(Protocol *protocol, SEL selector, NSUInteger blockIndex)
+{
// Required, non-inherited method:
const char* methodTypeEncoding = _protocol_getMethodTypeEncoding(protocol, selector, true, true);
// @optional, non-inherited method:
@@ -197,16 +220,14 @@
ASSERT(methodTypeEncoding);
if (!methodTypeEncoding)
- return false;
+ return { };
NSMethodSignature *targetMethodSignature = [NSMethodSignature signatureWithObjCTypes:methodTypeEncoding];
ASSERT(targetMethodSignature);
if (!targetMethodSignature)
- return false;
- NSMethodSignature *expectedBlockSignature = [targetMethodSignature _signatureForBlockAtArgumentIndex:blockIndex];
- ASSERT(expectedBlockSignature);
+ return { };
- return [wireBlockSignature isEqual:expectedBlockSignature];
+ return [targetMethodSignature _signatureForBlockAtArgumentIndex:blockIndex]._typeString.UTF8String;
}
- (void)_invokeMethod:(const WebKit::RemoteObjectInvocation&)remoteObjectInvocation
@@ -243,14 +264,21 @@
continue;
// We found the block.
- NSMethodSignature *wireBlockSignature = [NSMethodSignature signatureWithObjCTypes:replyInfo->blockSignature.utf8().data()];
+ String wireBlockSignature = [NSMethodSignature signatureWithObjCTypes:replyInfo->blockSignature.utf8().data()]._typeString.UTF8String;
+ String expectedBlockSignature = replyBlockSignature([interface protocol], invocation.selector, i);
- if (!validateReplyBlockSignature(wireBlockSignature, [interface protocol], invocation.selector, i)) {
- NSLog(@"_invokeMethod: Failed to validate reply block signature: %@", wireBlockSignature._typeString);
+ if (expectedBlockSignature.isNull()) {
+ NSLog(@"_invokeMethod: Failed to validate reply block signature: could not find local signature");
ASSERT_NOT_REACHED();
continue;
}
+ if (!blockSignaturesAreCompatible(wireBlockSignature, expectedBlockSignature)) {
+ NSLog(@"_invokeMethod: Failed to validate reply block signature: %s != %s", wireBlockSignature.utf8().data(), expectedBlockSignature.utf8().data());
+ ASSERT_NOT_REACHED();
+ continue;
+ }
+
RetainPtr<_WKRemoteObjectRegistry> remoteObjectRegistry = self;
uint64_t replyID = replyInfo->replyID;
@@ -287,7 +315,7 @@
};
RefPtr<ReplyBlockCallChecker> checker = ReplyBlockCallChecker::create(self, replyID);
- id replyBlock = __NSMakeSpecialForwardingCaptureBlock(wireBlockSignature._typeString.UTF8String, [interface, remoteObjectRegistry, replyID, checker](NSInvocation *invocation) {
+ id replyBlock = __NSMakeSpecialForwardingCaptureBlock(wireBlockSignature.utf8().data(), [interface, remoteObjectRegistry, replyID, checker](NSInvocation *invocation) {
auto encoder = adoptNS([[WKRemoteObjectEncoder alloc] init]);
[encoder encodeObject:invocation forKey:invocationKey];