<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[194721] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/194721">194721</a></dd>
<dt>Author</dt> <dd>ap@apple.com</dd>
<dt>Date</dt> <dd>2016-01-07 14:09:33 -0800 (Thu, 07 Jan 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>testRunner.runUIScript crashes while running multiple tests in a row that invokes the same UIScript
https://bugs.webkit.org/show_bug.cgi?id=152390
&lt;rdar://problem/23948321&gt;

Reviewed by Simon Fraser.

Tools:

Fix two use-after-frees.

1. WKPageCallAfterNextPresentationUpdate's callback has a pointer to TestInvocation,
but we may have already progressed to another test by the time the callback fires,
having destroyed the TestInvocation.
2. UIScriptController is a RefCounted object, but it has a raw pointer to
UIScriptContext which has the same lifetime as a TestInvocation.
As a result, completion blocks of UIScriptController actions would use a destroyed
TestInvocation.

* WebKitTestRunner/TestInvocation.cpp:
(WTR::TestInvocation::~TestInvocation):
(WTR::TestInvocation::url):
(WTR::TestInvocation::didReceiveMessageFromInjectedBundle):
(WTR::TestInvocation::runUISideScriptAfterUpdateCallback):
(WTR::TestInvocation::runUISideScript):
* WebKitTestRunner/TestInvocation.h:
* WebKitTestRunner/UIScriptContext/UIScriptContext.cpp:
(UIScriptContext::UIScriptContext):
(UIScriptContext::~UIScriptContext):
(UIScriptContext::runUIScript):
* WebKitTestRunner/UIScriptContext/UIScriptContext.h:
* WebKitTestRunner/UIScriptContext/UIScriptController.cpp:
(WTR::UIScriptController::UIScriptController):
(WTR::UIScriptController::contextDestroyed):
(WTR::UIScriptController::makeWindowObject):
(WTR::UIScriptController::setWillBeginZoomingCallback):
(WTR::UIScriptController::willBeginZoomingCallback):
(WTR::UIScriptController::setDidEndZoomingCallback):
(WTR::UIScriptController::didEndZoomingCallback):
(WTR::UIScriptController::setDidEndScrollingCallback):
(WTR::UIScriptController::didEndScrollingCallback):
(WTR::UIScriptController::setDidShowKeyboardCallback):
(WTR::UIScriptController::didShowKeyboardCallback):
(WTR::UIScriptController::setDidHideKeyboardCallback):
(WTR::UIScriptController::didHideKeyboardCallback):
(WTR::UIScriptController::uiScriptComplete):
* WebKitTestRunner/UIScriptContext/UIScriptController.h:
(WTR::UIScriptController::create):
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptController::doAsyncTask):
(WTR::UIScriptController::zoomToScale):
(WTR::UIScriptController::singleTapAtPoint):
(WTR::UIScriptController::doubleTapAtPoint):
(WTR::UIScriptController::typeCharacterUsingHardwareKeyboard):
(WTR::UIScriptController::contentVisibleRect):
(WTR::UIScriptController::platformSetWillBeginZoomingCallback):
(WTR::UIScriptController::platformSetDidEndZoomingCallback):
(WTR::UIScriptController::platformSetDidShowKeyboardCallback):
(WTR::UIScriptController::platformSetDidHideKeyboardCallback):
(WTR::UIScriptController::platformSetDidEndScrollingCallback):
* WebKitTestRunner/mac/UIScriptControllerMac.mm:
(WTR::UIScriptController::doAsyncTask):

LayoutTests:

* platform/ios-simulator/TestExpectations: Unskipped tests that used to be affected.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsplatformiossimulatorTestExpectations">trunk/LayoutTests/platform/ios-simulator/TestExpectations</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsWebKitTestRunnerTestInvocationcpp">trunk/Tools/WebKitTestRunner/TestInvocation.cpp</a></li>
<li><a href="#trunkToolsWebKitTestRunnerTestInvocationh">trunk/Tools/WebKitTestRunner/TestInvocation.h</a></li>
<li><a href="#trunkToolsWebKitTestRunnerUIScriptContextUIScriptContextcpp">trunk/Tools/WebKitTestRunner/UIScriptContext/UIScriptContext.cpp</a></li>
<li><a href="#trunkToolsWebKitTestRunnerUIScriptContextUIScriptContexth">trunk/Tools/WebKitTestRunner/UIScriptContext/UIScriptContext.h</a></li>
<li><a href="#trunkToolsWebKitTestRunnerUIScriptContextUIScriptControllercpp">trunk/Tools/WebKitTestRunner/UIScriptContext/UIScriptController.cpp</a></li>
<li><a href="#trunkToolsWebKitTestRunnerUIScriptContextUIScriptControllerh">trunk/Tools/WebKitTestRunner/UIScriptContext/UIScriptController.h</a></li>
<li><a href="#trunkToolsWebKitTestRunneriosUIScriptControllerIOSmm">trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm</a></li>
<li><a href="#trunkToolsWebKitTestRunnermacUIScriptControllerMacmm">trunk/Tools/WebKitTestRunner/mac/UIScriptControllerMac.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (194720 => 194721)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-01-07 22:02:54 UTC (rev 194720)
+++ trunk/LayoutTests/ChangeLog        2016-01-07 22:09:33 UTC (rev 194721)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2016-01-07  Alexey Proskuryakov  &lt;ap@apple.com&gt;
+
+        testRunner.runUIScript crashes while running multiple tests in a row that invokes the same UIScript
+        https://bugs.webkit.org/show_bug.cgi?id=152390
+        &lt;rdar://problem/23948321&gt;
+
+        Reviewed by Simon Fraser.
+
+        * platform/ios-simulator/TestExpectations: Unskipped tests that used to be affected.
+
</ins><span class="cx"> 2016-01-07  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Incorrect position: fixed; rendering when child of position:relative/sticky.
</span></span></pre></div>
<a id="trunkLayoutTestsplatformiossimulatorTestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/ios-simulator/TestExpectations (194720 => 194721)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/ios-simulator/TestExpectations        2016-01-07 22:02:54 UTC (rev 194720)
+++ trunk/LayoutTests/platform/ios-simulator/TestExpectations        2016-01-07 22:09:33 UTC (rev 194721)
</span><span class="lines">@@ -2837,15 +2837,6 @@
</span><span class="cx"> webkit.org/b/152279 http/tests/misc/large-js-program.php [ Pass Crash ]
</span><span class="cx"> webkit.org/b/152279 js/dom/line-column-numbers.html [ Pass Crash ]
</span><span class="cx"> 
</span><del>-webkit.org/b/152390 http/tests/contentdispositionattachmentsandbox/referer-header-stripped-with-meta-referer-always.html [ Skip ]
-webkit.org/b/152390 http/tests/contentdispositionattachmentsandbox/referer-header-stripped-with-meta-referer-default.html [ Skip ]
-webkit.org/b/152390 http/tests/contentdispositionattachmentsandbox/referer-header-stripped-with-meta-referer-never.html [ Skip ]
-webkit.org/b/152390 http/tests/contentdispositionattachmentsandbox/referer-header-stripped-with-meta-referer-no-referrer-when-downgrade.html [ Skip ]
-webkit.org/b/152390 http/tests/contentdispositionattachmentsandbox/referer-header-stripped-with-meta-referer-no-referrer.html [ Skip ]
-webkit.org/b/152390 http/tests/contentdispositionattachmentsandbox/referer-header-stripped-with-meta-referer-origin.html [ Skip ]
-webkit.org/b/152390 http/tests/contentdispositionattachmentsandbox/referer-header-stripped-with-meta-referer-unsafe-url.html [ Skip ]
-webkit.org/b/152390 http/tests/contentdispositionattachmentsandbox/referer-header-stripped.html [ Skip ]
-
</del><span class="cx"> webkit.org/b/152137 fast/media/mq-any-hover-matchMedia.html [ Failure ]
</span><span class="cx"> webkit.org/b/152137 fast/media/mq-any-hover-styling.html [ Failure ]
</span><span class="cx"> webkit.org/b/152137 fast/media/mq-any-pointer-matchMedia.html [ Failure ]
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (194720 => 194721)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2016-01-07 22:02:54 UTC (rev 194720)
+++ trunk/Tools/ChangeLog        2016-01-07 22:09:33 UTC (rev 194721)
</span><span class="lines">@@ -1,3 +1,65 @@
</span><ins>+2016-01-07  Alexey Proskuryakov  &lt;ap@apple.com&gt;
+
+        testRunner.runUIScript crashes while running multiple tests in a row that invokes the same UIScript
+        https://bugs.webkit.org/show_bug.cgi?id=152390
+        &lt;rdar://problem/23948321&gt;
+
+        Reviewed by Simon Fraser.
+
+        Fix two use-after-frees.
+
+        1. WKPageCallAfterNextPresentationUpdate's callback has a pointer to TestInvocation,
+        but we may have already progressed to another test by the time the callback fires,
+        having destroyed the TestInvocation.
+        2. UIScriptController is a RefCounted object, but it has a raw pointer to
+        UIScriptContext which has the same lifetime as a TestInvocation.
+        As a result, completion blocks of UIScriptController actions would use a destroyed
+        TestInvocation.
+
+        * WebKitTestRunner/TestInvocation.cpp:
+        (WTR::TestInvocation::~TestInvocation):
+        (WTR::TestInvocation::url):
+        (WTR::TestInvocation::didReceiveMessageFromInjectedBundle):
+        (WTR::TestInvocation::runUISideScriptAfterUpdateCallback):
+        (WTR::TestInvocation::runUISideScript):
+        * WebKitTestRunner/TestInvocation.h:
+        * WebKitTestRunner/UIScriptContext/UIScriptContext.cpp:
+        (UIScriptContext::UIScriptContext):
+        (UIScriptContext::~UIScriptContext):
+        (UIScriptContext::runUIScript):
+        * WebKitTestRunner/UIScriptContext/UIScriptContext.h:
+        * WebKitTestRunner/UIScriptContext/UIScriptController.cpp:
+        (WTR::UIScriptController::UIScriptController):
+        (WTR::UIScriptController::contextDestroyed):
+        (WTR::UIScriptController::makeWindowObject):
+        (WTR::UIScriptController::setWillBeginZoomingCallback):
+        (WTR::UIScriptController::willBeginZoomingCallback):
+        (WTR::UIScriptController::setDidEndZoomingCallback):
+        (WTR::UIScriptController::didEndZoomingCallback):
+        (WTR::UIScriptController::setDidEndScrollingCallback):
+        (WTR::UIScriptController::didEndScrollingCallback):
+        (WTR::UIScriptController::setDidShowKeyboardCallback):
+        (WTR::UIScriptController::didShowKeyboardCallback):
+        (WTR::UIScriptController::setDidHideKeyboardCallback):
+        (WTR::UIScriptController::didHideKeyboardCallback):
+        (WTR::UIScriptController::uiScriptComplete):
+        * WebKitTestRunner/UIScriptContext/UIScriptController.h:
+        (WTR::UIScriptController::create):
+        * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
+        (WTR::UIScriptController::doAsyncTask):
+        (WTR::UIScriptController::zoomToScale):
+        (WTR::UIScriptController::singleTapAtPoint):
+        (WTR::UIScriptController::doubleTapAtPoint):
+        (WTR::UIScriptController::typeCharacterUsingHardwareKeyboard):
+        (WTR::UIScriptController::contentVisibleRect):
+        (WTR::UIScriptController::platformSetWillBeginZoomingCallback):
+        (WTR::UIScriptController::platformSetDidEndZoomingCallback):
+        (WTR::UIScriptController::platformSetDidShowKeyboardCallback):
+        (WTR::UIScriptController::platformSetDidHideKeyboardCallback):
+        (WTR::UIScriptController::platformSetDidEndScrollingCallback):
+        * WebKitTestRunner/mac/UIScriptControllerMac.mm:
+        (WTR::UIScriptController::doAsyncTask):
+
</ins><span class="cx"> 2016-01-07  Youenn Fablet  &lt;youenn.fablet@crf.canon.fr&gt;
</span><span class="cx"> 
</span><span class="cx">         [buildbot] clean-build script should remove untracked files and revert local changes too
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerTestInvocationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/TestInvocation.cpp (194720 => 194721)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/TestInvocation.cpp        2016-01-07 22:02:54 UTC (rev 194720)
+++ trunk/Tools/WebKitTestRunner/TestInvocation.cpp        2016-01-07 22:09:33 UTC (rev 194721)
</span><span class="lines">@@ -75,6 +75,8 @@
</span><span class="cx"> 
</span><span class="cx"> TestInvocation::~TestInvocation()
</span><span class="cx"> {
</span><ins>+    if (m_pendingUIScriptInvocationData)
+        m_pendingUIScriptInvocationData-&gt;testInvocation = nullptr;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> WKURLRef TestInvocation::url() const
</span><span class="lines">@@ -643,6 +645,7 @@
</span><span class="cx">         invocationData-&gt;testInvocation = this;
</span><span class="cx">         invocationData-&gt;callbackID = (unsigned)WKUInt64GetValue(static_cast&lt;WKUInt64Ref&gt;(WKDictionaryGetItemForKey(messageBodyDictionary, callbackIDKey.get())));
</span><span class="cx">         invocationData-&gt;scriptString = static_cast&lt;WKStringRef&gt;(WKDictionaryGetItemForKey(messageBodyDictionary, scriptKey.get()));
</span><ins>+        m_pendingUIScriptInvocationData = invocationData;
</ins><span class="cx">         WKPageCallAfterNextPresentationUpdate(TestController::singleton().mainWebView()-&gt;page(), invocationData, runUISideScriptAfterUpdateCallback);
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="lines">@@ -695,12 +698,17 @@
</span><span class="cx"> void TestInvocation::runUISideScriptAfterUpdateCallback(WKErrorRef, void* context)
</span><span class="cx"> {
</span><span class="cx">     UIScriptInvocationData* data = static_cast&lt;UIScriptInvocationData*&gt;(context);
</span><del>-    data-&gt;testInvocation-&gt;runUISideScript(data-&gt;scriptString.get(), data-&gt;callbackID);
</del><ins>+    if (TestInvocation* invocation = data-&gt;testInvocation) {
+        RELEASE_ASSERT(TestController::singleton().isCurrentInvocation(invocation));
+        invocation-&gt;runUISideScript(data-&gt;scriptString.get(), data-&gt;callbackID);
+    }
</ins><span class="cx">     delete data;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void TestInvocation::runUISideScript(WKStringRef script, unsigned scriptCallbackID)
</span><span class="cx"> {
</span><ins>+    m_pendingUIScriptInvocationData = nullptr;
+
</ins><span class="cx">     if (!m_UIScriptContext)
</span><span class="cx">         m_UIScriptContext = std::make_unique&lt;UIScriptContext&gt;(*this);
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerTestInvocationh"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/TestInvocation.h (194720 => 194721)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/TestInvocation.h        2016-01-07 22:02:54 UTC (rev 194720)
+++ trunk/Tools/WebKitTestRunner/TestInvocation.h        2016-01-07 22:09:33 UTC (rev 194721)
</span><span class="lines">@@ -115,7 +115,7 @@
</span><span class="cx">     std::string m_errorMessage;
</span><span class="cx">     
</span><span class="cx">     std::unique_ptr&lt;UIScriptContext&gt; m_UIScriptContext;
</span><del>-
</del><ins>+    UIScriptInvocationData* m_pendingUIScriptInvocationData { nullptr };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WTR
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerUIScriptContextUIScriptContextcpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/UIScriptContext/UIScriptContext.cpp (194720 => 194721)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/UIScriptContext/UIScriptContext.cpp        2016-01-07 22:02:54 UTC (rev 194720)
+++ trunk/Tools/WebKitTestRunner/UIScriptContext/UIScriptContext.cpp        2016-01-07 22:09:33 UTC (rev 194721)
</span><span class="lines">@@ -53,6 +53,11 @@
</span><span class="cx">     m_controller-&gt;makeWindowObject(m_context.get(), globalObject, &amp;exception);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+UIScriptContext::~UIScriptContext()
+{
+    m_controller-&gt;contextDestroyed();
+}
+
</ins><span class="cx"> void UIScriptContext::runUIScript(WKStringRef script, unsigned scriptCallbackID)
</span><span class="cx"> {
</span><span class="cx">     m_currentScriptCallbackID = scriptCallbackID;
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerUIScriptContextUIScriptContexth"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/UIScriptContext/UIScriptContext.h (194720 => 194721)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/UIScriptContext/UIScriptContext.h        2016-01-07 22:02:54 UTC (rev 194720)
+++ trunk/Tools/WebKitTestRunner/UIScriptContext/UIScriptContext.h        2016-01-07 22:09:33 UTC (rev 194721)
</span><span class="lines">@@ -51,9 +51,10 @@
</span><span class="cx"> } CallbackType;
</span><span class="cx"> 
</span><span class="cx"> class UIScriptContext {
</span><ins>+    WTF_MAKE_NONCOPYABLE(UIScriptContext);
</ins><span class="cx"> public:
</span><del>-
</del><span class="cx">     UIScriptContext(UIScriptContextDelegate&amp;);
</span><ins>+    ~UIScriptContext();
</ins><span class="cx"> 
</span><span class="cx">     void runUIScript(WKStringRef script, unsigned scriptCallbackID);
</span><span class="cx">     void requestUIScriptCompletion(JSStringRef);
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerUIScriptContextUIScriptControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/UIScriptContext/UIScriptController.cpp (194720 => 194721)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/UIScriptContext/UIScriptController.cpp        2016-01-07 22:02:54 UTC (rev 194720)
+++ trunk/Tools/WebKitTestRunner/UIScriptContext/UIScriptController.cpp        2016-01-07 22:09:33 UTC (rev 194721)
</span><span class="lines">@@ -33,10 +33,15 @@
</span><span class="cx"> namespace WTR {
</span><span class="cx"> 
</span><span class="cx"> UIScriptController::UIScriptController(UIScriptContext&amp; context)
</span><del>-    : m_context(context)
</del><ins>+    : m_context(&amp;context)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void UIScriptController::contextDestroyed()
+{
+    m_context = nullptr;
+}
+
</ins><span class="cx"> void UIScriptController::makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception)
</span><span class="cx"> {
</span><span class="cx">     setProperty(context, windowObject, &quot;uiController&quot;, this, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception);
</span><span class="lines">@@ -55,57 +60,57 @@
</span><span class="cx"> 
</span><span class="cx"> void UIScriptController::setWillBeginZoomingCallback(JSValueRef callback)
</span><span class="cx"> {
</span><del>-    m_context.registerCallback(callback, CallbackTypeWillBeginZooming);
</del><ins>+    m_context-&gt;registerCallback(callback, CallbackTypeWillBeginZooming);
</ins><span class="cx">     platformSetWillBeginZoomingCallback();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSValueRef UIScriptController::willBeginZoomingCallback() const
</span><span class="cx"> {
</span><del>-    return m_context.callbackWithID(CallbackTypeWillBeginZooming);
</del><ins>+    return m_context-&gt;callbackWithID(CallbackTypeWillBeginZooming);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void UIScriptController::setDidEndZoomingCallback(JSValueRef callback)
</span><span class="cx"> {
</span><del>-    m_context.registerCallback(callback, CallbackTypeDidEndZooming);
</del><ins>+    m_context-&gt;registerCallback(callback, CallbackTypeDidEndZooming);
</ins><span class="cx">     platformSetDidEndZoomingCallback();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSValueRef UIScriptController::didEndZoomingCallback() const
</span><span class="cx"> {
</span><del>-    return m_context.callbackWithID(CallbackTypeDidEndZooming);
</del><ins>+    return m_context-&gt;callbackWithID(CallbackTypeDidEndZooming);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void UIScriptController::setDidEndScrollingCallback(JSValueRef callback)
</span><span class="cx"> {
</span><del>-    m_context.registerCallback(callback, CallbackTypeDidEndScrolling);
</del><ins>+    m_context-&gt;registerCallback(callback, CallbackTypeDidEndScrolling);
</ins><span class="cx">     platformSetDidEndScrollingCallback();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSValueRef UIScriptController::didEndScrollingCallback() const
</span><span class="cx"> {
</span><del>-    return m_context.callbackWithID(CallbackTypeDidEndScrolling);
</del><ins>+    return m_context-&gt;callbackWithID(CallbackTypeDidEndScrolling);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void UIScriptController::setDidShowKeyboardCallback(JSValueRef callback)
</span><span class="cx"> {
</span><del>-    m_context.registerCallback(callback, CallbackTypeDidShowKeyboard);
</del><ins>+    m_context-&gt;registerCallback(callback, CallbackTypeDidShowKeyboard);
</ins><span class="cx">     platformSetDidShowKeyboardCallback();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSValueRef UIScriptController::didShowKeyboardCallback() const
</span><span class="cx"> {
</span><del>-    return m_context.callbackWithID(CallbackTypeDidShowKeyboard);
</del><ins>+    return m_context-&gt;callbackWithID(CallbackTypeDidShowKeyboard);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void UIScriptController::setDidHideKeyboardCallback(JSValueRef callback)
</span><span class="cx"> {
</span><del>-    m_context.registerCallback(callback, CallbackTypeDidHideKeyboard);
</del><ins>+    m_context-&gt;registerCallback(callback, CallbackTypeDidHideKeyboard);
</ins><span class="cx">     platformSetDidHideKeyboardCallback();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSValueRef UIScriptController::didHideKeyboardCallback() const
</span><span class="cx"> {
</span><del>-    return m_context.callbackWithID(CallbackTypeDidHideKeyboard);
</del><ins>+    return m_context-&gt;callbackWithID(CallbackTypeDidHideKeyboard);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if !PLATFORM(IOS)
</span><span class="lines">@@ -172,7 +177,7 @@
</span><span class="cx"> 
</span><span class="cx"> void UIScriptController::uiScriptComplete(JSStringRef result)
</span><span class="cx"> {
</span><del>-    m_context.requestUIScriptCompletion(result);
</del><ins>+    m_context-&gt;requestUIScriptCompletion(result);
</ins><span class="cx">     platformClearAllCallbacks();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnerUIScriptContextUIScriptControllerh"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/UIScriptContext/UIScriptController.h (194720 => 194721)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/UIScriptContext/UIScriptController.h        2016-01-07 22:02:54 UTC (rev 194720)
+++ trunk/Tools/WebKitTestRunner/UIScriptContext/UIScriptController.h        2016-01-07 22:09:33 UTC (rev 194721)
</span><span class="lines">@@ -39,7 +39,9 @@
</span><span class="cx">     {
</span><span class="cx">         return adoptRef(*new UIScriptController(context));
</span><span class="cx">     }
</span><del>-    
</del><ins>+
+    void contextDestroyed();
+
</ins><span class="cx">     void makeWindowObject(JSContextRef, JSObjectRef windowObject, JSValueRef* exception);
</span><span class="cx">     
</span><span class="cx">     void doAsyncTask(JSValueRef callback);
</span><span class="lines">@@ -87,7 +89,7 @@
</span><span class="cx"> 
</span><span class="cx">     JSObjectRef objectFromRect(const WKRect&amp;) const;
</span><span class="cx"> 
</span><del>-    UIScriptContext&amp; m_context;
</del><ins>+    UIScriptContext* m_context;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunneriosUIScriptControllerIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm (194720 => 194721)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm        2016-01-07 22:02:54 UTC (rev 194720)
+++ trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm        2016-01-07 22:09:33 UTC (rev 194721)
</span><span class="lines">@@ -42,10 +42,12 @@
</span><span class="cx"> 
</span><span class="cx"> void UIScriptController::doAsyncTask(JSValueRef callback)
</span><span class="cx"> {
</span><del>-    unsigned callbackID = m_context.prepareForAsyncTask(callback, CallbackTypeNonPersistent);
</del><ins>+    unsigned callbackID = m_context-&gt;prepareForAsyncTask(callback, CallbackTypeNonPersistent);
</ins><span class="cx"> 
</span><span class="cx">     dispatch_async(dispatch_get_main_queue(), ^{
</span><del>-        m_context.asyncTaskComplete(callbackID);
</del><ins>+        if (!m_context)
+            return;
+        m_context-&gt;asyncTaskComplete(callbackID);
</ins><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -53,10 +55,12 @@
</span><span class="cx"> {
</span><span class="cx">     TestRunnerWKWebView *webView = TestController::singleton().mainWebView()-&gt;platformView();
</span><span class="cx"> 
</span><del>-    unsigned callbackID = m_context.prepareForAsyncTask(callback, CallbackTypeNonPersistent);
</del><ins>+    unsigned callbackID = m_context-&gt;prepareForAsyncTask(callback, CallbackTypeNonPersistent);
</ins><span class="cx"> 
</span><span class="cx">     [webView zoomToScale:scale animated:YES completionHandler:^{
</span><del>-        m_context.asyncTaskComplete(callbackID);
</del><ins>+        if (!m_context)
+            return;
+        m_context-&gt;asyncTaskComplete(callbackID);
</ins><span class="cx">     }];
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -77,29 +81,35 @@
</span><span class="cx"> 
</span><span class="cx"> void UIScriptController::singleTapAtPoint(long x, long y, JSValueRef callback)
</span><span class="cx"> {
</span><del>-    unsigned callbackID = m_context.prepareForAsyncTask(callback, CallbackTypeNonPersistent);
</del><ins>+    unsigned callbackID = m_context-&gt;prepareForAsyncTask(callback, CallbackTypeNonPersistent);
</ins><span class="cx"> 
</span><span class="cx">     [[HIDEventGenerator sharedHIDEventGenerator] tap:globalToContentCoordinates(TestController::singleton().mainWebView()-&gt;platformView(), x, y) completionBlock:^{
</span><del>-        m_context.asyncTaskComplete(callbackID);
</del><ins>+        if (!m_context)
+            return;
+        m_context-&gt;asyncTaskComplete(callbackID);
</ins><span class="cx">     }];
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void UIScriptController::doubleTapAtPoint(long x, long y, JSValueRef callback)
</span><span class="cx"> {
</span><del>-    unsigned callbackID = m_context.prepareForAsyncTask(callback, CallbackTypeNonPersistent);
</del><ins>+    unsigned callbackID = m_context-&gt;prepareForAsyncTask(callback, CallbackTypeNonPersistent);
</ins><span class="cx"> 
</span><span class="cx">     [[HIDEventGenerator sharedHIDEventGenerator] doubleTap:globalToContentCoordinates(TestController::singleton().mainWebView()-&gt;platformView(), x, y) completionBlock:^{
</span><del>-        m_context.asyncTaskComplete(callbackID);
</del><ins>+        if (!m_context)
+            return;
+        m_context-&gt;asyncTaskComplete(callbackID);
</ins><span class="cx">     }];
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void UIScriptController::typeCharacterUsingHardwareKeyboard(JSStringRef character, JSValueRef callback)
</span><span class="cx"> {
</span><del>-    unsigned callbackID = m_context.prepareForAsyncTask(callback, CallbackTypeNonPersistent);
</del><ins>+    unsigned callbackID = m_context-&gt;prepareForAsyncTask(callback, CallbackTypeNonPersistent);
</ins><span class="cx"> 
</span><span class="cx">     // Assumes that the keyboard is already shown.
</span><span class="cx">     [[HIDEventGenerator sharedHIDEventGenerator] keyDown:toWTFString(toWK(character)) completionBlock:^{
</span><del>-        m_context.asyncTaskComplete(callbackID);
</del><ins>+        if (!m_context)
+            return;
+        m_context-&gt;asyncTaskComplete(callbackID);
</ins><span class="cx">     }];
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -122,14 +132,16 @@
</span><span class="cx">     CGRect contentVisibleRect = webView._contentVisibleRect;
</span><span class="cx">     
</span><span class="cx">     WKRect wkRect = WKRectMake(contentVisibleRect.origin.x, contentVisibleRect.origin.y, contentVisibleRect.size.width, contentVisibleRect.size.height);
</span><del>-    return m_context.objectFromRect(wkRect);
</del><ins>+    return m_context-&gt;objectFromRect(wkRect);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void UIScriptController::platformSetWillBeginZoomingCallback()
</span><span class="cx"> {
</span><span class="cx">     TestRunnerWKWebView *webView = TestController::singleton().mainWebView()-&gt;platformView();
</span><span class="cx">     webView.willBeginZoomingCallback = ^{
</span><del>-        m_context.fireCallback(CallbackTypeWillBeginZooming);
</del><ins>+        if (!m_context)
+            return;
+        m_context-&gt;fireCallback(CallbackTypeWillBeginZooming);
</ins><span class="cx">     };
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -137,7 +149,9 @@
</span><span class="cx"> {
</span><span class="cx">     TestRunnerWKWebView *webView = TestController::singleton().mainWebView()-&gt;platformView();
</span><span class="cx">     webView.didEndZoomingCallback = ^{
</span><del>-        m_context.fireCallback(CallbackTypeDidEndZooming);
</del><ins>+        if (!m_context)
+            return;
+        m_context-&gt;fireCallback(CallbackTypeDidEndZooming);
</ins><span class="cx">     };
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -145,7 +159,9 @@
</span><span class="cx"> {
</span><span class="cx">     TestRunnerWKWebView *webView = TestController::singleton().mainWebView()-&gt;platformView();
</span><span class="cx">     webView.didShowKeyboardCallback = ^{
</span><del>-        m_context.fireCallback(CallbackTypeDidShowKeyboard);
</del><ins>+        if (!m_context)
+            return;
+        m_context-&gt;fireCallback(CallbackTypeDidShowKeyboard);
</ins><span class="cx">     };
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -153,7 +169,9 @@
</span><span class="cx"> {
</span><span class="cx">     TestRunnerWKWebView *webView = TestController::singleton().mainWebView()-&gt;platformView();
</span><span class="cx">     webView.didHideKeyboardCallback = ^{
</span><del>-        m_context.fireCallback(CallbackTypeDidHideKeyboard);
</del><ins>+        if (!m_context)
+            return;
+        m_context-&gt;fireCallback(CallbackTypeDidHideKeyboard);
</ins><span class="cx">     };
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -161,7 +179,9 @@
</span><span class="cx"> {
</span><span class="cx">     TestRunnerWKWebView *webView = TestController::singleton().mainWebView()-&gt;platformView();
</span><span class="cx">     webView.didEndScrollingCallback = ^{
</span><del>-        m_context.fireCallback(CallbackTypeDidEndScrolling);
</del><ins>+        if (!m_context)
+            return;
+        m_context-&gt;fireCallback(CallbackTypeDidEndScrolling);
</ins><span class="cx">     };
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnermacUIScriptControllerMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/mac/UIScriptControllerMac.mm (194720 => 194721)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/mac/UIScriptControllerMac.mm        2016-01-07 22:02:54 UTC (rev 194720)
+++ trunk/Tools/WebKitTestRunner/mac/UIScriptControllerMac.mm        2016-01-07 22:09:33 UTC (rev 194721)
</span><span class="lines">@@ -32,10 +32,12 @@
</span><span class="cx"> 
</span><span class="cx"> void UIScriptController::doAsyncTask(JSValueRef callback)
</span><span class="cx"> {
</span><del>-    unsigned callbackID = m_context.prepareForAsyncTask(callback, CallbackTypeNonPersistent);
</del><ins>+    unsigned callbackID = m_context-&gt;prepareForAsyncTask(callback, CallbackTypeNonPersistent);
</ins><span class="cx"> 
</span><span class="cx">     dispatch_async(dispatch_get_main_queue(), ^{
</span><del>-        m_context.asyncTaskComplete(callbackID);
</del><ins>+        if (!m_context)
+            return;
+        m_context-&gt;asyncTaskComplete(callbackID);
</ins><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>