Title: [282365] trunk
- Revision
- 282365
- Author
- cdu...@apple.com
- Date
- 2021-09-13 15:06:45 -0700 (Mon, 13 Sep 2021)
Log Message
Crash under WebPage::runJavaScript()
https://bugs.webkit.org/show_bug.cgi?id=230223
<rdar://80172436>
Reviewed by Brady Eidson.
Source/WebKit:
The resolveFunction() was capturing `frame = makeRef(frame)` and then calling `frame->coreFrame()->script()`.
This would lead to a null dereference crash in the case where the core frame gets destroyed before the JS
promise gets resolved. Protecting the WebFrame does not keep the core Frame alive as WebFrame::m_coreFrame
is merely a WeakPtr. To address the issue, the lambda now also protects the core frame and uses it to get
the script controller.
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::runJavaScript):
Tools:
Add API test coverage.
* TestWebKitAPI/Tests/WebKitCocoa/AsyncFunction.mm:
(-[AsyncJSUIDelegate initWithAlertHandler:]):
(-[AsyncJSUIDelegate webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:]):
(TestWebKitAPI::TEST):
Modified Paths
Diff
Modified: trunk/Source/WebKit/ChangeLog (282364 => 282365)
--- trunk/Source/WebKit/ChangeLog 2021-09-13 22:01:40 UTC (rev 282364)
+++ trunk/Source/WebKit/ChangeLog 2021-09-13 22:06:45 UTC (rev 282365)
@@ -1,3 +1,20 @@
+2021-09-13 Chris Dumez <cdu...@apple.com>
+
+ Crash under WebPage::runJavaScript()
+ https://bugs.webkit.org/show_bug.cgi?id=230223
+ <rdar://80172436>
+
+ Reviewed by Brady Eidson.
+
+ The resolveFunction() was capturing `frame = makeRef(frame)` and then calling `frame->coreFrame()->script()`.
+ This would lead to a null dereference crash in the case where the core frame gets destroyed before the JS
+ promise gets resolved. Protecting the WebFrame does not keep the core Frame alive as WebFrame::m_coreFrame
+ is merely a WeakPtr. To address the issue, the lambda now also protects the core frame and uses it to get
+ the script controller.
+
+ * WebProcess/WebPage/WebPage.cpp:
+ (WebKit::WebPage::runJavaScript):
+
2021-09-13 Per Arne Vollan <pvol...@apple.com>
Send preference updates to the GPU process
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (282364 => 282365)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2021-09-13 22:01:40 UTC (rev 282364)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2021-09-13 22:06:45 UTC (rev 282365)
@@ -3722,11 +3722,11 @@
}
#endif
- auto resolveFunction = [world = makeRef(*world), frame = makeRef(*frame), completionHandler = WTFMove(completionHandler)] (ValueOrException result) mutable {
+ auto resolveFunction = [world = makeRef(*world), frame = Ref { *frame }, coreFrame = Ref { *frame->coreFrame() }, completionHandler = WTFMove(completionHandler)] (ValueOrException result) mutable {
RefPtr<SerializedScriptValue> serializedResultValue;
if (result) {
serializedResultValue = SerializedScriptValue::create(frame->jsContextForWorld(world.ptr()),
- toRef(frame->coreFrame()->script().globalObject(world->coreWorld()), result.value()), nullptr);
+ toRef(coreFrame->script().globalObject(world->coreWorld()), result.value()), nullptr);
}
IPC::DataReference dataReference;
Modified: trunk/Tools/ChangeLog (282364 => 282365)
--- trunk/Tools/ChangeLog 2021-09-13 22:01:40 UTC (rev 282364)
+++ trunk/Tools/ChangeLog 2021-09-13 22:06:45 UTC (rev 282365)
@@ -1,3 +1,18 @@
+2021-09-13 Chris Dumez <cdu...@apple.com>
+
+ Crash under WebPage::runJavaScript()
+ https://bugs.webkit.org/show_bug.cgi?id=230223
+ <rdar://80172436>
+
+ Reviewed by Brady Eidson.
+
+ Add API test coverage.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/AsyncFunction.mm:
+ (-[AsyncJSUIDelegate initWithAlertHandler:]):
+ (-[AsyncJSUIDelegate webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:]):
+ (TestWebKitAPI::TEST):
+
2021-09-13 Tyler Wilcock <tyle...@apple.com>
AX: Make PDFs loaded via <embed> accessible
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/AsyncFunction.mm (282364 => 282365)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/AsyncFunction.mm 2021-09-13 22:01:40 UTC (rev 282364)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/AsyncFunction.mm 2021-09-13 22:06:45 UTC (rev 282365)
@@ -27,8 +27,10 @@
#import "PlatformUtilities.h"
#import "Test.h"
+#import "TestUIDelegate.h"
#import "TestWKWebView.h"
#import <WebKit/WKContentWorld.h>
+#import <WebKit/WKFrameInfo.h>
#import <WebKit/WKProcessPoolPrivate.h>
#import <WebKit/WKWebViewPrivate.h>
@@ -280,5 +282,43 @@
TestWebKitAPI::Util::run(&done);
}
+TEST(AsyncFunction, PromiseDetachedFrame)
+{
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+ auto uiDelegate = adoptNS([[TestUIDelegate alloc] init]);
+ [webView setUIDelegate:uiDelegate.get()];
+
+ __block RetainPtr<WKFrameInfo> subframe;
+ __block bool doneGettingSubframe = false;
+ uiDelegate.get().runJavaScriptAlertPanelWithMessage = ^(WKWebView *, NSString *, WKFrameInfo * frame, void (^completionHandler)(void)) {
+ subframe = frame;
+ doneGettingSubframe = true;
+ completionHandler();
+ };
+
+ [webView synchronouslyLoadHTMLString:@"<iframe src=''></iframe>"];
+
+ TestWebKitAPI::Util::run(&doneGettingSubframe);
+
+ ASSERT_TRUE(!!subframe);
+ EXPECT_FALSE([subframe isMainFrame]);
+
+ auto pid = [webView _webProcessIdentifier];
+ EXPECT_NE(pid, 0);
+
+ NSString *functionBody = @"return new Promise(function(resolve, reject) { setTimeout(function(){ top.setTimeout(function() { resolve(42); }, 100); top.document.querySelector('iframe').remove(); }, 0); })";
+
+ bool done = false;
+ [webView callAsyncJavaScript:functionBody arguments:nil inFrame:subframe.get() inContentWorld:WKContentWorld.pageWorld completionHandler:[&] (id result, NSError *error) {
+ EXPECT_NULL(error);
+ EXPECT_TRUE([result isKindOfClass:[NSNumber class]]);
+ EXPECT_TRUE([result isEqualToNumber:@42]);
+ done = true;
+ }];
+ TestWebKitAPI::Util::run(&done);
+
+ EXPECT_EQ([webView _webProcessIdentifier], pid);
}
+}
+
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes