Title: [183781] trunk
Revision
183781
Author
[email protected]
Date
2015-05-04 16:58:32 -0700 (Mon, 04 May 2015)

Log Message

Crash at com.apple.WebKit.WebContent at com.apple.WebCore: WebCore::createWindow + 185
https://bugs.webkit.org/show_bug.cgi?id=144597
<rdar://problem/20361579>

Reviewed by Andreas Kling.

Source/WebCore:

Test: fast/dom/Window/window-open-activeWindow-null-frame.html

In our implementation of window.open(), we make sure that the window
which window.open() is called has a frame. However, we did not have the
same check for the activeDOMWindow (i.e. the lexicalGlobalObject) causing
us to crash in WebCore::createWindow() when dereferencing it.

This patch updates WebCore::createWindow() takes a reference to the
openerFrame instead of a pointer to make it clear the implementation
expects it to be non-null. A null check is then added for the frame
at the call site: DOMWindow::createWindow().

* inspector/InspectorFrontendClientLocal.cpp:
(WebCore::InspectorFrontendClientLocal::openInNewTab):
* loader/FrameLoader.cpp:
(WebCore::isDocumentSandboxed):
(WebCore::FrameLoader::submitForm):
(WebCore::createWindow):
Take a reference to openerFrame instead of a pointer as the
implementation expects it to be non-null.

* loader/FrameLoader.h:
* page/DOMWindow.cpp:
(WebCore::DOMWindow::createWindow):
Add null check for activeFrame before passing it to
WebCore::createWindow().

LayoutTests:

Add a layout test to cover the case where window.open() is called on a
window that is different than the activeDOMWindow and where the
activeDOMWindow does not have a frame.

* fast/dom/Window/resources/test-frame.html: Added.
* fast/dom/Window/window-open-activeWindow-null-frame-expected.txt: Added.
* fast/dom/Window/window-open-activeWindow-null-frame.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (183780 => 183781)


--- trunk/LayoutTests/ChangeLog	2015-05-04 23:51:21 UTC (rev 183780)
+++ trunk/LayoutTests/ChangeLog	2015-05-04 23:58:32 UTC (rev 183781)
@@ -1,3 +1,19 @@
+2015-05-04  Chris Dumez  <[email protected]>
+
+        Crash at com.apple.WebKit.WebContent at com.apple.WebCore: WebCore::createWindow + 185
+        https://bugs.webkit.org/show_bug.cgi?id=144597
+        <rdar://problem/20361579>
+
+        Reviewed by Andreas Kling.
+
+        Add a layout test to cover the case where window.open() is called on a
+        window that is different than the activeDOMWindow and where the
+        activeDOMWindow does not have a frame.
+
+        * fast/dom/Window/resources/test-frame.html: Added.
+        * fast/dom/Window/window-open-activeWindow-null-frame-expected.txt: Added.
+        * fast/dom/Window/window-open-activeWindow-null-frame.html: Added.
+
 2015-05-04  Simon Fraser  <[email protected]>
 
         display:none iframes cause repeated compositing flushing

Added: trunk/LayoutTests/fast/dom/Window/resources/test-frame.html (0 => 183781)


--- trunk/LayoutTests/fast/dom/Window/resources/test-frame.html	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/Window/resources/test-frame.html	2015-05-04 23:58:32 UTC (rev 183781)
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+<body>
+TEST
+</body>
+</html>

Added: trunk/LayoutTests/fast/dom/Window/window-open-activeWindow-null-frame-expected.txt (0 => 183781)


--- trunk/LayoutTests/fast/dom/Window/window-open-activeWindow-null-frame-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/Window/window-open-activeWindow-null-frame-expected.txt	2015-05-04 23:58:32 UTC (rev 183781)
@@ -0,0 +1,10 @@
+Tests window.open() call with an activeDOMWindow that has a null frame.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+This test passes if it doesn't crash.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/dom/Window/window-open-activeWindow-null-frame.html (0 => 183781)


