Fixing bug 131841. Don't make calls on weak XPCOM (nsIPresShell in this case) pointers since the objects might go away during the call, this lead to a crash in this particular case. r=sicking@bigfoot.com, sr=vidur@netscape.com, brendan@mozilla.org

This commit is contained in:
jst%netscape.com 2002-05-18 00:02:50 +00:00
parent 4ec7e2797f
commit c68cadcb79
4 changed files with 105 additions and 74 deletions

View File

@ -755,7 +755,8 @@ nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup)
PRInt32 pscount = mPresShells.Count();
PRInt32 psindex;
for (psindex = 0; psindex < pscount; psindex++) {
nsIPresShell* shell = (nsIPresShell*)mPresShells.ElementAt(psindex);
nsCOMPtr<nsIPresShell> shell =
(nsIPresShell*)mPresShells.ElementAt(psindex);
nsCOMPtr<nsIStyleSet> set;
if (NS_SUCCEEDED(shell->GetStyleSet(getter_AddRefs(set)))) {
if (set) {
@ -1450,7 +1451,7 @@ void nsDocument::AddStyleSheetToStyleSets(nsIStyleSheet* aSheet)
PRInt32 count = mPresShells.Count();
PRInt32 indx;
for (indx = 0; indx < count; indx++) {
nsIPresShell* shell = (nsIPresShell*)mPresShells.ElementAt(indx);
nsCOMPtr<nsIPresShell> shell = (nsIPresShell*)mPresShells.ElementAt(indx);
nsCOMPtr<nsIStyleSet> set;
if (NS_SUCCEEDED(shell->GetStyleSet(getter_AddRefs(set)))) {
if (set) {
@ -1490,7 +1491,7 @@ void nsDocument::RemoveStyleSheetFromStyleSets(nsIStyleSheet* aSheet)
PRInt32 count = mPresShells.Count();
PRInt32 indx;
for (indx = 0; indx < count; indx++) {
nsIPresShell* shell = (nsIPresShell*)mPresShells.ElementAt(indx);
nsCOMPtr<nsIPresShell> shell = (nsIPresShell*)mPresShells.ElementAt(indx);
nsCOMPtr<nsIStyleSet> set;
if (NS_SUCCEEDED(shell->GetStyleSet(getter_AddRefs(set)))) {
if (set) {
@ -1615,7 +1616,8 @@ nsDocument::InsertStyleSheetAt(nsIStyleSheet* aSheet, PRInt32 aIndex, PRBool aNo
if (enabled) {
count = mPresShells.Count();
for (indx = 0; indx < count; indx++) {
nsIPresShell* shell = (nsIPresShell*)mPresShells.ElementAt(indx);
nsCOMPtr<nsIPresShell> shell =
(nsIPresShell*)mPresShells.ElementAt(indx);
nsCOMPtr<nsIStyleSet> set;
shell->GetStyleSet(getter_AddRefs(set));
if (set) {
@ -1647,7 +1649,8 @@ void nsDocument::SetStyleSheetDisabledState(nsIStyleSheet* aSheet,
if (-1 != indx) {
count = mPresShells.Count();
for (indx = 0; indx < count; indx++) {
nsIPresShell* shell = (nsIPresShell*)mPresShells.ElementAt(indx);
nsCOMPtr<nsIPresShell> shell =
(nsIPresShell*)mPresShells.ElementAt(indx);
nsCOMPtr<nsIStyleSet> set;
if (NS_SUCCEEDED(shell->GetStyleSet(getter_AddRefs(set)))) {
if (set) {
@ -1709,8 +1712,9 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject)
// PresShell owns us -- it's tidy.)
PRInt32 count;
for (count = mPresShells.Count() - 1; count >= 0; --count) {
nsIPresShell* shell = NS_STATIC_CAST(nsIPresShell*, mPresShells[count]);
if (! shell)
nsCOMPtr<nsIPresShell> shell =
NS_STATIC_CAST(nsIPresShell*, mPresShells[count]);
if (!shell)
continue;
shell->ReleaseAnonymousContent();
@ -2709,8 +2713,8 @@ nsDocument::GetDefaultView(nsIDOMAbstractView** aDefaultView)
*aDefaultView = nsnull;
NS_ENSURE_TRUE(mPresShells.Count() != 0, NS_OK);
nsIPresShell *shell = NS_STATIC_CAST(nsIPresShell *,
mPresShells.ElementAt(0));
nsCOMPtr<nsIPresShell> shell = NS_STATIC_CAST(nsIPresShell *,
mPresShells.ElementAt(0));
NS_ENSURE_TRUE(shell, NS_OK);
nsCOMPtr<nsIPresContext> ctx;
@ -2761,7 +2765,8 @@ NS_IMETHODIMP
nsDocument::SetTitle(const nsAString& aTitle)
{
for (PRInt32 i = mPresShells.Count() - 1; i >= 0; --i) {
nsIPresShell* shell = NS_STATIC_CAST(nsIPresShell*, mPresShells[i]);
nsCOMPtr<nsIPresShell> shell =
NS_STATIC_CAST(nsIPresShell*, mPresShells[i]);
nsCOMPtr<nsIPresContext> context;
nsresult rv = shell->GetPresContext(getter_AddRefs(context));
@ -2909,7 +2914,7 @@ NS_IMETHODIMP
nsDocument::GetDir(nsAString& aDirection)
{
#ifdef IBMBIDI
nsIPresShell* shell = (nsIPresShell*) mPresShells.SafeElementAt(0);
nsCOMPtr<nsIPresShell> shell = (nsIPresShell*)mPresShells.SafeElementAt(0);
if (shell) {
nsCOMPtr<nsIPresContext> context;
shell->GetPresContext(getter_AddRefs(context) );
@ -2940,7 +2945,7 @@ nsDocument::SetDir(const nsAString& aDirection)
{
#ifdef IBMBIDI
if (mPresShells.Count() != 0) {
nsIPresShell* shell = (nsIPresShell*) mPresShells.ElementAt(0);
nsCOMPtr<nsIPresShell> shell = (nsIPresShell*)mPresShells.ElementAt(0);
if (shell) {
nsCOMPtr<nsIPresContext> context;
shell->GetPresContext(getter_AddRefs(context) );
@ -3638,7 +3643,9 @@ nsDocument::FlushPendingNotifications(PRBool aFlushReflows,
PRInt32 i, count = mPresShells.Count();
for (i = 0; i < count; i++) {
nsIPresShell* shell = NS_STATIC_CAST(nsIPresShell*, mPresShells[i]);
nsCOMPtr<nsIPresShell> shell =
NS_STATIC_CAST(nsIPresShell*, mPresShells[i]);
if (shell) {
shell->FlushPendingNotifications(aUpdateViews);
}

View File

@ -1353,8 +1353,8 @@ nsHTMLDocument::SetDTDMode(nsDTDMode aMode)
if (mCSSLoader) {
mCSSLoader->SetQuirkMode(PRBool(eDTDMode_strict!= mDTDMode));
}
nsIPresShell* shell = (nsIPresShell*) mPresShells.SafeElementAt(0);
if (nsnull != shell) {
nsCOMPtr<nsIPresShell> shell = (nsIPresShell*)mPresShells.SafeElementAt(0);
if (shell) {
nsCOMPtr<nsIPresContext> pc;
shell->GetPresContext(getter_AddRefs(pc));
if (pc) {
@ -1523,7 +1523,9 @@ nsHTMLDocument::FlushPendingNotifications(PRBool aFlushReflows,
if (aFlushReflows) {
PRInt32 i = 0, n = mPresShells.Count();
while ((i < n) && (isSafeToFlush)) {
nsIPresShell* shell = NS_STATIC_CAST(nsIPresShell*, mPresShells[i]);
nsCOMPtr<nsIPresShell> shell =
NS_STATIC_CAST(nsIPresShell*, mPresShells[i]);
if (shell) {
shell->IsSafeToFlush(isSafeToFlush);
}
@ -2443,7 +2445,7 @@ nsHTMLDocument::OpenCommon(nsIURI* aSourceURL)
nsCOMPtr<nsIWebShell> webShell;
// Get the webshell of our primary presentation shell
nsIPresShell* shell = (nsIPresShell*) mPresShells.SafeElementAt(0);
nsCOMPtr<nsIPresShell> shell = (nsIPresShell*)mPresShells.SafeElementAt(0);
if (shell) {
nsCOMPtr<nsIPresContext> cx;
shell->GetPresContext(getter_AddRefs(cx));
@ -3253,7 +3255,7 @@ nsHTMLDocument::GetSelection(nsAString& aReturn)
consoleService->LogStringMessage(NS_LITERAL_STRING("Deprecated method document.getSelection() called. Please use window.getSelection() instead.").get());
}
nsIPresShell* shell = (nsIPresShell*)mPresShells.SafeElementAt(0);
nsCOMPtr<nsIPresShell> shell = (nsIPresShell*)mPresShells.SafeElementAt(0);
if (!shell) {
return NS_OK;

View File

@ -1334,7 +1334,7 @@ nsXULDocument::AddStyleSheetToStyleSets(nsIStyleSheet* aSheet)
PRInt32 count = mPresShells.Count();
PRInt32 indx;
for (indx = 0; indx < count; indx++) {
nsIPresShell* shell = (nsIPresShell*)mPresShells.ElementAt(indx);
nsCOMPtr<nsIPresShell> shell = (nsIPresShell*)mPresShells.ElementAt(indx);
nsCOMPtr<nsIStyleSet> set;
if (NS_SUCCEEDED(shell->GetStyleSet(getter_AddRefs(set)))) {
if (set) {
@ -1461,7 +1461,7 @@ nsXULDocument::RemoveStyleSheetFromStyleSets(nsIStyleSheet* aSheet)
PRInt32 count = mPresShells.Count();
PRInt32 indx;
for (indx = 0; indx < count; indx++) {
nsIPresShell* shell = (nsIPresShell*)mPresShells.ElementAt(indx);
nsCOMPtr<nsIPresShell> shell = (nsIPresShell*)mPresShells.ElementAt(indx);
nsCOMPtr<nsIStyleSet> set;
if (NS_SUCCEEDED(shell->GetStyleSet(getter_AddRefs(set)))) {
if (set) {
@ -1513,7 +1513,7 @@ nsXULDocument::InsertStyleSheetAt(nsIStyleSheet* aSheet, PRInt32 aIndex, PRBool
if (enabled) {
count = mPresShells.Count();
for (i = 0; i < count; i++) {
nsIPresShell* shell = (nsIPresShell*)mPresShells.ElementAt(i);
nsCOMPtr<nsIPresShell> shell = (nsIPresShell*)mPresShells.ElementAt(i);
nsCOMPtr<nsIStyleSet> set;
shell->GetStyleSet(getter_AddRefs(set));
if (set) {
@ -1544,7 +1544,9 @@ nsXULDocument::SetStyleSheetDisabledState(nsIStyleSheet* aSheet,
if (-1 != mStyleSheets.IndexOf((void *)aSheet)) {
count = mPresShells.Count();
for (i = 0; i < count; i++) {
nsIPresShell* shell = (nsIPresShell*)mPresShells.ElementAt(i);
nsCOMPtr<nsIPresShell> shell =
(nsIPresShell*)mPresShells.ElementAt(i);
nsCOMPtr<nsIStyleSet> set;
shell->GetStyleSet(getter_AddRefs(set));
if (set) {
@ -1633,8 +1635,10 @@ nsXULDocument::SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject)
// keeping the document alive. (While not strictly necessary
// -- the PresShell owns us -- it's tidy.)
for (PRInt32 count = mPresShells.Count() - 1; count >= 0; --count) {
nsIPresShell* shell = NS_STATIC_CAST(nsIPresShell*, mPresShells[count]);
if (! shell)
nsCOMPtr<nsIPresShell> shell =
NS_STATIC_CAST(nsIPresShell*, mPresShells[count]);
if (!shell)
continue;
shell->ReleaseAnonymousContent();
@ -2122,14 +2126,16 @@ nsXULDocument::ExecuteOnBroadcastHandlerFor(nsIContent* aBroadcaster,
PRInt32 j = mPresShells.Count();
while (--j >= 0) {
nsIPresShell* shell = NS_STATIC_CAST(nsIPresShell*, mPresShells[j]);
nsCOMPtr<nsIPresShell> shell =
NS_STATIC_CAST(nsIPresShell*, mPresShells[j]);
nsCOMPtr<nsIPresContext> aPresContext;
shell->GetPresContext(getter_AddRefs(aPresContext));
// Handle the DOM event
nsEventStatus status = nsEventStatus_eIgnore;
child->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
child->HandleDOMEvent(aPresContext, &event, nsnull,
NS_EVENT_FLAG_INIT, &status);
}
}
@ -2478,7 +2484,9 @@ nsXULDocument::FlushPendingNotifications(PRBool aFlushReflows, PRBool aUpdateVie
PRInt32 i, count = mPresShells.Count();
for (i = 0; i < count; i++) {
nsIPresShell* shell = NS_STATIC_CAST(nsIPresShell*, mPresShells[i]);
nsCOMPtr<nsIPresShell> shell =
NS_STATIC_CAST(nsIPresShell*, mPresShells[i]);
if (shell) {
shell->FlushPendingNotifications(aUpdateViews);
}
@ -3225,8 +3233,8 @@ nsXULDocument::GetDefaultView(nsIDOMAbstractView** aDefaultView)
NS_ENSURE_ARG_POINTER(aDefaultView);
*aDefaultView = nsnull;
nsIPresShell *shell = NS_STATIC_CAST(nsIPresShell *,
mPresShells.SafeElementAt(0));
nsCOMPtr<nsIPresShell> shell = NS_STATIC_CAST(nsIPresShell *,
mPresShells.SafeElementAt(0));
NS_ENSURE_TRUE(shell, NS_OK);
nsCOMPtr<nsIPresContext> ctx;
@ -3520,7 +3528,8 @@ NS_IMETHODIMP
nsXULDocument::SetTitle(const nsAString& aTitle)
{
for (PRInt32 i = mPresShells.Count() - 1; i >= 0; --i) {
nsIPresShell* shell = NS_STATIC_CAST(nsIPresShell*, mPresShells[i]);
nsCOMPtr<nsIPresShell> shell =
NS_STATIC_CAST(nsIPresShell*, mPresShells[i]);
nsCOMPtr<nsIPresContext> context;
nsresult rv = shell->GetPresContext(getter_AddRefs(context));

View File

@ -77,7 +77,7 @@ NS_IMETHODIMP
nsDOMWindowList::SetDocShell(nsIDocShell* aDocShell)
{
nsCOMPtr<nsIDocShellTreeNode> docShellAsNode(do_QueryInterface(aDocShell));
mDocShellNode = docShellAsNode.get(); // Weak Reference
mDocShellNode = docShellAsNode; // Weak Reference
return NS_OK;
}
@ -85,29 +85,34 @@ nsDOMWindowList::SetDocShell(nsIDocShell* aDocShell)
NS_IMETHODIMP
nsDOMWindowList::GetLength(PRUint32* aLength)
{
nsresult ret = NS_OK;
PRInt32 length;
nsresult rv = NS_OK;
*aLength = 0;
if (mDocShellNode) {
nsCOMPtr<nsIWebNavigation> shellAsNav = do_QueryInterface(mDocShellNode);
if (shellAsNav) {
nsCOMPtr<nsIDOMDocument> domdoc;
shellAsNav->GetDocument(getter_AddRefs(domdoc));
if (domdoc) {
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domdoc);
if (doc) {
doc->FlushPendingNotifications();
}
}
nsCOMPtr<nsIWebNavigation> shellAsNav(do_QueryInterface(mDocShellNode));
if (shellAsNav) {
nsCOMPtr<nsIDOMDocument> domdoc;
shellAsNav->GetDocument(getter_AddRefs(domdoc));
nsCOMPtr<nsIDocument> doc(do_QueryInterface(domdoc));
if (doc) {
doc->FlushPendingNotifications();
}
ret = mDocShellNode->GetChildCount(&length);
}
// The above flush might cause mDocShellNode to be cleared, so we
// need to check that it's still non-null here.
if (mDocShellNode) {
PRInt32 length;
rv = mDocShellNode->GetChildCount(&length);
*aLength = length;
}
return ret;
return rv;
}
NS_IMETHODIMP
@ -116,20 +121,24 @@ nsDOMWindowList::Item(PRUint32 aIndex, nsIDOMWindow** aReturn)
nsCOMPtr<nsIDocShellTreeItem> item;
*aReturn = nsnull;
if (mDocShellNode) {
nsCOMPtr<nsIWebNavigation> shellAsNav = do_QueryInterface(mDocShellNode);
if (shellAsNav) {
nsCOMPtr<nsIDOMDocument> domdoc;
shellAsNav->GetDocument(getter_AddRefs(domdoc));
if (domdoc) {
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domdoc);
if (doc) {
doc->FlushPendingNotifications();
}
}
}
nsCOMPtr<nsIWebNavigation> shellAsNav = do_QueryInterface(mDocShellNode);
if (shellAsNav) {
nsCOMPtr<nsIDOMDocument> domdoc;
shellAsNav->GetDocument(getter_AddRefs(domdoc));
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domdoc);
if (doc) {
doc->FlushPendingNotifications();
}
}
// The above flush might cause mDocShellNode to be cleared, so we
// need to check that it's still non-null here.
if (mDocShellNode) {
mDocShellNode->GetChildAt(aIndex, getter_AddRefs(item));
nsCOMPtr<nsIScriptGlobalObject> globalObject(do_GetInterface(item));
@ -149,20 +158,24 @@ nsDOMWindowList::NamedItem(const nsAString& aName, nsIDOMWindow** aReturn)
nsCOMPtr<nsIDocShellTreeItem> item;
*aReturn = nsnull;
if (mDocShellNode) {
nsCOMPtr<nsIWebNavigation> shellAsNav = do_QueryInterface(mDocShellNode);
if (shellAsNav) {
nsCOMPtr<nsIDOMDocument> domdoc;
shellAsNav->GetDocument(getter_AddRefs(domdoc));
if (domdoc) {
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domdoc);
if (doc) {
doc->FlushPendingNotifications();
}
}
}
nsCOMPtr<nsIWebNavigation> shellAsNav(do_QueryInterface(mDocShellNode));
if (shellAsNav) {
nsCOMPtr<nsIDOMDocument> domdoc;
shellAsNav->GetDocument(getter_AddRefs(domdoc));
nsCOMPtr<nsIDocument> doc(do_QueryInterface(domdoc));
if (doc) {
doc->FlushPendingNotifications();
}
}
// The above flush might cause mDocShellNode to be cleared, so we
// need to check that it's still non-null here.
if (mDocShellNode) {
mDocShellNode->FindChildWithName(PromiseFlatString(aName).get(),
PR_FALSE, PR_FALSE,
nsnull, getter_AddRefs(item));