From dc7199416471f25d83704e4911f6df8d97655d30 Mon Sep 17 00:00:00 2001 From: "jst@mozilla.org" Date: Sun, 11 Nov 2007 21:48:24 -0800 Subject: [PATCH] Fixing bug 392532. Infinite recursion crash when getting scroll chrome flags off of a window at the wrong point in time. r+sr=bzbarsky@mit.edu, a=vladimir@pobox.com --- docshell/base/nsDocShell.cpp | 18 ++++++++++++++++++ docshell/base/nsDocShell.h | 4 ++++ xpfe/appshell/src/nsXULWindow.cpp | 25 +++++++++++++++++-------- 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 4304aaa0c85f..85661c0224be 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -304,6 +304,9 @@ nsDocShell::nsDocShell(): mEditorData(nsnull), mTreeOwner(nsnull), mChromeEventHandler(nsnull) +#ifdef DEBUG + , mInEnsureScriptEnv(PR_FALSE) +#endif { if (gDocShellCount++ == 0) { NS_ASSERTION(sURIFixup == nsnull, @@ -8670,6 +8673,16 @@ nsDocShell::EnsureScriptEnvironment() return NS_ERROR_NOT_AVAILABLE; } +#ifdef DEBUG + NS_ASSERTION(!mInEnsureScriptEnv, + "Infinite loop! Calling EnsureScriptEnvironment() from " + "within EnsureScriptEnvironment()!"); + + // Yeah, this isn't re-entrant safe, but that's ok since if we + // re-enter this method, we'll infinitely loop... + mInEnsureScriptEnv = PR_TRUE; +#endif + nsCOMPtr factory = do_GetService(kDOMScriptObjectFactoryCID); NS_ENSURE_TRUE(factory, NS_ERROR_FAILURE); @@ -8700,6 +8713,11 @@ nsDocShell::EnsureScriptEnvironment() nsresult rv; rv = mScriptGlobal->EnsureScriptEnvironment(nsIProgrammingLanguage::JAVASCRIPT); NS_ENSURE_SUCCESS(rv, rv); + +#ifdef DEBUG + mInEnsureScriptEnv = PR_FALSE; +#endif + return NS_OK; } diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index 6dbd4eb2e0de..3f9bee4765d8 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -651,6 +651,10 @@ protected: nsIDocShellTreeOwner * mTreeOwner; // Weak Reference nsPIDOMEventTarget * mChromeEventHandler; //Weak Reference +#ifdef DEBUG + PRBool mInEnsureScriptEnv; +#endif + static nsIURIFixup *sURIFixup; diff --git a/xpfe/appshell/src/nsXULWindow.cpp b/xpfe/appshell/src/nsXULWindow.cpp index 35afa93ee402..d9f7ccb8be3d 100644 --- a/xpfe/appshell/src/nsXULWindow.cpp +++ b/xpfe/appshell/src/nsXULWindow.cpp @@ -1992,16 +1992,25 @@ void nsXULWindow::SetContentScrollbarVisibility(PRBool aVisible) PRBool nsXULWindow::GetContentScrollbarVisibility() { - PRBool visible = PR_TRUE; + // This code already exists in dom/src/base/nsBarProp.cpp, but we + // can't safely get to that from here as this function is called + // while the DOM window is being set up, and we need the DOM window + // to get to that code. + nsCOMPtr scroller(do_QueryInterface(mPrimaryContentShell)); - nsCOMPtr contentWin(do_GetInterface(mPrimaryContentShell)); - if (contentWin) { - nsCOMPtr scrollbars; - contentWin->GetScrollbars(getter_AddRefs(scrollbars)); - if (scrollbars) - scrollbars->GetVisible(&visible); + if (scroller) { + PRInt32 prefValue; + scroller->GetDefaultScrollbarPreferences( + nsIScrollable::ScrollOrientation_Y, &prefValue); + if (prefValue == nsIScrollable::Scrollbar_Never) // try the other way + scroller->GetDefaultScrollbarPreferences( + nsIScrollable::ScrollOrientation_X, &prefValue); + + if (prefValue == nsIScrollable::Scrollbar_Never) + return PR_FALSE; } - return visible; + + return PR_TRUE; } // during spinup, attributes that haven't been loaded yet can't be dirty