--- trunk/LayoutTests/fast/dom/Window/window-open-activeWindow-null-frame.html	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/Window/window-open-activeWindow-null-frame.html	2015-05-04 23:58:32 UTC (rev 183781)
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script>
+description("Tests window.open() call with an activeDOMWindow that has a null frame.");
+debug("This test passes if it doesn't crash.");
+
+window.jsTestIsAsync = true;
+
+if (window.testRunner)
+    testRunner.setCanOpenWindows(true);
+
+function openWindow()
+{
+    testFrameWindowOpen.call(window);
+    finishJSTest();
+}
+
+function removeSubFrame()
+{
+    var testFrame = document.getElementById("testFrame");
+    testFrameWindow = testFrame.contentWindow;
+    testFrameWindowOpen = testFrameWindow.open;
+    testFrame.remove();
+    gc();
+
+    setTimeout(openWindow, 0);
+}
+</script>
+</head>
+<body>
+<iframe id="testFrame" src="" _onload_="removeSubFrame()"></iframe>
+<script src=""
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (183780 => 183781)


--- trunk/Source/WebCore/ChangeLog	2015-05-04 23:51:21 UTC (rev 183780)
+++ trunk/Source/WebCore/ChangeLog	2015-05-04 23:58:32 UTC (rev 183781)
@@ -1,3 +1,38 @@
+2015-05-04  Chris Dumez  <[email protected]>
+
+        Crash at com.apple.WebKit.WebContent at com.apple.WebCore: WebCore::createWindow + 185
+        https://bugs.webkit.org/show_bug.cgi?id=144597
+        <rdar://problem/20361579>
+
+        Reviewed by Andreas Kling.
+
+        Test: fast/dom/Window/window-open-activeWindow-null-frame.html
+
+        In our implementation of window.open(), we make sure that the window
+        which window.open() is called has a frame. However, we did not have the
+        same check for the activeDOMWindow (i.e. the lexicalGlobalObject) causing
+        us to crash in WebCore::createWindow() when dereferencing it.
+
+        This patch updates WebCore::createWindow() takes a reference to the
+        openerFrame instead of a pointer to make it clear the implementation
+        expects it to be non-null. A null check is then added for the frame
+        at the call site: DOMWindow::createWindow().
+
+        * inspector/InspectorFrontendClientLocal.cpp:
+        (WebCore::InspectorFrontendClientLocal::openInNewTab):
+        * loader/FrameLoader.cpp:
+        (WebCore::isDocumentSandboxed):
+        (WebCore::FrameLoader::submitForm):
+        (WebCore::createWindow):
+        Take a reference to openerFrame instead of a pointer as the
+        implementation expects it to be non-null.
+
+        * loader/FrameLoader.h:
+        * page/DOMWindow.cpp:
+        (WebCore::DOMWindow::createWindow):
+        Add null check for activeFrame before passing it to
+        WebCore::createWindow().
+
 2015-05-04  Dean Jackson  <[email protected]>
 
         Create a named CSS property for system colors

Modified: trunk/Source/WebCore/inspector/InspectorFrontendClientLocal.cpp (183780 => 183781)


--- trunk/Source/WebCore/inspector/InspectorFrontendClientLocal.cpp	2015-05-04 23:51:21 UTC (rev 183780)
+++ trunk/Source/WebCore/inspector/InspectorFrontendClientLocal.cpp	2015-05-04 23:58:32 UTC (rev 183781)
@@ -214,7 +214,7 @@
 
     bool created;
     WindowFeatures windowFeatures;
-    RefPtr<Frame> frame = WebCore::createWindow(&mainFrame, &mainFrame, request, windowFeatures, created);
+    RefPtr<Frame> frame = WebCore::createWindow(mainFrame, &mainFrame, request, windowFeatures, created);
     if (!frame)
         return;
 

Modified: trunk/Source/WebCore/loader/FrameLoader.cpp (183780 => 183781)


