WebCore:
authorantti <antti@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 27 Sep 2007 23:56:17 +0000 (23:56 +0000)
committerantti <antti@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 27 Sep 2007 23:56:17 +0000 (23:56 +0000)
        Reviewed by Geoff.

        Fix for <rdar://problem/5499125>
        REGRESSION (r21367): After launching Kidzui beta, a webview frame fails to appear in its main window

        If window object properties were modified when it had initial empty document (synchronously after
        window.open() for example) those modifications were lost when the real document was switched in.

        Match Firefox behavior where window properties are not cleared if the inital document and the loaded one
        have matching security domains.

        Tests: fast/dom/Window/window-early-properties.html
               http/tests/security/window-properties-clear-domain.html
               http/tests/security/window-properties-clear-port.html
               http/tests/security/window-properties-pass.html

        * WebCore.exp:
        * loader/FrameLoader.cpp:
        (WebCore::FrameLoader::FrameLoader):
        (WebCore::FrameLoader::init):
        (WebCore::FrameLoader::clear):
        (WebCore::FrameLoader::isSecureTransition):
        (WebCore::FrameLoader::begin):
        * loader/FrameLoader.h:
        If we are transitioning from initial empty document to the final one, do a domain security check
        between old security policy URL and new URL. If that passes don't clear script proxy and script objects.

        * bindings/js/kjs_proxy.cpp:
        (WebCore::KJSProxy::updateDocumentWrapper):
        * bindings/js/kjs_proxy.h:
        * page/Frame.cpp:
        (WebCore::Frame::setDocument):
        Since we don't always clear window properties anymore, we need to update the document property to point to
        the newly created one.

LayoutTests:

        Reviewed by Geoff.

        Tests for <rdar://problem/5499125>
        REGRESSION (r21359-21368): After launching Kidzui beta, a webview frame fails to appear in its main window

        * fast/dom/Window/window-early-properties-expected.txt: Added.
        * fast/dom/Window/window-early-properties.html: Added.
        * http/tests/security/resources/has-custom-property.html: Added.
        * http/tests/security/resources/no-custom-property.html: Added.
        * http/tests/security/window-properties-clear-domain-expected.txt: Added.
        * http/tests/security/window-properties-clear-domain.html: Added.
        * http/tests/security/window-properties-clear-port-expected.txt: Added.
        * http/tests/security/window-properties-clear-port.html: Added.
        * http/tests/security/window-properties-pass-expected.txt: Added.
        * http/tests/security/window-properties-pass.html: Added.

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

18 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/dom/Window/window-early-properties-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/Window/window-early-properties.html [new file with mode: 0644]
LayoutTests/http/tests/security/resources/has-custom-property.html [new file with mode: 0644]
LayoutTests/http/tests/security/resources/no-custom-property.html [new file with mode: 0644]
LayoutTests/http/tests/security/window-properties-clear-domain-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/window-properties-clear-domain.html [new file with mode: 0644]
LayoutTests/http/tests/security/window-properties-clear-port-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/window-properties-clear-port.html [new file with mode: 0644]
LayoutTests/http/tests/security/window-properties-pass-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/window-properties-pass.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/WebCore.exp
WebCore/bindings/js/kjs_proxy.cpp
WebCore/bindings/js/kjs_proxy.h
WebCore/loader/FrameLoader.cpp
WebCore/loader/FrameLoader.h
WebCore/page/Frame.cpp

index a550a8155460c950407107502bbcd6bd8da02150..7dff558042717dbf04566aa73962cc6ca81e0ea6 100644 (file)
@@ -1,3 +1,21 @@
+2007-09-27  Antti Koivisto  <antti@apple.com>
+
+        Reviewed by Geoff.
+        
+        Tests for <rdar://problem/5499125>
+        REGRESSION (r21359-21368): After launching Kidzui beta, a webview frame fails to appear in its main window
+
+        * fast/dom/Window/window-early-properties-expected.txt: Added.
+        * fast/dom/Window/window-early-properties.html: Added.
+        * http/tests/security/resources/has-custom-property.html: Added.
+        * http/tests/security/resources/no-custom-property.html: Added.
+        * http/tests/security/window-properties-clear-domain-expected.txt: Added.
+        * http/tests/security/window-properties-clear-domain.html: Added.
+        * http/tests/security/window-properties-clear-port-expected.txt: Added.
+        * http/tests/security/window-properties-clear-port.html: Added.
+        * http/tests/security/window-properties-pass-expected.txt: Added.
+        * http/tests/security/window-properties-pass.html: Added.
+
 2007-09-26  Adam Roben  <aroben@apple.com>
 
         Remove a test that was probably only intermittently failing
