[iOS WK1] Do not try to dispatch messages to subframes if their documents have not...
authorbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 15 May 2017 17:24:14 +0000 (17:24 +0000)
committerbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 15 May 2017 17:24:14 +0000 (17:24 +0000)
https://bugs.webkit.org/show_bug.cgi?id=172059
<rdar://problem/31963192>

Reviewed by Zalan Bujtas.

On iOS WK1 we can end up in an inconsistent state, where
1. The web thread is inside a newly-injected iframe's document's constructor and
2. waiting on a delegate callback on the main thread
while the main thread
(a) Evaluates arbitrary JavaScript that modifies storage which
(b) Triggers an event dispatch.

* storage/StorageEventDispatcher.cpp:
(WebCore::StorageEventDispatcher::dispatchSessionStorageEvents): If the sub-frame's document
is in an inconsistent state, skip it.
(WebCore::StorageEventDispatcher::dispatchLocalStorageEvents): Ditto.
(WebCore::StorageEventDispatcher::dispatchSessionStorageEventsToFrames): Ditto.
(WebCore::StorageEventDispatcher::dispatchLocalStorageEventsToFrames): Ditto.

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

Source/WebCore/ChangeLog
Source/WebCore/storage/StorageEventDispatcher.cpp

index e4e79f8..7d079d3 100644 (file)
@@ -1,3 +1,25 @@
+2017-05-15  Brent Fulgham  <bfulgham@apple.com>
+
+        [iOS WK1] Do not try to dispatch messages to subframes if their documents have not been constructed yet.
+        https://bugs.webkit.org/show_bug.cgi?id=172059
+        <rdar://problem/31963192>
+
+        Reviewed by Zalan Bujtas.
+
+        On iOS WK1 we can end up in an inconsistent state, where
+        1. The web thread is inside a newly-injected iframe's document's constructor and
+        2. waiting on a delegate callback on the main thread
+        while the main thread
+        (a) Evaluates arbitrary JavaScript that modifies storage which
+        (b) Triggers an event dispatch.
+        * storage/StorageEventDispatcher.cpp:
+        (WebCore::StorageEventDispatcher::dispatchSessionStorageEvents): If the sub-frame's document
+        is in an inconsistent state, skip it.
+        (WebCore::StorageEventDispatcher::dispatchLocalStorageEvents): Ditto.
+        (WebCore::StorageEventDispatcher::dispatchSessionStorageEventsToFrames): Ditto.
+        (WebCore::StorageEventDispatcher::dispatchLocalStorageEventsToFrames): Ditto.
+
 2017-05-15  Zalan Bujtas  <zalan@apple.com>
 
         Simple line layout: Leading whitespace followed by a <br> produces an extra linebreak.
index ab89263..9ee0fb5 100644 (file)
@@ -50,6 +50,8 @@ void StorageEventDispatcher::dispatchSessionStorageEvents(const String& key, con
 
     // Send events only to our page.
     for (Frame* frame = &page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+        if (!frame->document())
+            continue;
         if (sourceFrame != frame && frame->document()->securityOrigin().equal(securityOrigin.securityOrigin().ptr()))
             frames.append(frame);
     }
@@ -68,6 +70,8 @@ void StorageEventDispatcher::dispatchLocalStorageEvents(const String& key, const
     // Send events to every page.
     for (auto& pageInGroup : page->group().pages()) {
         for (Frame* frame = &pageInGroup->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+            if (!frame->document())
+                continue;
             if (sourceFrame != frame && frame->document()->securityOrigin().equal(securityOrigin.securityOrigin().ptr()))
                 frames.append(frame);
         }
@@ -82,6 +86,8 @@ void StorageEventDispatcher::dispatchSessionStorageEventsToFrames(Page& page, co
 
     for (auto& frame : frames) {
         auto result = frame->document()->domWindow()->sessionStorage();
+        if (!frame->document())
+            continue;
         if (!result.hasException())
             frame->document()->enqueueWindowEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, url, result.releaseReturnValue()));
     }
@@ -94,6 +100,8 @@ void StorageEventDispatcher::dispatchLocalStorageEventsToFrames(PageGroup& pageG
 
     for (auto& frame : frames) {
         auto result = frame->document()->domWindow()->localStorage();
+        if (!frame->document())
+            continue;
         if (!result.hasException())
             frame->document()->enqueueWindowEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, url, result.releaseReturnValue()));
     }