WebKit.GeolocationTransitionToLowAccuracy API crashes when enabling PSON
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 14 Nov 2018 06:14:58 +0000 (06:14 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 14 Nov 2018 06:14:58 +0000 (06:14 +0000)
https://bugs.webkit.org/show_bug.cgi?id=191616

Reviewed by Chris Dumez.

The crash was caused by WKView in autorelease pool invoking stopUpdatingCallback after
GeolocationTransitionToLowAccuracyStateTracker in the stack had been destroyed,
resulting in the use-after-free.

Made the tests more robust by clearing geolocation provider before exiting each test
since we can't really prevent WKView from entering an autorelease pool.

Also made WebKit.GeolocationTransitionToLowAccuracy wait for the success callback
instead of simply the end of the navigation so that the test would continue to work
even if a web content process was created for the second web view (lowAccuracyWebView)

* TestWebKitAPI/Tests/WebKit/Geolocation.cpp:
(TestWebKitAPI::setupGeolocationProvider): Moved "*" to match the WebKit coding style guideline.
(TestWebKitAPI::clearGeolocationProvider): Added.
(TestWebKitAPI::runJavaScriptAlert): Added.
(TestWebKitAPI::didFinishNavigation): Deleted.
* TestWebKitAPI/Tests/WebKit/geolocationWatchPosition.html:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238165 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebKit/Geolocation.cpp
Tools/TestWebKitAPI/Tests/WebKit/geolocationWatchPosition.html

index 5b7aba7..cc36242 100644 (file)
@@ -1,3 +1,28 @@
+2018-11-13  Ryosuke Niwa  <rniwa@webkit.org>
+
+        WebKit.GeolocationTransitionToLowAccuracy API crashes when enabling PSON
+        https://bugs.webkit.org/show_bug.cgi?id=191616
+
+        Reviewed by Chris Dumez.
+
+        The crash was caused by WKView in autorelease pool invoking stopUpdatingCallback after
+        GeolocationTransitionToLowAccuracyStateTracker in the stack had been destroyed,
+        resulting in the use-after-free.
+
+        Made the tests more robust by clearing geolocation provider before exiting each test
+        since we can't really prevent WKView from entering an autorelease pool.
+
+        Also made WebKit.GeolocationTransitionToLowAccuracy wait for the success callback
+        instead of simply the end of the navigation so that the test would continue to work
+        even if a web content process was created for the second web view (lowAccuracyWebView)
+
+        * TestWebKitAPI/Tests/WebKit/Geolocation.cpp:
+        (TestWebKitAPI::setupGeolocationProvider): Moved "*" to match the WebKit coding style guideline.
+        (TestWebKitAPI::clearGeolocationProvider): Added.
+        (TestWebKitAPI::runJavaScriptAlert): Added.
+        (TestWebKitAPI::didFinishNavigation): Deleted.
+        * TestWebKitAPI/Tests/WebKit/geolocationWatchPosition.html:
+
 2018-11-13  Chris Dumez  <cdumez@apple.com>
 
         WKProcessPool.InitialWarmedProcessUsed API is failing with PSON enabled
index 69cc910..53ad244 100644 (file)
@@ -104,7 +104,7 @@ void decidePolicyForGeolocationPermissionRequestCallBack(WKPageRef page, WKFrame
     WKGeolocationPermissionRequestAllow(permissionRequest);
 }
 
-void setupGeolocationProvider(WKContextRef context, void *clientInfo)
+void setupGeolocationProvider(WKContextRef context, voidclientInfo)
 {
     WKGeolocationProviderV1 providerCallback;
     memset(&providerCallback, 0, sizeof(WKGeolocationProviderV1));
@@ -117,6 +117,11 @@ void setupGeolocationProvider(WKContextRef context, void *clientInfo)
 
     WKGeolocationManagerSetProvider(WKContextGetGeolocationManager(context), &providerCallback.base);
 }
+    
+void clearGeolocationProvider(WKContextRef context)
+{
+    WKGeolocationManagerSetProvider(WKContextGetGeolocationManager(context), nullptr);
+}
 
 void setupView(PlatformWebView& webView)
 {
@@ -168,6 +173,7 @@ TEST(WebKit, GeolocationBasic)
     WKPageLoadURL(webView.page(), url.get());
 
     Util::run(&stateTracker.finished);
+    clearGeolocationProvider(context.get());
 }
 
 // Geolocation requested with High Accuracy.
@@ -209,6 +215,7 @@ TEST(WebKit, GeolocationBasicWithHighAccuracy)
     WKPageLoadURL(webView.page(), url.get());
 
     Util::run(&stateTracker.finished);
+    clearGeolocationProvider(context.get());
 }
 
 // Geolocation start without High Accuracy, then requires High Accuracy.
@@ -272,6 +279,8 @@ TEST(WebKit, GeolocationTransitionToHighAccuracy)
     Util::run(&stateTracker.enabledHighAccuracy);
     WKPageLoadURL(lowAccuracyWebView.page(), resetUrl.get());
     Util::run(&stateTracker.finished);
+
+    clearGeolocationProvider(context.get());
 }
 
 // Geolocation start with High Accuracy, then should fall back to low accuracy.
@@ -307,7 +316,7 @@ struct GeolocationTransitionToLowAccuracyStateTracker : GeolocationStateTracker
     }
 };
 
-static void didFinishNavigation(WKPageRef page, WKNavigationRef, WKTypeRef userData, const void* clientInfo)
+static void runJavaScriptAlert(WKPageRef page, WKStringRef alertText, WKFrameRef frame, const void* clientInfo)
 {
     *static_cast<bool*>(const_cast<void*>(clientInfo)) = true;
 }
@@ -315,7 +324,6 @@ static void didFinishNavigation(WKPageRef page, WKNavigationRef, WKTypeRef userD
 TEST(WebKit, GeolocationTransitionToLowAccuracy)
 {
     WKRetainPtr<WKContextRef> context(AdoptWK, WKContextCreate());
-    WKContextSetMaximumNumberOfProcesses(context.get(), 1);
 
     GeolocationTransitionToLowAccuracyStateTracker stateTracker;
     setupGeolocationProvider(context.get(), &stateTracker);
@@ -331,14 +339,13 @@ TEST(WebKit, GeolocationTransitionToLowAccuracy)
 
     bool finishedSecondStep = false;
 
-    WKPageNavigationClientV0 loaderClient;
-    memset(&loaderClient, 0, sizeof(loaderClient));
-
-    loaderClient.base.version = 0;
-    loaderClient.base.clientInfo = &finishedSecondStep;
-    loaderClient.didFinishNavigation = didFinishNavigation;
-
-    WKPageSetPageNavigationClient(lowAccuracyWebView.page(), &loaderClient.base);
+    WKPageUIClientV2 uiClient;
+    memset(&uiClient, 0, sizeof(uiClient));
+    uiClient.base.version = 2;
+    uiClient.base.clientInfo = &finishedSecondStep;
+    uiClient.decidePolicyForGeolocationPermissionRequest = decidePolicyForGeolocationPermissionRequestCallBack;
+    uiClient.runJavaScriptAlert = runJavaScriptAlert;
+    WKPageSetPageUIClient(lowAccuracyWebView.page(), &uiClient.base);
 
     WKRetainPtr<WKURLRef> lowAccuracyURL(AdoptWK, Util::createURLForResource("geolocationWatchPosition", "html"));
     WKPageLoadURL(lowAccuracyWebView.page(), lowAccuracyURL.get());
@@ -346,9 +353,13 @@ TEST(WebKit, GeolocationTransitionToLowAccuracy)
 
     WKRetainPtr<WKURLRef> resetUrl = adoptWK(WKURLCreateWithUTF8CString("about:blank"));
     WKPageLoadURL(highAccuracyWebView.page(), resetUrl.get());
+
     Util::run(&stateTracker.disabledHighAccuracy);
+
     WKPageLoadURL(lowAccuracyWebView.page(), resetUrl.get());
     Util::run(&stateTracker.finished);
+
+    clearGeolocationProvider(context.get());
 }
 
 } // namespace TestWebKitAPI
index 24788b7..fdc2b50 100644 (file)
@@ -1,3 +1,3 @@
 <script>
-navigator.geolocation.watchPosition(function() { });
+navigator.geolocation.watchPosition(function() { setTimeout(() => alert("SUCCESS"), 0); }, function() { setTimeout(() => alert("FAIL"), 0); }, {timeout: 100});
 </script>