diff --git a/LayoutTests/fast/dom/Window/window-early-properties-expected.txt b/LayoutTests/fast/dom/Window/window-early-properties-expected.txt
new file mode 100644 (file)
index 0000000..4835135
--- /dev/null
@@ -0,0 +1,4 @@
+Test setting window properties right after window.open()
+window retains early properties: PASS
+document does not retain early properties: PASS
+
diff --git a/LayoutTests/fast/dom/Window/window-early-properties.html b/LayoutTests/fast/dom/Window/window-early-properties.html
new file mode 100644 (file)
index 0000000..6a061cb
--- /dev/null
@@ -0,0 +1,31 @@
+<html>
+<head>
+<script>
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.setCanOpenWindows();
+    layoutTestController.waitUntilDone();
+}
+var w;
+function test()
+{
+    w = window.open("data:text/html,HelloWorld!");
+    w.myProp = "1";
+    w.document.myProp = "2";
+    setTimeout(test2, 10);
+}
+
+function test2()
+{
+    var c = document.getElementById('console');
+    c.innerHTML = "window retains early properties: " + ((w.myProp && w.myProp=='1') ? "PASS" : "FAIL") + "<br>";  
+    c.innerHTML +="document does not retain early properties: " + ((w.document.myProp) ? "FAIL" : "PASS") + "<br>";
+    w.close();
+    if (window.layoutTestController) 
+        layoutTestController.notifyDone();
+}
+</script>
+<body onload='test()'>
+Test setting window properties right after window.open()
+<div id=console>FAIL, test did not run</div>
+
diff --git a/LayoutTests/http/tests/security/resources/has-custom-property.html b/LayoutTests/http/tests/security/resources/has-custom-property.html
new file mode 100644 (file)
index 0000000..8ebf23d
--- /dev/null
@@ -0,0 +1,9 @@
+<script>
+if (window.myProp)
+    alert("PASS");
+else 
+    alert("FAIL, no myProp found");
+window.close();
+if (window.layoutTestController)
+    layoutTestController.notifyDone();
+</script>
diff --git a/LayoutTests/http/tests/security/resources/no-custom-property.html b/LayoutTests/http/tests/security/resources/no-custom-property.html
new file mode 100644 (file)
index 0000000..2af4128
--- /dev/null
@@ -0,0 +1,9 @@
+<script>
+if (window.myProp)
+    alert("FAIL, myProp found");
+else 
+    alert("PASS");
+window.close();
+if (window.layoutTestController)
+    layoutTestController.notifyDone();
+</script>
diff --git a/LayoutTests/http/tests/security/window-properties-clear-domain-expected.txt b/LayoutTests/http/tests/security/window-properties-clear-domain-expected.txt
new file mode 100644 (file)
index 0000000..78ab43f
--- /dev/null
@@ -0,0 +1,2 @@
+ALERT: PASS
+Test that window properties set for initial document are reset if domain security check fails
diff --git a/LayoutTests/http/tests/security/window-properties-clear-domain.html b/LayoutTests/http/tests/security/window-properties-clear-domain.html
new file mode 100644 (file)
index 0000000..df678f1
--- /dev/null
@@ -0,0 +1,19 @@
+<html>
+<head>
+<script>
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.setCanOpenWindows();
+    layoutTestController.waitUntilDone();
+}
+function test()
+{
+    var w = window.open("http://localhost:8000/security/resources/no-custom-property.html");
+    w.myProp = 1;
+}
+
+</script>
+<body onload='test()'>
+Test that window properties set for initial document are reset if domain security check fails 
+
+
diff --git a/LayoutTests/http/tests/security/window-properties-clear-port-expected.txt b/LayoutTests/http/tests/security/window-properties-clear-port-expected.txt
new file mode 100644 (file)
index 0000000..a5bc181
--- /dev/null
@@ -0,0 +1,2 @@
+ALERT: PASS
+Test that window properties set for initial document are reset if port security check fails
diff --git a/LayoutTests/http/tests/security/window-properties-clear-port.html b/LayoutTests/http/tests/security/window-properties-clear-port.html
new file mode 100644 (file)
index 0000000..38a5db6
--- /dev/null
@@ -0,0 +1,19 @@
+<html>
+<head>
+<script>
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.setCanOpenWindows();
+    layoutTestController.waitUntilDone();
+}
+function test()
+{
+    var w = window.open("http://localhost:8080/security/resources/no-custom-property.html");
+    w.myProp = 1;
+}
+
+</script>
+<body onload='test()'>
+Test that window properties set for initial document are reset if port security check fails 
+
+
diff --git a/LayoutTests/http/tests/security/window-properties-pass-expected.txt b/LayoutTests/http/tests/security/window-properties-pass-expected.txt
new file mode 100644 (file)
index 0000000..9207f90
--- /dev/null
@@ -0,0 +1,2 @@
+ALERT: PASS
+Test that window properties set for initial document are kept if security check passes
diff --git a/LayoutTests/http/tests/security/window-properties-pass.html b/LayoutTests/http/tests/security/window-properties-pass.html
new file mode 100644 (file)
index 0000000..7f23f53
--- /dev/null
@@ -0,0 +1,19 @@
+<html>
+<head>
+<script src='resources/cross-frame-access.js'></script>
+<script>
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.setCanOpenWindows();
+    layoutTestController.waitUntilDone();
+}
+function test()
+{
+    var w = window.open("http://127.0.0.1:8000/security/resources/has-custom-property.html");
+    w.myProp = 1;
+}
+
+</script>
+<body onload='test()'>
+Test that window properties set for initial document are kept if security check passes
+
index 2dc4afa9dddb33a9cfb8916b00f3914ab0d871dc..7fcb0bf3718e076df38f7546998c92bd4af61d72 100644 (file)
@@ -1,3 +1,40 @@
+2007-09-27  Antti Koivisto  <antti@apple.com>
+
+        Reviewed by Geoff.
+        
+        Fix for <rdar://problem/5499125>
+        REGRESSION (r21367): After launching Kidzui beta, a webview frame fails to appear in its main window
+        
+        If window object properties were modified when it had initial empty document (synchronously after 
+        window.open() for example) those modifications were lost when the real document was switched in.
+        
+        Match Firefox behavior where window properties are not cleared if the inital document and the loaded one
+        have matching security domains.
+
+        Tests: fast/dom/Window/window-early-properties.html
+               http/tests/security/window-properties-clear-domain.html
+               http/tests/security/window-properties-clear-port.html
+               http/tests/security/window-properties-pass.html
+
+        * WebCore.exp:
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::FrameLoader):
+        (WebCore::FrameLoader::init):
+        (WebCore::FrameLoader::clear):
+        (WebCore::FrameLoader::isSecureTransition):
+        (WebCore::FrameLoader::begin):
+        * loader/FrameLoader.h:
+        If we are transitioning from initial empty document to the final one, do a domain security check
+        between old security policy URL and new URL. If that passes don't clear script proxy and script objects.
+        
+        * bindings/js/kjs_proxy.cpp:
+        (WebCore::KJSProxy::updateDocumentWrapper):
+        * bindings/js/kjs_proxy.h:
+        * page/Frame.cpp:
+        (WebCore::Frame::setDocument):
+        Since we don't always clear window properties anymore, we need to update the document property to point to
+        the newly created one. 
+        
 2007-09-27  Kevin Decker  <kdecker@apple.com>
 
         Reviewed by Darin.
