diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog index 518b09269b09c555ab2dcd1a4fc447edcc372b5b..f3aca26860d8e736d25316cdef4cd756edf925fe 100644 --- a/LayoutTests/ChangeLog +++ b/LayoutTests/ChangeLog @@ -1,3 +1,14 @@ +2008-05-13 Anders Carlsson + + Reviewed by Darin. + + Add testcase. + + * http/tests/appcache/navigating-away-while-cache-attempt-in-progress-expected.txt: Added. + * http/tests/appcache/navigating-away-while-cache-attempt-in-progress.html: Added. + * http/tests/appcache/resources/navigating-away-while-cache-attempt-in-progress.manifest: Added. + * http/tests/appcache/resources/slow-resource.php: Added. + 2008-05-13 Alexey Proskuryakov Reviewed by Darin. diff --git a/LayoutTests/http/tests/appcache/navigating-away-while-cache-attempt-in-progress-expected.txt b/LayoutTests/http/tests/appcache/navigating-away-while-cache-attempt-in-progress-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..ca09f7eaceb4af9b5bc2baedecbd2b6b9a6fada8 --- /dev/null +++ b/LayoutTests/http/tests/appcache/navigating-away-while-cache-attempt-in-progress-expected.txt @@ -0,0 +1,2 @@ +This tests that navigating away while a cache is loading does not crash. +SUCCESS - did not crash diff --git a/LayoutTests/http/tests/appcache/navigating-away-while-cache-attempt-in-progress.html b/LayoutTests/http/tests/appcache/navigating-away-while-cache-attempt-in-progress.html new file mode 100644 index 0000000000000000000000000000000000000000..451133f2210b53261c482aa3c6cb38e833c506cb --- /dev/null +++ b/LayoutTests/http/tests/appcache/navigating-away-while-cache-attempt-in-progress.html @@ -0,0 +1,21 @@ + + + +
This tests that navigating away while a cache is loading does not crash.
+
SUCCESS - did not crash
+ diff --git a/LayoutTests/http/tests/appcache/resources/navigating-away-while-cache-attempt-in-progress.manifest b/LayoutTests/http/tests/appcache/resources/navigating-away-while-cache-attempt-in-progress.manifest new file mode 100644 index 0000000000000000000000000000000000000000..10f6ddb74c96e3d61fbbfd01ced6a2690b2aadaf --- /dev/null +++ b/LayoutTests/http/tests/appcache/resources/navigating-away-while-cache-attempt-in-progress.manifest @@ -0,0 +1,2 @@ +CACHE MANIFEST +slow-resource.php diff --git a/LayoutTests/http/tests/appcache/resources/slow-resource.php b/LayoutTests/http/tests/appcache/resources/slow-resource.php new file mode 100644 index 0000000000000000000000000000000000000000..b720ba1a60ca328779a0b9de10fc34974a9dcb66 --- /dev/null +++ b/LayoutTests/http/tests/appcache/resources/slow-resource.php @@ -0,0 +1,3 @@ + diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog index 5d38afd58223b3dfcec10e7084684e63185bac95..7b729a952dc0413d18d4feca785d6a957fa741a4 100644 --- a/WebCore/ChangeLog +++ b/WebCore/ChangeLog @@ -1,3 +1,22 @@ +2008-05-13 Anders Carlsson + + Reviewed by Darin. + + Don't crash when a document loader is destroyed while an initial caching attempt + is in progress. + + * loader/appcache/ApplicationCacheGroup.cpp: + (WebCore::ApplicationCacheGroup::~ApplicationCacheGroup): + Stop loading. + + (WebCore::ApplicationCacheGroup::stopLoading): + New method that stops a cache update. + + (WebCore::ApplicationCacheGroup::documentLoaderDestroyed): + Delete ourselves here. + + * loader/appcache/ApplicationCacheGroup.h: + 2008-05-13 Alexey Proskuryakov Reviewed by Darin. diff --git a/WebCore/loader/appcache/ApplicationCacheGroup.cpp b/WebCore/loader/appcache/ApplicationCacheGroup.cpp index 14bb969fa78a7b85960add0a3d8cc02281386cf7..e990caf49db01900d3770c60c8001eddf5e55144 100644 --- a/WebCore/loader/appcache/ApplicationCacheGroup.cpp +++ b/WebCore/loader/appcache/ApplicationCacheGroup.cpp @@ -58,6 +58,9 @@ ApplicationCacheGroup::~ApplicationCacheGroup() ASSERT(!m_newestCache); ASSERT(m_caches.isEmpty()); + if (m_cacheBeingUpdated) + stopLoading(); + cacheStorage().cacheGroupDestroyed(this); } @@ -220,6 +223,29 @@ void ApplicationCacheGroup::finishedLoadingMainResource(DocumentLoader* loader) checkIfLoadIsComplete(); } +void ApplicationCacheGroup::stopLoading() +{ + ASSERT(m_cacheBeingUpdated); + + if (m_manifestHandle) { + ASSERT(!m_currentHandle); + + m_manifestHandle->setClient(0); + m_manifestHandle->cancel(); + m_manifestHandle = 0; + } + + if (m_currentHandle) { + ASSERT(!m_manifestHandle); + + m_currentHandle->setClient(0); + m_currentHandle->cancel(); + m_currentHandle = 0; + } + + m_cacheBeingUpdated = 0; +} + void ApplicationCacheGroup::documentLoaderDestroyed(DocumentLoader* loader) { HashSet::iterator it = m_associatedDocumentLoaders.find(loader); @@ -233,9 +259,14 @@ void ApplicationCacheGroup::documentLoaderDestroyed(DocumentLoader* loader) m_cacheCandidates.remove(loader); } - if (m_associatedDocumentLoaders.isEmpty() && m_cacheCandidates.isEmpty()) { - // We should only have the newest cache remaining. - ASSERT(m_caches.size() == 1); + if (!m_associatedDocumentLoaders.isEmpty() || !m_cacheCandidates.isEmpty()) + return; + + // We should only have the newest cache remaining, or there is an initial cache attempt in progress. + ASSERT(m_caches.size() == 1 || m_cacheBeingUpdated); + + // If a cache update is in progress, stop it. + if (m_caches.size() == 1) { ASSERT(m_caches.contains(m_newestCache.get())); // Release our reference to the newest cache. @@ -243,7 +274,16 @@ void ApplicationCacheGroup::documentLoaderDestroyed(DocumentLoader* loader) // This could cause us to be deleted. m_newestCache = 0; - } + + return; + } + + // There is an initial cache attempt in progress + ASSERT(m_cacheBeingUpdated); + ASSERT(m_caches.size() == 0); + + // Delete ourselves, causing the cache attempt to be stopped. + delete this; } void ApplicationCacheGroup::cacheDestroyed(ApplicationCache* cache) diff --git a/WebCore/loader/appcache/ApplicationCacheGroup.h b/WebCore/loader/appcache/ApplicationCacheGroup.h index fb60dca84c05ddbbcf7cef91f159db37c1bd83f8..40d3ab80915087554aa15cf7c6bf94c5f193a7bc 100644 --- a/WebCore/loader/appcache/ApplicationCacheGroup.h +++ b/WebCore/loader/appcache/ApplicationCacheGroup.h @@ -99,6 +99,8 @@ private: void associateDocumentLoaderWithCache(DocumentLoader*, ApplicationCache*); + void stopLoading(); + KURL m_manifestURL; Status m_status;