Bug 1432396 - Add assertions that we don't allow reinitialization of variables that were reset in nsDocShell::Destroy(). r=bz

Here is the list of variables which are reset in nsDocShell::Destroy().
The right column shows the function where the variable is set.  In this patch
all the functions other than SetTreeOwner(*1) have an assertion that we don't
allow the function to be called or bail out during destroying the docshell.

It is possible that SetTreeOwner() is called in script through
`browser.setAttribute("primary", "true")`.  So we can't assert there, we just
bail out from SetTreeOwner when the docshell is being destroyed.

mInitialClientSource              MaybeCreateInitialClientSource()
mObserveErrorPages:               Initially true, never sets true again
mLoadingURI:                      CreateContentViewer()
mOSHE->SetEditorData(nullptr):    DetachEditorFromWindow()
mLSHE->SetEditorData(nullptr):    Setting again in RestoreFromHistory() after bailing out if mIsBeingDestroyed is true
mContentListener:                 Init()
Stop(nsIWebNavigation::STOP_ALL)
  mRestorePresentationEvent:      RestorePresentation()
  mFailedChannel:                 LoadErrorPage()
  mFailedURI:                     LoadErrorPage()
  mRefreshURIList:                RefreshURI()
mEditorData:                      ReattachEditorToWindow() and EnsureEditorData()
mTransferableHookData:            EnsureTransferableHookData()
mContentViewer:                   SetupNewViewer()
mParentWidget:                    SetParentWidget()
mCurrentURI:                      SetCurrentURI()
mScriptGlobal:                    EnsureScriptEnvironment()
mSessionHistory                   SetSessionHistory()
SetTreeOwner():                   SetTreeOwner() *1
mOnePermittedSandboxedNavigator:  SetOnePermittedSandboxedNavigator()
mSecurityUI:                      SetSecurityUI()
CancelRefreshURITimers()
  mRefreshURIList:                RefreshURI()
  mSavedRefreshURIList:           RefreshURI()
mPrivateBrowsingId:               SetPrivateBrowsing()
mOriginAttributes:                SetOriginAttributes()
DecreasePrivateDocShellCount:     SetAffectPrivateSessionLifetime()

MozReview-Commit-ID: G5d941R9K8V

--HG--
extra : rebase_source : 978e5b232e76a803c104c030bbeb91315d886491
This commit is contained in:
Hiroyuki Ikezoe 2018-02-16 06:29:59 +09:00
Родитель fbdb88bdd8
Коммит 7034a44b02
1 изменённых файлов: 44 добавлений и 0 удалений

Просмотреть файл

@ -452,6 +452,8 @@ nsDocShell::~nsDocShell()
nsresult
nsDocShell::Init()
{
MOZ_ASSERT(!mIsBeingDestroyed);
nsresult rv = nsDocLoader::Init();
NS_ENSURE_SUCCESS(rv, rv);
@ -1426,6 +1428,8 @@ bool
nsDocShell::SetCurrentURI(nsIURI* aURI, nsIRequest* aRequest,
bool aFireOnLocationChange, uint32_t aLocationFlags)
{
MOZ_ASSERT(!mIsBeingDestroyed);
MOZ_LOG(gDocShellLeakLog, LogLevel::Debug,
("DOCSHELL %p SetCurrentURI %s\n",
this, aURI ? aURI->GetSpecOrDefault().get() : ""));
@ -1753,6 +1757,8 @@ nsDocShell::SetUsePrivateBrowsing(bool aUsePrivateBrowsing)
NS_IMETHODIMP
nsDocShell::SetPrivateBrowsing(bool aUsePrivateBrowsing)
{
MOZ_ASSERT(!mIsBeingDestroyed);
bool changed = aUsePrivateBrowsing != (mPrivateBrowsingId > 0);
if (changed) {
mPrivateBrowsingId = aUsePrivateBrowsing ? 1 : 0;
@ -1828,6 +1834,8 @@ nsDocShell::SetRemoteTabs(bool aUseRemoteTabs)
NS_IMETHODIMP
nsDocShell::SetAffectPrivateSessionLifetime(bool aAffectLifetime)
{
MOZ_ASSERT(!mIsBeingDestroyed);
bool change = aAffectLifetime != mAffectPrivateSessionLifetime;
if (change && UsePrivateBrowsing()) {
AssertOriginAttributesMatchPrivateBrowsing();
@ -2330,6 +2338,8 @@ nsDocShell::GetSecurityUI(nsISecureBrowserUI** aSecurityUI)
NS_IMETHODIMP
nsDocShell::SetSecurityUI(nsISecureBrowserUI* aSecurityUI)
{
MOZ_ASSERT(!mIsBeingDestroyed);
mSecurityUI = aSecurityUI;
mSecurityUI->SetDocShell(this);
return NS_OK;
@ -2788,6 +2798,8 @@ nsDocShell::GetParentDocshell()
void
nsDocShell::MaybeCreateInitialClientSource(nsIPrincipal* aPrincipal)
{
MOZ_ASSERT(!mIsBeingDestroyed);
// If there is an existing document then there is no need to create
// a client for a future initial about:blank document.
if (mScriptGlobal && mScriptGlobal->GetCurrentInnerWindowInternal() &&
@ -3587,6 +3599,10 @@ PrintDocTree(nsIDocShellTreeItem* aParentNode)
NS_IMETHODIMP
nsDocShell::SetTreeOwner(nsIDocShellTreeOwner* aTreeOwner)
{
if (mIsBeingDestroyed && aTreeOwner) {
return NS_ERROR_FAILURE;
}
#ifdef DEBUG_DOCSHELL_FOCUS
nsCOMPtr<nsIDocShellTreeItem> item(do_QueryInterface(aTreeOwner));
if (item) {
@ -4936,6 +4952,8 @@ nsDocShell::LoadErrorPage(nsIURI* aURI, const char16_t* aURL,
const char* aCSSClass,
nsIChannel* aFailedChannel)
{
MOZ_ASSERT(!mIsBeingDestroyed);
#if defined(DEBUG)
if (MOZ_LOG_TEST(gDocShellLog, LogLevel::Debug)) {
nsAutoCString chanName;
@ -5246,6 +5264,8 @@ nsDocShell::SetSessionHistory(nsISHistory* aSessionHistory)
// make sure that we are the root docshell and
// set a handle to root docshell in SH.
MOZ_ASSERT(!mIsBeingDestroyed);
nsCOMPtr<nsIDocShellTreeItem> root;
/* Get the root docshell. If *this* is the root docshell
* then save a handle to *this* in SH. SH needs it to do
@ -5427,6 +5447,10 @@ nsDocShell::Create()
NS_IMETHODIMP
nsDocShell::Destroy()
{
// XXX: We allow this function to be called just once. If you are going to
// reset new variables in this function, please make sure the variables will
// never be re-initialized. Adding assertions to check |mIsBeingDestroyed|
// in the setter functions for the variables would be enough.
if (mIsBeingDestroyed) {
return NS_ERROR_DOCSHELL_DYING;
}
@ -5722,6 +5746,7 @@ nsDocShell::GetParentWidget(nsIWidget** aParentWidget)
NS_IMETHODIMP
nsDocShell::SetParentWidget(nsIWidget* aParentWidget)
{
MOZ_ASSERT(!mIsBeingDestroyed);
mParentWidget = aParentWidget;
return NS_OK;
@ -5970,6 +5995,8 @@ nsDocShell::SetOnePermittedSandboxedNavigator(nsIDocShell* aSandboxedNavigator)
return NS_OK;
}
MOZ_ASSERT(!mIsBeingDestroyed);
mOnePermittedSandboxedNavigator = do_GetWeakReference(aSandboxedNavigator);
NS_ASSERTION(mOnePermittedSandboxedNavigator,
"One Permitted Sandboxed Navigator must support weak references.");
@ -6321,6 +6348,8 @@ nsDocShell::RefreshURI(nsIURI* aURI, nsIPrincipal* aPrincipal,
int32_t aDelay, bool aRepeat,
bool aMetaRefresh)
{
MOZ_ASSERT(!mIsBeingDestroyed);
NS_ENSURE_ARG(aURI);
/* Check if Meta refresh/redirects are permitted. Some
@ -7870,6 +7899,8 @@ nsDocShell::CanSavePresentation(uint32_t aLoadType,
void
nsDocShell::ReattachEditorToWindow(nsISHEntry* aSHEntry)
{
MOZ_ASSERT(!mIsBeingDestroyed);
NS_ASSERTION(!mEditorData,
"Why reattach an editor when we already have one?");
NS_ASSERTION(aSHEntry && aSHEntry->HasDetachedEditor(),
@ -7907,6 +7938,9 @@ nsDocShell::DetachEditorFromWindow()
if (NS_SUCCEEDED(res)) {
// Make mOSHE hold the owning ref to the editor data.
if (mOSHE) {
MOZ_ASSERT(!mIsBeingDestroyed || !mOSHE->HasDetachedEditor(),
"We should not set the editor data again once after we "
"detached the editor data during destroying this docshell");
mOSHE->SetEditorData(mEditorData.forget());
} else {
mEditorData = nullptr;
@ -8091,6 +8125,8 @@ nsDocShell::GetRestoringDocument(bool* aRestoring)
nsresult
nsDocShell::RestorePresentation(nsISHEntry* aSHEntry, bool* aRestoring)
{
MOZ_ASSERT(!mIsBeingDestroyed);
NS_ASSERTION(mLoadType & LOAD_CMD_HISTORY,
"RestorePresentation should only be called for history loads");
@ -8948,6 +8984,8 @@ nsDocShell::NewContentViewerObj(const nsACString& aContentType,
nsresult
nsDocShell::SetupNewViewer(nsIContentViewer* aNewViewer)
{
MOZ_ASSERT(!mIsBeingDestroyed);
//
// Copy content viewer state from previous or parent content viewer.
//
@ -12948,6 +12986,8 @@ nsDocShell::EnsureScriptEnvironment()
nsresult
nsDocShell::EnsureEditorData()
{
MOZ_ASSERT(!mIsBeingDestroyed);
bool openDocHasDetachedEditor = mOSHE && mOSHE->HasDetachedEditor();
if (!mEditorData && !mIsBeingDestroyed && !openDocHasDetachedEditor) {
// We shouldn't recreate the editor data if it already exists, or
@ -12963,6 +13003,8 @@ nsDocShell::EnsureEditorData()
nsresult
nsDocShell::EnsureTransferableHookData()
{
MOZ_ASSERT(!mIsBeingDestroyed);
if (!mTransferableHookData) {
mTransferableHookData = new nsTransferableHookData();
}
@ -14089,6 +14131,8 @@ nsDocShell::ServiceWorkerAllowedToControlWindow(nsIPrincipal* aPrincipal,
nsresult
nsDocShell::SetOriginAttributes(const OriginAttributes& aAttrs)
{
MOZ_ASSERT(!mIsBeingDestroyed);
if (!CanSetOriginAttributes()) {
return NS_ERROR_FAILURE;
}