index f0be982b596de0a66cf4183745968e57eccc78b9..1bc6b07aea7afe157d82cb094c4feda97f0ac1f1 100644 (file)
@@ -168,7 +168,7 @@ __ZN7WebCore11FrameLoader4loadERKNS_15ResourceRequestERKNS_16NavigationActionENS
 __ZN7WebCore11FrameLoader4loadERKNS_15ResourceRequestERKNS_6StringE
 __ZN7WebCore11FrameLoader4loadERKNS_4KURLEPNS_5EventE
 __ZN7WebCore11FrameLoader4loadERKNS_4KURLERKNS_6StringENS_13FrameLoadTypeES6_PNS_5EventEN3WTF10PassRefPtrINS_9FormStateEEE
-__ZN7WebCore11FrameLoader5clearEb
+__ZN7WebCore11FrameLoader5clearEbb
 __ZN7WebCore11FrameLoader6reloadEv
 __ZN7WebCore11FrameLoader7canLoadERKNS_4KURLEPKNS_8DocumentE
 __ZN7WebCore11HistoryItem12addChildItemEN3WTF10PassRefPtrIS0_EE
index a7bf632dc54568d2e9d662c6060f68fab2ff171e..3edaf94309893424660fb144669a8b688d501432 100644 (file)
@@ -26,6 +26,7 @@
 #include "Frame.h"
 #include "FrameLoader.h"
 #include "GCController.h"
+#include "JSDocument.h"
 #include "JSDOMWindow.h"
 #include "Page.h"
 #include "kjs_events.h"
@@ -164,5 +165,14 @@ void KJSProxy::initScriptIfNeeded()
 
   m_frame->loader()->dispatchWindowObjectAvailable();
 }
+    
+void KJSProxy::updateDocumentWrapper() 
+{
+    if (!m_script || !m_frame->document())
+        return;
+    JSLock lock;
+    // this will update 'document' property to point to the current document
+    toJS(m_script->globalExec(), m_frame->document());
+}
 
 }
index d085e545967b24a96c86d743cb3a69ff1c615dab..91538cedb45b250757a01eeb8ad4df219df687d1 100644 (file)
@@ -54,6 +54,8 @@ public:
     void initScriptIfNeeded();
 
     bool haveInterpreter() const { return m_script; }
+    
+    void updateDocumentWrapper();
 
 private:
     RefPtr<KJS::ScriptInterpreter> m_script;
index eaac25b1af91d261bcca61d5884eb0310178a485..e58378d7a5345a3dbdd08d7b86dd73ec0b57f6dc 100644 (file)
@@ -236,6 +236,7 @@ FrameLoader::FrameLoader(Frame* frame, FrameLoaderClient* client)
     , m_opener(0)
     , m_openedByDOM(false)
     , m_creatingInitialEmptyDocument(false)
+    , m_isDisplayingInitialEmptyDocument(false)
     , m_committedFirstRealDocumentLoad(false)
     , m_didPerformFirstNavigation(false)
 #if USE(LOW_BANDWIDTH_DISPLAY)
@@ -260,6 +261,7 @@ FrameLoader::~FrameLoader()
 void FrameLoader::init()
 {
     // this somewhat odd set of steps is needed to give the frame an initial empty document
+    m_isDisplayingInitialEmptyDocument = false;
     m_creatingInitialEmptyDocument = true;
     setPolicyDocumentLoader(m_client->createDocumentLoader(ResourceRequest(String("")), SubstituteData()).get());
     setProvisionalDocumentLoader(m_policyDocumentLoader.get());
@@ -763,7 +765,7 @@ void FrameLoader::cancelAndClear()
     clear(false);
 }
 
-void FrameLoader::clear(bool clearWindowProperties)
+void FrameLoader::clear(bool clearWindowProperties, bool clearScriptObjects)
 {
     // FIXME: Commenting out the below line causes <http://bugs.webkit.org/show_bug.cgi?id=11212>, but putting it
     // back causes a measurable performance regression which we will need to fix to restore the correct behavior
@@ -800,7 +802,9 @@ void FrameLoader::clear(bool clearWindowProperties)
     m_decoder = 0;
 
     m_containsPlugIns = false;
-    m_frame->clearScriptObjects();
+    
+    if (clearScriptObjects)
+        m_frame->clearScriptObjects();
   
     m_redirectionTimer.stop();
     m_scheduledRedirection.clear();
@@ -809,6 +813,7 @@ void FrameLoader::clear(bool clearWindowProperties)
     m_checkLoadCompleteTimer.stop();
 
     m_receivedData = false;
+    m_isDisplayingInitialEmptyDocument = false;
 
     if (!m_encodingWasChosenByUser)
         m_encoding = String();
@@ -853,6 +858,21 @@ void FrameLoader::setResponseMIMEType(const String& type)
 {
     m_responseMIMEType = type;
 }
+    
+bool FrameLoader::isSecureTransition(const KURL& fromURL, const KURL& toURL)
+{ 
+    // new window created by the application
+    if (fromURL.isEmpty())
+        return true;
+    
+    if (fromURL.isLocalFile())
+        return true;
+    
+    if (equalIgnoringCase(fromURL.host(), toURL.host()) && equalIgnoringCase(fromURL.protocol(), toURL.protocol()) && fromURL.port() == toURL.port())
+        return true;
+    
+    return false;
+}
 
 void FrameLoader::begin()
 {
@@ -861,7 +881,9 @@ void FrameLoader::begin()
 
 void FrameLoader::begin(const KURL& url, bool dispatch)
 {
-    clear();
+    bool resetScripting = !(m_isDisplayingInitialEmptyDocument && m_frame->document() 
+                            && isSecureTransition(m_frame->document()->securityPolicyURL(), url));
+    clear(resetScripting, resetScripting);
     if (dispatch)
         dispatchWindowObjectAvailable();
 
@@ -869,6 +891,7 @@ void FrameLoader::begin(const KURL& url, bool dispatch)
     m_isComplete = false;
     m_didCallImplicitClose = false;
     m_isLoadingMainResource = true;
+    m_isDisplayingInitialEmptyDocument = m_creatingInitialEmptyDocument;
 
     KURL ref(url);
     ref.setUser(DeprecatedString());
index 2690f30b88aea09298dff1cb5e14f7a8e8ab1d66..0e602ff4662df67b1e39e02b741c007ecf92188e 100644 (file)
@@ -531,7 +531,7 @@ namespace WebCore {
         void opened();
         void updateHistoryAfterClientRedirect();
 
-        void clear(bool clearWindowProperties = true);
+        void clear(bool clearWindowProperties = true, bool clearScriptObjects = true);
 
         bool shouldReloadToHandleUnreachableURL(DocumentLoader*);
         void handleUnimplementablePolicy(const ResourceError&);
@@ -545,6 +545,8 @@ namespace WebCore {
         void stopRedirectionTimer();
 
         void startIconLoader();
+        
+        bool isSecureTransition(const KURL& fromURL, const KURL& toURL);
 
 #if USE(LOW_BANDWIDTH_DISPLAY)
         // implementation of CachedResourceClient        
@@ -636,6 +638,7 @@ namespace WebCore {
         bool m_openedByDOM;
 
         bool m_creatingInitialEmptyDocument;
+        bool m_isDisplayingInitialEmptyDocument;
         bool m_committedFirstRealDocumentLoad;
 
         RefPtr<HistoryItem> m_currentHistoryItem;
index b4c9e2b0bda72f384479085e19f7dfb0940d836e..f300998a0c19c71319fef0b8b745cb7b6faa8b1c 100644 (file)
@@ -279,6 +279,9 @@ void Frame::setDocument(PassRefPtr<Document> newDoc)
         
     if (d->m_doc && !d->m_doc->attached())
         d->m_doc->attach();
+    
+    if (d->m_jscript && d->m_doc)
+        d->m_jscript->updateDocumentWrapper();
 }
 
 Settings* Frame::settings() const