--- trunk/Source/WebCore/loader/FrameLoader.cpp	2015-05-04 23:51:21 UTC (rev 183780)
+++ trunk/Source/WebCore/loader/FrameLoader.cpp	2015-05-04 23:58:32 UTC (rev 183781)
@@ -169,9 +169,9 @@
 // non-member lets us exclude it from the header file, thus keeping FrameLoader.h's
 // API simpler.
 //
-static bool isDocumentSandboxed(Frame* frame, SandboxFlags mask)
+static bool isDocumentSandboxed(Frame& frame, SandboxFlags mask)
 {
-    return frame->document() && frame->document()->isSandboxed(mask);
+    return frame.document() && frame.document()->isSandboxed(mask);
 }
 
 class FrameLoader::FrameProgressTracker {
@@ -355,7 +355,7 @@
     if (submission->action().isEmpty())
         return;
 
-    if (isDocumentSandboxed(&m_frame, SandboxForms)) {
+    if (isDocumentSandboxed(m_frame, SandboxForms)) {
         // FIXME: This message should be moved off the console once a solution to https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
         m_frame.document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, "Blocked form submission to '" + submission->action().stringCenterEllipsizedToLength() + "' because the form's frame is sandboxed and the 'allow-forms' permission is not set.");
         return;
@@ -3413,14 +3413,14 @@
     return true;
 }
 
-PassRefPtr<Frame> createWindow(Frame* openerFrame, Frame* lookupFrame, const FrameLoadRequest& request, const WindowFeatures& features, bool& created)
+PassRefPtr<Frame> createWindow(Frame& openerFrame, Frame* lookupFrame, const FrameLoadRequest& request, const WindowFeatures& features, bool& created)
 {
     ASSERT(!features.dialog || request.frameName().isEmpty());
 
     created = false;
 
     if (!request.frameName().isEmpty() && request.frameName() != "_blank") {
-        if (RefPtr<Frame> frame = lookupFrame->loader().findFrameForNavigation(request.frameName(), openerFrame->document())) {
+        if (RefPtr<Frame> frame = lookupFrame->loader().findFrameForNavigation(request.frameName(), openerFrame.document())) {
             if (request.frameName() != "_self") {
                 if (Page* page = frame->page())
                     page->chrome().focus();
@@ -3432,28 +3432,28 @@
     // Sandboxed frames cannot open new auxiliary browsing contexts.
     if (isDocumentSandboxed(openerFrame, SandboxPopups)) {
         // FIXME: This message should be moved off the console once a solution to https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
-        openerFrame->document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, "Blocked opening '" + request.resourceRequest().url().stringCenterEllipsizedToLength() + "' in a new window because the request was made in a sandboxed frame whose 'allow-popups' permission is not set.");
+        openerFrame.document()->addConsoleMessage(MessageSource::Security, MessageLevel::Error, "Blocked opening '" + request.resourceRequest().url().stringCenterEllipsizedToLength() + "' in a new window because the request was made in a sandboxed frame whose 'allow-popups' permission is not set.");
         return nullptr;
     }
 
     // FIXME: Setting the referrer should be the caller's responsibility.
     FrameLoadRequest requestWithReferrer = request;
-    String referrer = SecurityPolicy::generateReferrerHeader(openerFrame->document()->referrerPolicy(), request.resourceRequest().url(), openerFrame->loader().outgoingReferrer());
+    String referrer = SecurityPolicy::generateReferrerHeader(openerFrame.document()->referrerPolicy(), request.resourceRequest().url(), openerFrame.loader().outgoingReferrer());
     if (!referrer.isEmpty())
         requestWithReferrer.resourceRequest().setHTTPReferrer(referrer);
-    FrameLoader::addHTTPOriginIfNeeded(requestWithReferrer.resourceRequest(), openerFrame->loader().outgoingOrigin());
+    FrameLoader::addHTTPOriginIfNeeded(requestWithReferrer.resourceRequest(), openerFrame.loader().outgoingOrigin());
 
-    Page* oldPage = openerFrame->page();
+    Page* oldPage = openerFrame.page();
     if (!oldPage)
         return nullptr;
 
-    Page* page = oldPage->chrome().createWindow(openerFrame, requestWithReferrer, features, NavigationAction(requestWithReferrer.resourceRequest()));
+    Page* page = oldPage->chrome().createWindow(&openerFrame, requestWithReferrer, features, NavigationAction(requestWithReferrer.resourceRequest()));
     if (!page)
         return nullptr;
 
     RefPtr<Frame> frame = &page->mainFrame();
 
-    frame->loader().forceSandboxFlags(openerFrame->document()->sandboxFlags());
+    frame->loader().forceSandboxFlags(openerFrame.document()->sandboxFlags());
 
     if (request.frameName() != "_blank")
         frame->tree().setName(request.frameName());

Modified: trunk/Source/WebCore/loader/FrameLoader.h (183780 => 183781)


--- trunk/Source/WebCore/loader/FrameLoader.h	2015-05-04 23:51:21 UTC (rev 183780)
+++ trunk/Source/WebCore/loader/FrameLoader.h	2015-05-04 23:58:32 UTC (rev 183781)
@@ -458,7 +458,7 @@
 //
 // FIXME: Consider making this function part of an appropriate class (not FrameLoader)
 // and moving it to a more appropriate location.
-PassRefPtr<Frame> createWindow(Frame* openerFrame, Frame* lookupFrame, const FrameLoadRequest&, const WindowFeatures&, bool& created);
+PassRefPtr<Frame> createWindow(Frame& openerFrame, Frame* lookupFrame, const FrameLoadRequest&, const WindowFeatures&, bool& created);
 
 } // namespace WebCore
 

Modified: trunk/Source/WebCore/page/DOMWindow.cpp (183780 => 183781)


--- trunk/Source/WebCore/page/DOMWindow.cpp	2015-05-04 23:51:21 UTC (rev 183780)
+++ trunk/Source/WebCore/page/DOMWindow.cpp	2015-05-04 23:58:32 UTC (rev 183781)
@@ -2075,12 +2075,14 @@
 PassRefPtr<Frame> DOMWindow::createWindow(const String& urlString, const AtomicString& frameName, const WindowFeatures& windowFeatures, DOMWindow& activeWindow, Frame* firstFrame, Frame* openerFrame, std::function<void (DOMWindow&)> prepareDialogFunction)
 {
     Frame* activeFrame = activeWindow.frame();
+    if (!activeFrame)
+        return nullptr;
 
     URL completedURL = urlString.isEmpty() ? URL(ParsedURLString, emptyString()) : firstFrame->document()->completeURL(urlString);
     if (!completedURL.isEmpty() && !completedURL.isValid()) {
         // Don't expose client code to invalid URLs.
         activeWindow.printErrorMessage("Unable to open a window with invalid URL '" + completedURL.string() + "'.\n");
-        return 0;
+        return nullptr;
     }
 
     // For whatever reason, Firefox uses the first frame to determine the outgoingReferrer. We replicate that behavior here.
@@ -2093,9 +2095,9 @@
     // We pass the opener frame for the lookupFrame in case the active frame is different from
     // the opener frame, and the name references a frame relative to the opener frame.
     bool created;
-    RefPtr<Frame> newFrame = WebCore::createWindow(activeFrame, openerFrame, frameRequest, windowFeatures, created);
+    RefPtr<Frame> newFrame = WebCore::createWindow(*activeFrame, openerFrame, frameRequest, windowFeatures, created);
     if (!newFrame)
-        return 0;
+        return nullptr;
 
     newFrame->loader().setOpener(openerFrame);
     newFrame->page()->setOpenedByDOM();
@@ -2117,7 +2119,7 @@
 
     // Navigating the new frame could result in it being detached from its page by a navigation policy delegate.
     if (!newFrame->page())
-        return 0;
+        return nullptr;
 
     return newFrame.release();
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to