Crash in WebCore::NavigationScheduler::startTimer()
https://bugs.webkit.org/show_bug.cgi?id=123288
<rdar://problem/14055644>

Reviewed by Alexey Proskuryakov.

Source/WebCore:

Currently NavigationScheduler::startTimer() synchronously notifies the client
before the Web Inspector of a scheduled redirect. If a client cancels this
redirect then NavigationScheduler::m_redirect will become null and we'll
subsequently crash when informing the Web Inspector of this formerly scheduled
redirect. Instead, NavigationScheduler::startTimer() should notify the Web
Inspector before it notifies the client of a scheduled redirect.

As a side benefit of this change, the Web Inspector is notified of a scheduled
redirect before being notified of it being canceled when a client chooses to cancel
a scheduled redirect.

* loader/NavigationScheduler.cpp:
(WebCore::NavigationScheduler::startTimer):

Tools:

Add API test.

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/mac/WillPerformClientRedirectToURLCrash.html: Added.
* TestWebKitAPI/Tests/mac/WillPerformClientRedirectToURLCrash.mm: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@157957 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/loader/NavigationScheduler.cpp b/Source/WebCore/loader/NavigationScheduler.cpp
index 9ab959f..11860e2 100644
--- a/Source/WebCore/loader/NavigationScheduler.cpp
+++ b/Source/WebCore/loader/NavigationScheduler.cpp
@@ -466,9 +466,10 @@
     if (!m_redirect->shouldStartTimer(m_frame))
         return;
 
-    m_timer.startOneShot(m_redirect->delay());
-    m_redirect->didStartTimer(m_frame, &m_timer);
-    InspectorInstrumentation::frameScheduledNavigation(m_frame, m_redirect->delay());
+    double delay = m_redirect->delay();
+    m_timer.startOneShot(delay);
+    InspectorInstrumentation::frameScheduledNavigation(m_frame, delay);
+    m_redirect->didStartTimer(m_frame, &m_timer); // m_redirect may be null on return (e.g. the client canceled the load)
 }
 
 void NavigationScheduler::cancel(bool newLoadInProgress)