Bug 640904 - Check for null window globals within PreCreate hooks and assert IsClosedOrClosing(). r=peterv,smaug

This commit is contained in:
Bobby Holley 2012-04-27 10:38:14 +02:00
Родитель d7547c60eb
Коммит 9c2ece0538
1 изменённых файлов: 34 добавлений и 28 удалений

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

@ -535,6 +535,8 @@ using mozilla::dom::indexedDB::IDBWrapperCache;
#include "DOMError.h"
#include "DOMRequest.h"
#include "mozilla/Likely.h"
#undef None // something included above defines this preprocessor symbol, maybe Xlib headers
#include "WebGLContext.h"
@ -1968,6 +1970,23 @@ WrapNativeParent(JSContext *cx, JSObject *scope, nsISupports *native,
return NS_OK;
}
// Helper to handle torn-down inner windows.
static inline nsresult
SetParentToWindow(nsGlobalWindow *win, JSObject **parent)
{
MOZ_ASSERT(win);
MOZ_ASSERT(win->IsInnerWindow());
*parent = win->FastGetGlobalJSObject();
if (MOZ_UNLIKELY(!*parent)) {
// The only known case where this can happen is when the inner window has
// been torn down. See bug 691178 comment 11.
MOZ_ASSERT(win->IsClosedOrClosing());
return NS_ERROR_FAILURE;
}
return NS_OK;
}
// static
nsISupports *
@ -4629,8 +4648,9 @@ nsDOMClassInfo::PreCreate(nsISupports *nativeObj, JSContext *cx,
}
if (piwin->IsOuterWindow()) {
*parentObj = ((nsGlobalWindow *)piwin.get())->
GetCurrentInnerWindowInternal()->GetGlobalJSObject();
nsGlobalWindow *win = ((nsGlobalWindow *)piwin.get())->
GetCurrentInnerWindowInternal();
return SetParentToWindow(win, parentObj);
}
return NS_OK;
@ -5165,20 +5185,15 @@ nsWindowSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
nsGlobalWindow *win = nsGlobalWindow::FromSupports(nativeObj);
NS_ASSERTION(win->IsInnerWindow(), "Should be inner window.");
JSObject *winObj = win->FastGetGlobalJSObject();
if (!winObj) {
// We sometimes get a disconnected window during file api test. :-(
if (!win->GetOuterWindowInternal())
return NS_ERROR_FAILURE;
// See bug 691178 comment 11 for why this is necessary.
if (win->IsClosedOrClosing())
return NS_ERROR_FAILURE;
NS_ASSERTION(win->GetOuterWindowInternal()->IsCreatingInnerWindow(),
"should have a JS object by this point");
// If we're bootstrapping, we don't have a JS object yet.
if (win->GetOuterWindowInternal()->IsCreatingInnerWindow())
return NS_OK;
}
*parentObj = winObj;
return NS_OK;
return SetParentToWindow(win, parentObj);
}
// This JS class piggybacks on nsHTMLDocumentSH::ReleaseDocument()...
@ -6029,8 +6044,7 @@ nsDOMConstructor::PreCreate(JSContext *cx, JSObject *globalObj, JSObject **paren
}
nsGlobalWindow *win = static_cast<nsGlobalWindow *>(owner.get());
*parentObj = win->FastGetGlobalJSObject();
return NS_OK;
return SetParentToWindow(win, parentObj);
}
nsresult
@ -7480,7 +7494,7 @@ nsLocationSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
}
*parentObj = sgo->GetGlobalJSObject();
return NS_OK;
return *parentObj ? NS_OK : NS_ERROR_FAILURE;
}
// DOM Navigator helper
@ -7579,14 +7593,7 @@ nsNavigatorSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
return NS_ERROR_UNEXPECTED;
}
JSObject *global = win->GetGlobalJSObject();
if (global) {
*parentObj = global;
}
return NS_OK;
return SetParentToWindow(win, parentObj);
}
// DOM Node helper
@ -7853,7 +7860,7 @@ nsEventTargetSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
*parentObj = native_parent ? native_parent->GetGlobalJSObject() : globalObj;
return NS_OK;
return *parentObj ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
@ -10005,9 +10012,8 @@ nsHistorySH::PreCreate(nsISupports *nativeObj, JSContext *cx,
NS_WARNING("refusing to create history object in the wrong scope");
return NS_ERROR_FAILURE;
}
*parentObj = static_cast<nsGlobalWindow *>(innerWindow.get())->FastGetGlobalJSObject();
return NS_OK;
return SetParentToWindow(static_cast<nsGlobalWindow *>(innerWindow.get()),
parentObj);
}
NS_IMETHODIMP