diff --git a/docshell/base/crashtests/436900-1-inner.html b/docshell/base/crashtests/436900-1-inner.html new file mode 100644 index 00000000000..6fe35ccb1a7 --- /dev/null +++ b/docshell/base/crashtests/436900-1-inner.html @@ -0,0 +1,21 @@ + + + + + + + + + + + + diff --git a/docshell/base/crashtests/436900-1.html b/docshell/base/crashtests/436900-1.html new file mode 100644 index 00000000000..582d1919d12 --- /dev/null +++ b/docshell/base/crashtests/436900-1.html @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/docshell/base/crashtests/crashtests.list b/docshell/base/crashtests/crashtests.list index 23ab439ff78..a7d1b5f706b 100644 --- a/docshell/base/crashtests/crashtests.list +++ b/docshell/base/crashtests/crashtests.list @@ -1,2 +1,3 @@ load 369126-1.html load 403574-1.xhtml +load 436900-1.html diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index fe3bebbe9fd..1a7921f3e0a 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -4435,6 +4435,31 @@ nsDocShell::RefreshURI(nsIURI * aURI, PRInt32 aDelay, PRBool aRepeat, return NS_OK; } +nsresult +nsDocShell::ForceRefreshURIFromTimer(nsIURI * aURI, + PRInt32 aDelay, + PRBool aMetaRefresh, + nsITimer* aTimer) +{ + NS_PRECONDITION(aTimer, "Must have a timer here"); + + // Remove aTimer from mRefreshURIList if needed + if (mRefreshURIList) { + PRUint32 n = 0; + mRefreshURIList->Count(&n); + + for (PRUint32 i = 0; i < n; ++i) { + nsCOMPtr timer = do_QueryElementAt(mRefreshURIList, i); + if (timer == aTimer) { + mRefreshURIList->RemoveElementAt(i); + break; + } + } + } + + return ForceRefreshURI(aURI, aDelay, aMetaRefresh); +} + NS_IMETHODIMP nsDocShell::ForceRefreshURI(nsIURI * aURI, PRInt32 aDelay, @@ -9303,9 +9328,7 @@ nsRefreshTimer::Notify(nsITimer * aTimer) // Get the delay count to determine load type PRUint32 delay = 0; aTimer->GetDelay(&delay); - nsCOMPtr refreshURI = do_QueryInterface(mDocShell); - if (refreshURI) - refreshURI->ForceRefreshURI(mURI, delay, mMetaRefresh); + mDocShell->ForceRefreshURIFromTimer(mURI, delay, mMetaRefresh, aTimer); } return NS_OK; } diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index af26a537473..13fe8446cc0 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -109,6 +109,7 @@ #include "nsIChannelClassifier.h" class nsIScrollableView; +class nsDocShell; /* load commands were moved to nsIDocShell.h */ /* load types were moved to nsDocShellLoadTypes.h */ @@ -133,7 +134,7 @@ public: PRInt32 GetDelay() { return mDelay ;} - nsCOMPtr mDocShell; + nsRefPtr mDocShell; nsCOMPtr mURI; PRInt32 mDelay; PRPackedBool mRepeat; @@ -235,6 +236,13 @@ public: // subframes. It then simulates the completion of the toplevel load. nsresult RestoreFromHistory(); + // Perform a URI load from a refresh timer. This is just like the + // ForceRefreshURI method on nsIRefreshURI, but makes sure to take + // the timer involved out of mRefreshURIList if it's there. + // aTimer must not be null. + nsresult ForceRefreshURIFromTimer(nsIURI * aURI, PRInt32 aDelay, + PRBool aMetaRefresh, nsITimer* aTimer); + protected: // Object Management virtual ~nsDocShell();