Title: [234599] trunk/Tools
- Revision
- 234599
- Author
- wenson_hs...@apple.com
- Date
- 2018-08-06 06:59:04 -0700 (Mon, 06 Aug 2018)
Log Message
[iOS] Layout tests that send HID events cause WebKitTestRunner to crash on recent SDKs
https://bugs.webkit.org/show_bug.cgi?id=188334
<rdar://problem/40630074>
Reviewed by Tim Horton.
To mark the end of previously dispatched IOHID events, HIDEventGenerator currently sends a vendor-defined event
and stores the completion callback ID for the previously dispatched events as vendor-defined data. When this
vendor-defined marker event is handled by the application, we then read the callback ID back from the event, map
it to a completion block, and invoke the completion block to signal that the previous HID event has been
processed.
This callback ID is an unsigned, so we tell IOKit that we need `sizeof(unsigned)` (4 bytes) to store it. On
shipping software, IOKit clamps this to a minimum of 8 bytes, i.e. `sizeof(CFIndex)`. When we later call
IOHIDEventGetIntegerValue to read the value of our vendor-defined data as a CFIndex, we get our expected
callback ID because the buffer was clamped to 8 bytes.
However, on recent iOS SDKs that contain the fix for <rdar://problem/20082284>, IOKit no longer clamps the size
of the vendor-defined data buffer to 8 bytes. This means that when we try to use IOHIDEventGetIntegerValue to
read our callback ID back, we end up getting a CFIndex where the lower 4 bytes are the callback ID we wrote, and
the upper 4 bytes are garbage. In the case where any of these upper 4 bytes are non-zero, we fail to map the
callback ID to a completion handler, and so we never finish dispatching the HID event, causing an exception to
be thrown.
To fix this, we adjust callback ID to be a CFIndex, which matches IOHIDEventGetIntegerValue's return type.
* WebKitTestRunner/ios/HIDEventGenerator.mm:
(+[HIDEventGenerator nextEventCallbackID]):
(-[HIDEventGenerator _sendMarkerHIDEventWithCompletionBlock:]):
Also refactor a bit of `-_sendMarkerHIDEventWithCompletionBlock:` by using auto and move semantics.
Modified Paths
Diff
Modified: trunk/Tools/ChangeLog (234598 => 234599)
--- trunk/Tools/ChangeLog 2018-08-06 12:59:41 UTC (rev 234598)
+++ trunk/Tools/ChangeLog 2018-08-06 13:59:04 UTC (rev 234599)
@@ -1,3 +1,37 @@
+2018-08-06 Wenson Hsieh <wenson_hs...@apple.com>
+
+ [iOS] Layout tests that send HID events cause WebKitTestRunner to crash on recent SDKs
+ https://bugs.webkit.org/show_bug.cgi?id=188334
+ <rdar://problem/40630074>
+
+ Reviewed by Tim Horton.
+
+ To mark the end of previously dispatched IOHID events, HIDEventGenerator currently sends a vendor-defined event
+ and stores the completion callback ID for the previously dispatched events as vendor-defined data. When this
+ vendor-defined marker event is handled by the application, we then read the callback ID back from the event, map
+ it to a completion block, and invoke the completion block to signal that the previous HID event has been
+ processed.
+
+ This callback ID is an unsigned, so we tell IOKit that we need `sizeof(unsigned)` (4 bytes) to store it. On
+ shipping software, IOKit clamps this to a minimum of 8 bytes, i.e. `sizeof(CFIndex)`. When we later call
+ IOHIDEventGetIntegerValue to read the value of our vendor-defined data as a CFIndex, we get our expected
+ callback ID because the buffer was clamped to 8 bytes.
+
+ However, on recent iOS SDKs that contain the fix for <rdar://problem/20082284>, IOKit no longer clamps the size
+ of the vendor-defined data buffer to 8 bytes. This means that when we try to use IOHIDEventGetIntegerValue to
+ read our callback ID back, we end up getting a CFIndex where the lower 4 bytes are the callback ID we wrote, and
+ the upper 4 bytes are garbage. In the case where any of these upper 4 bytes are non-zero, we fail to map the
+ callback ID to a completion handler, and so we never finish dispatching the HID event, causing an exception to
+ be thrown.
+
+ To fix this, we adjust callback ID to be a CFIndex, which matches IOHIDEventGetIntegerValue's return type.
+
+ * WebKitTestRunner/ios/HIDEventGenerator.mm:
+ (+[HIDEventGenerator nextEventCallbackID]):
+ (-[HIDEventGenerator _sendMarkerHIDEventWithCompletionBlock:]):
+
+ Also refactor a bit of `-_sendMarkerHIDEventWithCompletionBlock:` by using auto and move semantics.
+
2018-08-03 Ben Richards <benton_richa...@apple.com>
We should cache the compiled sandbox profile in a data vault
Modified: trunk/Tools/WebKitTestRunner/ios/HIDEventGenerator.mm (234598 => 234599)
--- trunk/Tools/WebKitTestRunner/ios/HIDEventGenerator.mm 2018-08-06 12:59:41 UTC (rev 234598)
+++ trunk/Tools/WebKitTestRunner/ios/HIDEventGenerator.mm 2018-08-06 13:59:04 UTC (rev 234599)
@@ -171,9 +171,9 @@
return eventGenerator;
}
-+ (unsigned)nextEventCallbackID
++ (CFIndex)nextEventCallbackID
{
- static unsigned callbackID = 0;
+ static CFIndex callbackID = 0;
return ++callbackID;
}
@@ -479,24 +479,21 @@
- (BOOL)_sendMarkerHIDEventWithCompletionBlock:(void (^)(void))completionBlock
{
- unsigned callbackID = [HIDEventGenerator nextEventCallbackID];
- void (^completionBlockCopy)() = Block_copy(completionBlock);
- [_eventCallbacks setObject:completionBlockCopy forKey:@(callbackID)];
+ auto callbackID = [HIDEventGenerator nextEventCallbackID];
+ [_eventCallbacks setObject:Block_copy(completionBlock) forKey:@(callbackID)];
- uint64_t machTime = mach_absolute_time();
- RetainPtr<IOHIDEventRef> markerEvent = adoptCF(IOHIDEventCreateVendorDefinedEvent(kCFAllocatorDefault,
- machTime,
+ auto markerEvent = adoptCF(IOHIDEventCreateVendorDefinedEvent(kCFAllocatorDefault,
+ mach_absolute_time(),
kHIDPage_VendorDefinedStart + 100,
0,
1,
(uint8_t*)&callbackID,
- sizeof(unsigned),
+ sizeof(CFIndex),
kIOHIDEventOptionNone));
if (markerEvent) {
- markerEvent.get();
- dispatch_async(dispatch_get_main_queue(), ^{
- uint32_t contextID = [UIApplication sharedApplication].keyWindow._contextId;
+ dispatch_async(dispatch_get_main_queue(), [markerEvent = WTFMove(markerEvent)] {
+ auto contextID = [UIApplication sharedApplication].keyWindow._contextId;
ASSERT(contextID);
BKSHIDEventSetDigitizerInfo(markerEvent.get(), contextID, false, false, NULL, 0, 0);
[[UIApplication sharedApplication] _enqueueHIDEvent:markerEvent.get()];
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes