LayoutTests:
authorandersca <andersca@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 8 Dec 2006 00:54:15 +0000 (00:54 +0000)
committerandersca <andersca@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 8 Dec 2006 00:54:15 +0000 (00:54 +0000)
        Reviewed by Darin.

        <rdar://problem/4838778>
        DashboardClient crashing in WebCore::SubresourceLoader::didFail.

        * http/tests/xmlhttprequest/abort-crash-expected.txt: Added.
        * http/tests/xmlhttprequest/abort-crash.html: Added.
        * http/tests/xmlhttprequest/hello-world.cgi: Added.

WebCore:

        Reviewed by Darin.

        <rdar://problem/4838778>
        Title: DashboardClient crashing in WebCore::SubresourceLoader::didFail

        * loader/SubresourceLoader.cpp:
        (WebCore::SubresourceLoader::stopLoading):
        * loader/SubresourceLoader.h:
        Add stopLoading method which currently just clears the client. This isn't the ideal fix,
        since it doesn't actually stop the load.

        * loader/mac/SubresourceLoaderMac.mm:
        (WebCore::SubresourceLoader::willSendRequest):
        (WebCore::SubresourceLoader::didReceiveResponse):
        (WebCore::SubresourceLoader::didReceiveData):
        (WebCore::SubresourceLoader::didFinishLoading):
        (WebCore::SubresourceLoader::didFail):
        (WebCore::SubresourceLoader::didCancel):
        Add null-checks.

        * xml/xmlhttprequest.cpp:
        (WebCore::XMLHttpRequest::abort):
        Call stopLoading.

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

LayoutTests/ChangeLog
LayoutTests/http/tests/xmlhttprequest/abort-crash-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/xmlhttprequest/abort-crash.html [new file with mode: 0644]
LayoutTests/http/tests/xmlhttprequest/hello-world.cgi [new file with mode: 0755]
WebCore/ChangeLog
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/loader/SubresourceLoader.cpp
WebCore/loader/SubresourceLoader.h
WebCore/loader/mac/SubresourceLoaderMac.mm
WebCore/xml/xmlhttprequest.cpp

index c6b720815576cce143945a5807478be395728361..8bd9730d5e3c202d7e8989969e6bf1e097098ee8 100644 (file)
@@ -1,3 +1,14 @@
+2006-12-07  Anders Carlsson  <acarlsson@apple.com>
+
+        Reviewed by Darin.
+
+        <rdar://problem/4838778>
+        DashboardClient crashing in WebCore::SubresourceLoader::didFail.
+        
+        * http/tests/xmlhttprequest/abort-crash-expected.txt: Added.
+        * http/tests/xmlhttprequest/abort-crash.html: Added.
+        * http/tests/xmlhttprequest/hello-world.cgi: Added.
+
 2006-12-07  Kirby White  <KWhiteRight@gmail.com>
 
         Reviewed by Adele.
diff --git a/LayoutTests/http/tests/xmlhttprequest/abort-crash-expected.txt b/LayoutTests/http/tests/xmlhttprequest/abort-crash-expected.txt
new file mode 100644 (file)
index 0000000..c286d80
--- /dev/null
@@ -0,0 +1 @@
+This tests that aborting and then garbage collecting an XMLHttpRequest does not cause a crash. SUCCESS! Didn't crash.
diff --git a/LayoutTests/http/tests/xmlhttprequest/abort-crash.html b/LayoutTests/http/tests/xmlhttprequest/abort-crash.html
new file mode 100644 (file)
index 0000000..2db7e74
--- /dev/null
@@ -0,0 +1,39 @@
+<html>
+<head>
+<script>
+    
+function f() {
+    var req = new XMLHttpRequest();
+    req.open("GET", "hello-world.cgi"); 
+    req.setRequestHeader("Cache-Control", "no-cache");
+    req.send(null);  
+    req.abort();
+}
+
+function runTest() {
+    if (window.layoutTestController) {
+        layoutTestController.waitUntilDone();
+        layoutTestController.dumpAsText();
+    }
+    
+    f();
+    
+    // create lots of objects to force a garbage collection
+    var i = 0;
+    var s;
+    while (i < 5000) {
+        i = i+1.11;
+        s = s + " ";
+    }
+     
+     // Add a small timeout to give the callbacks a chance to fire
+     if (window.layoutTestController)
+        setTimeout("layoutTestController.notifyDone()", 100)
+}         
+</script>
+</head>
+<body onload="runTest()">
+    This tests that aborting and then garbage collecting an XMLHttpRequest does not cause a crash.
+    SUCCESS! Didn't crash.
+</body>
+</html>
diff --git a/LayoutTests/http/tests/xmlhttprequest/hello-world.cgi b/LayoutTests/http/tests/xmlhttprequest/hello-world.cgi
new file mode 100755 (executable)
index 0000000..fcd0f20
--- /dev/null
@@ -0,0 +1,4 @@
+#!/usr/bin/perl -w
+
+print "Content-type: text/plain\n\n";
+print "Hello World!";
\ No newline at end of file
index cb75842489306118d2fdc3b868d9be741ec2faf9..83928cef74d9db2d11d117000f2194bcb7a47ab6 100644 (file)
@@ -1,3 +1,29 @@
+2006-12-07  Anders Carlsson  <acarlsson@apple.com>
+
+        Reviewed by Darin.
+
+        <rdar://problem/4838778>
+        Title: DashboardClient crashing in WebCore::SubresourceLoader::didFail
+        
+        * loader/SubresourceLoader.cpp:
+        (WebCore::SubresourceLoader::stopLoading):
+        * loader/SubresourceLoader.h:
+        Add stopLoading method which currently just clears the client. This isn't the ideal fix,
+        since it doesn't actually stop the load.
+        
+        * loader/mac/SubresourceLoaderMac.mm:
+        (WebCore::SubresourceLoader::willSendRequest):
+        (WebCore::SubresourceLoader::didReceiveResponse):
+        (WebCore::SubresourceLoader::didReceiveData):
+        (WebCore::SubresourceLoader::didFinishLoading):
+        (WebCore::SubresourceLoader::didFail):
+        (WebCore::SubresourceLoader::didCancel):
+        Add null-checks.
+        
+        * xml/xmlhttprequest.cpp:
+        (WebCore::XMLHttpRequest::abort):
+        Call stopLoading.
+
 2006-12-07  Kevin McCullough  <kmccullough@apple.com>
 
         Reviewed by Geof.
index 928f04b4bb05e5572e0f3da42ae2f09e1823b333..f97505c1ea94e06c9d4e15e48d19d3c43957e9be 100644 (file)
                        );
                        inputPaths = (
                                "$(SRCROOT)/WebCore.exp",
-                               "$(SRCROOT)/WebCore.LP64.exp"
+                               "$(SRCROOT)/WebCore.LP64.exp",
                        );
                        name = "Generate 64-bit Export File";
                        outputPaths = (
index b28b08aa7ee0aade83d5add9102bbbc8077e9722..53ebf8f31f05b02a64a4c3613d09bde721801d15 100644 (file)
 
 namespace WebCore {
 
+void SubresourceLoader::stopLoading()
+{
+    // FIXME: This should stop loading for real and not just clear the client.
+    m_client = 0;
+}
+    
 #if !PLATFORM(MAC)
 
 SubresourceLoader::SubresourceLoader(Frame* frame, SubresourceLoaderClient* client)
index c780f1ac90a9dbb85e6e5fdac8aadf913300e927..346fa9708aa5a468218cb62b9fd64fcaf42bb8f6 100644 (file)
@@ -53,6 +53,8 @@ namespace WebCore {
         
         virtual ~SubresourceLoader();
 
+        void stopLoading();
+        
 #if PLATFORM(MAC)
         // FIXME: These should go away once ResourceLoader uses ResourceHandle.
         virtual bool load(NSURLRequest *);
index 580f848b22978765d3e3c040346a18c7c3b64ca7..61790dc0d017e1e45bb1215c2a4bf31be2d1a999 100644 (file)
@@ -156,7 +156,8 @@ NSURLRequest *SubresourceLoader::willSendRequest(NSURLRequest *newRequest, NSURL
     NSURLRequest *clientRequest = ResourceLoader::willSendRequest(newRequest, redirectResponse);
     if (clientRequest && oldURL != [clientRequest URL] && ![oldURL isEqual:[clientRequest URL]]) {
         ResourceRequest request = newRequest;
-        m_client->willSendRequest(this, request, redirectResponse);
+        if (m_client)
+            m_client->willSendRequest(this, request, redirectResponse);
         
         return request.nsURLRequest();
     }
@@ -175,7 +176,8 @@ void SubresourceLoader::didReceiveResponse(NSURLResponse *r)
     // anything including removing the last reference to this object; one example of this is 3266216.
     RefPtr<SubresourceLoader> protect(this);
 
-    m_client->didReceiveResponse(this, r);
+    if (m_client)
+        m_client->didReceiveResponse(this, r);
     
     // The loader can cancel a load if it receives a multipart response for a non-image
     if (reachedTerminalState())
@@ -186,7 +188,8 @@ void SubresourceLoader::didReceiveResponse(NSURLResponse *r)
         // Since a subresource loader does not load multipart sections progressively,
         // deliver the previously received data to the loader all at once now.
         // Then clear the data to make way for the next multipart section.
-        m_client->didReceiveData(this, (const char*)[resourceData() bytes], [resourceData() length]);
+        if (m_client)
+            m_client->didReceiveData(this, (const char*)[resourceData() bytes], [resourceData() length]);
         clearResourceData();
         
         // After the first multipart section is complete, signal to delegates that this load is "finished" 
@@ -202,7 +205,7 @@ void SubresourceLoader::didReceiveData(NSData *data, long long lengthReceived, b
 
     // A subresource loader does not load multipart sections progressively.
     // So don't deliver any data to the loader yet.
-    if (!m_loadingMultipartContent)
+    if (!m_loadingMultipartContent && m_client)
         m_client->didReceiveData(this, (const char*)[data bytes], [data length]);
 
     ResourceLoader::didReceiveData(data, lengthReceived, allAtOnce);
@@ -217,8 +220,10 @@ void SubresourceLoader::didFinishLoading()
     // Calling removeSubresourceLoader will likely result in a call to deref, so we must protect ourselves.
     RefPtr<SubresourceLoader> protect(this);
 
-    m_client->receivedAllData(this, resourceData());
-    m_client->didFinishLoading(this);
+    if (m_client) {
+        m_client->receivedAllData(this, resourceData());
+        m_client->didFinishLoading(this);
+    }
     
     m_handle = 0;
 
@@ -237,7 +242,8 @@ void SubresourceLoader::didFail(NSError *error)
     // Calling removeSubresourceLoader will likely result in a call to deref, so we must protect ourselves.
     RefPtr<SubresourceLoader> protect(this);
 
-    m_client->didFail(this, error);
+    if (m_client)
+        m_client->didFail(this, error);
     
     m_handle = 0;
     
@@ -254,7 +260,8 @@ void SubresourceLoader::didCancel(NSError *error)
     // Calling removeSubresourceLoader will likely result in a call to deref, so we must protect ourselves.
     RefPtr<SubresourceLoader> protect(this);
 
-    m_client->didFail(this, error);
+    if (m_client)
+        m_client->didFail(this, error);
     
     // FIXME: Once ResourceLoader uses ResourceHandle, this should be done in ResourceLoader::didCancel.
     m_handle->cancel();
index c040267e751cbe99c6771bf4ddad0e735d58801c..1cf1fcd0809e00df69fec79dce49d11e03653c25 100644 (file)
@@ -365,8 +365,10 @@ void XMLHttpRequest::abort()
 {
     bool hadLoader = m_loader;
 
-    if (hadLoader)
+    if (hadLoader) {
+        m_loader->stopLoading();
         m_loader = 0;
+    }
 
     m_decoder = 0;
     m_aborted = true;