Changeset 195496 in webkit
- Timestamp:
- Jan 22, 2016 5:04:59 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 10 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r195495 r195496 1 2016-01-22 Chris Dumez <cdumez@apple.com> 2 3 Document.open / Document.write should be prevented while the document is being unloaded 4 https://bugs.webkit.org/show_bug.cgi?id=153255 5 <rdar://problem/22741293> 6 7 Reviewed by Ryosuke Niwa. 8 9 Add layout tests that cover calling Document.open / Document.write from 10 unload and pagehide handlers. 11 12 * fast/frames/page-hide-document-open-expected.txt: Added. 13 * fast/frames/page-hide-document-open.html: Added. 14 * fast/frames/page-unload-document-open-expected.txt: Added. 15 * fast/frames/page-unload-document-open.html: Added. 16 * fast/frames/resources/finish-test.html: Added. 17 * fast/frames/resources/page-hide-document-open-frame.html: Added. 18 * fast/frames/resources/page-hide-document-open-win.html: Added. 19 * fast/frames/resources/page-unload-document-open-frame.html: Added. 20 * fast/frames/resources/page-unload-document-open-win.html: Added. 21 1 22 2016-01-22 Brady Eidson <beidson@apple.com> 2 23 -
trunk/Source/WebCore/ChangeLog
r195495 r195496 1 2016-01-22 Chris Dumez <cdumez@apple.com> 2 3 Document.open / Document.write should be prevented while the document is being unloaded 4 https://bugs.webkit.org/show_bug.cgi?id=153255 5 <rdar://problem/22741293> 6 7 Reviewed by Ryosuke Niwa. 8 9 Document.open / Document.write should be prevented while the document 10 is being unloaded, as per the HTML specification: 11 - https://html.spec.whatwg.org/multipage/webappapis.html#dom-document-open (step 6) 12 - https://html.spec.whatwg.org/multipage/webappapis.html#dom-document-write (step 3) 13 14 This patch is aligning our behavior with the specification and Firefox. 15 Calling Document.open / Document.write during the document was being 16 unloaded would cause us to crash as this was unexpected. 17 18 Tests: fast/frames/page-hide-document-open.html 19 fast/frames/page-unload-document-open.html 20 21 * WebCore.xcodeproj/project.pbxproj: 22 Add new IgnoreOpensDuringUnloadCountIncrementer.h header. 23 24 * dom/Document.cpp: 25 (WebCore::Document::open): 26 Abort if the document's ignore-opens-during-unload counter is greater 27 than zero, as per: 28 https://html.spec.whatwg.org/multipage/webappapis.html#dom-document-open (step 6) 29 30 (WebCore::Document::write): 31 Abort if the insertion point is undefined and the document's 32 ignore-opens-during-unload counter is greater than zero, as per: 33 https://html.spec.whatwg.org/multipage/webappapis.html#dom-document-write (step 3) 34 35 * dom/Document.h: 36 Add data member to maintain the document's ignore-opens-during-unload counter: 37 https://html.spec.whatwg.org/multipage/webappapis.html#ignore-opens-during-unload-counter 38 39 * dom/IgnoreOpensDuringUnloadCountIncrementer.h: Added. 40 Add utility class to increment / decrement a document's 41 ignore-opens-during-unload counter. 42 43 * history/CachedFrame.cpp: 44 (WebCore::CachedFrame::CachedFrame): 45 When a page goes into PageCache, we don't end up calling 46 FrameLoader::detachChildren() so we need to increment the document's 47 ignore-opens-during-unload counter before calling stopLoading() on each 48 subframe. 49 50 * loader/FrameLoader.cpp: 51 (WebCore::FrameLoader::detachChildren): 52 detachChildren() will end up firing the pagehide / unload events in each 53 child frame so we increment the parent frame's document's 54 ignore-opens-during-unload counter. This behavior matches the text of: 55 https://html.spec.whatwg.org/multipage/browsers.html#unload-a-document 56 57 As per the spec, the document's ignore-opens-during-unload counter should 58 be incremented before firing the pagehide / unload events at the document's 59 Window object. It should be decremented only after firing the pagehide / 60 unload events in each subframe. This is needed in case a subframe tries to 61 call document.open / document.write on a parent frame's document, from its 62 pagehide or unload handler. 63 64 (WebCore::FrameLoader::dispatchUnloadEvents): 65 Increment the document's ignore-opens-during-unload counter before firing 66 the pagehide / unload events and decrement it after. As per the spec, we 67 are not supposed to decrement this early. We actually supposed to wait 68 until the pagehide / unload events have been fired in all the subframes. 69 For this reason, we take care of re-incrementing the document's 70 ignore-opens-during-unload in detachChildren(), which will take care of 71 firing the pagehide / unload in the subframes. 72 1 73 2016-01-22 Brady Eidson <beidson@apple.com> 2 74 -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r195443 r195496 1701 1701 463EB6231B8789E00096ED51 /* TagCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 463EB6211B8789CB0096ED51 /* TagCollection.h */; }; 1702 1702 4669B2871B852A0B000F905F /* JSDOMNamedFlowCollectionCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46F2768E1B85297F005C2556 /* JSDOMNamedFlowCollectionCustom.cpp */; }; 1703 467302021C4EFE7800BCB357 /* IgnoreOpensDuringUnloadCountIncrementer.h in Headers */ = {isa = PBXBuildFile; fileRef = 467302011C4EFE6600BCB357 /* IgnoreOpensDuringUnloadCountIncrementer.h */; }; 1703 1704 4689F1AF1267BAE100E8D380 /* FileMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 4689F1AE1267BAE100E8D380 /* FileMetadata.h */; }; 1704 1705 46C83EFD1A9BBE2900A79A41 /* GeoNotifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 46C83EFB1A9BBE2900A79A41 /* GeoNotifier.cpp */; }; … … 9121 9122 463EB6201B8789CB0096ED51 /* TagCollection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TagCollection.cpp; sourceTree = "<group>"; }; 9122 9123 463EB6211B8789CB0096ED51 /* TagCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TagCollection.h; sourceTree = "<group>"; }; 9124 467302011C4EFE6600BCB357 /* IgnoreOpensDuringUnloadCountIncrementer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IgnoreOpensDuringUnloadCountIncrementer.h; sourceTree = "<group>"; }; 9123 9125 4689F1AE1267BAE100E8D380 /* FileMetadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileMetadata.h; sourceTree = "<group>"; }; 9124 9126 46C83EFB1A9BBE2900A79A41 /* GeoNotifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GeoNotifier.cpp; sourceTree = "<group>"; }; … … 24005 24007 C3CF17A315B0063F00276D39 /* IdTargetObserverRegistry.h */, 24006 24008 8AB4BC76126FDB7100DEB727 /* IgnoreDestructiveWriteCountIncrementer.h */, 24009 467302011C4EFE6600BCB357 /* IgnoreOpensDuringUnloadCountIncrementer.h */, 24007 24010 AA4C3A740B2B1679002334A2 /* InlineStyleSheetOwner.cpp */, 24008 24011 AA4C3A750B2B1679002334A2 /* InlineStyleSheetOwner.h */, … … 25625 25628 2E75841E12779ADA0062628B /* FileReaderLoader.h in Headers */, 25626 25629 2E75841F12779ADA0062628B /* FileReaderLoaderClient.h in Headers */, 25630 467302021C4EFE7800BCB357 /* IgnoreOpensDuringUnloadCountIncrementer.h in Headers */, 25627 25631 2EDF369D122C94B4002F7D4E /* FileReaderSync.h in Headers */, 25628 25632 2EF1BFEB121C9F4200C27627 /* FileStream.h in Headers */, -
trunk/Source/WebCore/dom/Document.cpp
r195452 r195496 476 476 , m_frameElementsShouldIgnoreScrolling(false) 477 477 , m_updateFocusAppearanceRestoresSelection(SelectionRestorationMode::SetDefault) 478 , m_ignoreDestructiveWriteCount(0)479 478 , m_markers(std::make_unique<DocumentMarkerController>(*this)) 480 479 , m_updateFocusAppearanceTimer(*this, &Document::updateFocusAppearanceTimerFired) … … 2498 2497 void Document::open(Document* ownerDocument) 2499 2498 { 2499 if (m_ignoreOpensDuringUnloadCount) 2500 return; 2501 2500 2502 if (ownerDocument) { 2501 2503 setURL(ownerDocument->url()); … … 2846 2848 2847 2849 bool hasInsertionPoint = m_parser && m_parser->hasInsertionPoint(); 2848 if (!hasInsertionPoint && m_ignoreDestructiveWriteCount)2850 if (!hasInsertionPoint && (m_ignoreOpensDuringUnloadCount || m_ignoreDestructiveWriteCount)) 2849 2851 return; 2850 2852 -
trunk/Source/WebCore/dom/Document.h
r195485 r195496 1339 1339 friend class Node; 1340 1340 friend class IgnoreDestructiveWriteCountIncrementer; 1341 friend class IgnoreOpensDuringUnloadCountIncrementer; 1341 1342 1342 1343 void updateTitleElement(Element* newTitleElement); … … 1529 1530 SelectionRestorationMode m_updateFocusAppearanceRestoresSelection; 1530 1531 1531 // http://www.whatwg.org/specs/web-apps/current-work/#ignore-destructive-writes-counter 1532 unsigned m_ignoreDestructiveWriteCount; 1532 // https://html.spec.whatwg.org/multipage/webappapis.html#ignore-destructive-writes-counter 1533 unsigned m_ignoreDestructiveWriteCount { 0 }; 1534 1535 // https://html.spec.whatwg.org/multipage/webappapis.html#ignore-opens-during-unload-counter 1536 unsigned m_ignoreOpensDuringUnloadCount { 0 }; 1533 1537 1534 1538 unsigned m_styleRecalcCount { 0 }; -
trunk/Source/WebCore/history/CachedFrame.cpp
r194496 r195496 40 40 #include "HistoryController.h" 41 41 #include "HistoryItem.h" 42 #include "IgnoreOpensDuringUnloadCountIncrementer.h" 42 43 #include "Logging.h" 43 44 #include "MainFrame.h" … … 158 159 frame.loader().stopLoading(UnloadEventPolicyUnloadAndPageHide); 159 160 160 // Create the CachedFrames for all Frames in the FrameTree. 161 for (Frame* child = frame.tree().firstChild(); child; child = child->tree().nextSibling()) 162 m_childFrames.append(std::make_unique<CachedFrame>(*child)); 161 { 162 // The following will fire the pagehide event in each subframe and the HTML specification states 163 // that the parent document's ignore-opens-during-unload counter should be incremented while the 164 // pagehide event is being fired in its subframes: 165 // https://html.spec.whatwg.org/multipage/browsers.html#unload-a-document 166 IgnoreOpensDuringUnloadCountIncrementer ignoreOpensDuringUnloadCountIncrementer(m_document.get()); 167 168 // Create the CachedFrames for all Frames in the FrameTree. 169 for (Frame* child = frame.tree().firstChild(); child; child = child->tree().nextSibling()) 170 m_childFrames.append(std::make_unique<CachedFrame>(*child)); 171 } 163 172 164 173 // Active DOM objects must be suspended before we cache the frame script data, -
trunk/Source/WebCore/loader/FrameLoader.cpp
r195494 r195496 78 78 #include "HistoryItem.h" 79 79 #include "IconController.h" 80 #include "IgnoreOpensDuringUnloadCountIncrementer.h" 80 81 #include "InspectorController.h" 81 82 #include "InspectorInstrumentation.h" … … 2427 2428 void FrameLoader::detachChildren() 2428 2429 { 2430 // detachChildren() will fire the unload event in each subframe and the 2431 // HTML specification states that the parent document's ignore-opens-during-unload counter while 2432 // this event is being fired in its subframes: 2433 // https://html.spec.whatwg.org/multipage/browsers.html#unload-a-document 2434 IgnoreOpensDuringUnloadCountIncrementer ignoreOpensDuringUnloadCountIncrementer(m_frame.document()); 2435 2429 2436 Vector<Ref<Frame>, 16> childrenToDetach; 2430 2437 childrenToDetach.reserveInitialCapacity(m_frame.tree().childCount()); … … 2879 2886 // We store the frame's page in a local variable because the frame might get detached inside dispatchEvent. 2880 2887 ForbidPromptsScope forbidPrompts(m_frame.page()); 2888 IgnoreOpensDuringUnloadCountIncrementer ignoreOpensDuringUnloadCountIncrementer(m_frame.document()); 2881 2889 2882 2890 if (m_didCallImplicitClose && !m_wasUnloadEventEmitted) {
Note: See TracChangeset
for help on using the changeset viewer.