Back out 670c8a2695b3 (bug 771354), 134557d57e6e 4ad52e488977 (bug 774607), and...

036eb8c2a08a d4d36e3b948f 35334e820632 6bd07fd5147d d49e7c0d762c 407f19deb14c d84551808abb (bug 774633)
on a CLOSED TREE
This commit is contained in:
Matt Brubeck 2012-08-23 21:34:27 -07:00
parent cafa580be3
commit 424ea88da6
21 changed files with 219 additions and 125 deletions

View File

@ -890,7 +890,8 @@ nsFrameScriptExecutor::InitTabChildGlobalInternal(nsISupports* aScope)
JSAutoRequest ar(cx);
nsIXPConnect* xpc = nsContentUtils::XPConnect();
const uint32_t flags = nsIXPConnect::INIT_JS_STANDARD_CLASSES;
const uint32_t flags = nsIXPConnect::INIT_JS_STANDARD_CLASSES |
nsIXPConnect::FLAG_SYSTEM_GLOBAL_OBJECT;
JS_SetContextPrivate(cx, aScope);

View File

@ -6665,17 +6665,26 @@ nsDocShell::EnsureContentViewer()
NS_TIME_FUNCTION;
nsIPrincipal* principal = nullptr;
nsCOMPtr<nsIURI> baseURI;
nsIPrincipal* principal = GetInheritedPrincipal(false);
nsCOMPtr<nsIDocShellTreeItem> parentItem;
GetSameTypeParent(getter_AddRefs(parentItem));
if (parentItem) {
nsCOMPtr<nsPIDOMWindow> domWin = do_GetInterface(GetAsSupports(this));
if (domWin) {
nsCOMPtr<nsIContent> parentContent =
do_QueryInterface(domWin->GetFrameElementInternal());
if (parentContent) {
baseURI = parentContent->GetBaseURI();
nsCOMPtr<nsPIDOMWindow> piDOMWindow(do_QueryInterface(mScriptGlobal));
if (piDOMWindow) {
principal = piDOMWindow->GetOpenerScriptPrincipal();
}
if (!principal) {
principal = GetInheritedPrincipal(false);
nsCOMPtr<nsIDocShellTreeItem> parentItem;
GetSameTypeParent(getter_AddRefs(parentItem));
if (parentItem) {
nsCOMPtr<nsPIDOMWindow> domWin = do_GetInterface(GetAsSupports(this));
if (domWin) {
nsCOMPtr<nsIContent> parentContent =
do_QueryInterface(domWin->GetFrameElementInternal());
if (parentContent) {
baseURI = parentContent->GetBaseURI();
}
}
}
}

View File

@ -1264,6 +1264,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsGlobalWindow)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mInnerWindowHolder)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOuterWindow)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOpenerScriptPrincipal)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mListenerManager,
nsEventListenerManager)
@ -1313,6 +1314,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGlobalWindow)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOuterWindow)
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOpenerScriptPrincipal)
if (tmp->mListenerManager) {
tmp->mListenerManager->Disconnect();
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mListenerManager)
@ -1460,6 +1462,8 @@ nsGlobalWindow::WouldReuseInnerWindow(nsIDocument *aNewDocument)
// We reuse the inner window when:
// a. We are currently at our original document.
// b. At least one of the following conditions are true:
// -- We are not currently a content window (i.e., we're currently a chrome
// window).
// -- The new document is the same as the old document. This means that we're
// getting called from document.open().
// -- The new document has the same origin as what we have loaded right now.
@ -1474,10 +1478,9 @@ nsGlobalWindow::WouldReuseInnerWindow(nsIDocument *aNewDocument)
NS_ASSERTION(NS_IsAboutBlank(mDoc->GetDocumentURI()),
"How'd this happen?");
// Great, we're the original document, check for one of the other
// conditions.
if (mDoc == aNewDocument) {
return true;
}
@ -1490,66 +1493,63 @@ nsGlobalWindow::WouldReuseInnerWindow(nsIDocument *aNewDocument)
return true;
}
nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(mDocShell));
if (treeItem) {
int32_t itemType = nsIDocShellTreeItem::typeContent;
treeItem->GetItemType(&itemType);
// If we're a chrome window, then we want to reuse the inner window.
return itemType == nsIDocShellTreeItem::typeChrome;
}
// No treeItem: don't reuse the current inner window.
return false;
}
void
nsGlobalWindow::SetInitialPrincipalToSubject()
nsGlobalWindow::SetOpenerScriptPrincipal(nsIPrincipal* aPrincipal)
{
FORWARD_TO_OUTER_VOID(SetInitialPrincipalToSubject, ());
FORWARD_TO_OUTER_VOID(SetOpenerScriptPrincipal, (aPrincipal));
// First, grab the subject principal. These methods never fail.
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
nsCOMPtr<nsIPrincipal> newWindowPrincipal, systemPrincipal;
ssm->GetSubjectPrincipal(getter_AddRefs(newWindowPrincipal));
ssm->GetSystemPrincipal(getter_AddRefs(systemPrincipal));
if (!newWindowPrincipal) {
newWindowPrincipal = systemPrincipal;
}
// Now, if we're about to use the system principal, make sure we're not using
// it for a content docshell.
if (newWindowPrincipal == systemPrincipal) {
int32_t itemType;
nsCOMPtr<nsIDocShellTreeItem> item = do_QueryInterface(GetDocShell());
nsresult rv = item->GetItemType(&itemType);
if (NS_FAILED(rv) || itemType != nsIDocShellTreeItem::typeChrome) {
newWindowPrincipal = nullptr;
}
}
// If there's an existing document, bail if it either:
if (mDoc) {
// (a) is not an initial about:blank document, or
if (!mDoc->IsInitialDocument())
return;
// (b) already has the correct principal.
if (mDoc->NodePrincipal() == newWindowPrincipal)
if (!mDoc->IsInitialDocument()) {
// We have a document already, and it's not the original one. Bail out.
// Do NOT set mOpenerScriptPrincipal in this case, just to be safe.
return;
}
#ifdef DEBUG
// If we have a document loaded at this point, it had better be about:blank.
// Otherwise, something is really weird.
// We better have an about:blank document loaded at this point. Otherwise,
// something is really weird.
nsCOMPtr<nsIURI> uri;
mDoc->NodePrincipal()->GetURI(getter_AddRefs(uri));
NS_ASSERTION(uri && NS_IsAboutBlank(uri) &&
NS_IsAboutBlank(mDoc->GetDocumentURI()),
"Unexpected original document");
#endif
GetDocShell()->CreateAboutBlankContentViewer(aPrincipal);
mDoc->SetIsInitialDocument(true);
nsCOMPtr<nsIPresShell> shell;
GetDocShell()->GetPresShell(getter_AddRefs(shell));
if (shell && !shell->DidInitialReflow()) {
// Ensure that if someone plays with this document they will get
// layout happening.
nsRect r = shell->GetPresContext()->GetVisibleArea();
shell->InitialReflow(r.width, r.height);
}
}
}
GetDocShell()->CreateAboutBlankContentViewer(newWindowPrincipal);
mDoc->SetIsInitialDocument(true);
nsIPrincipal*
nsGlobalWindow::GetOpenerScriptPrincipal()
{
FORWARD_TO_OUTER(GetOpenerScriptPrincipal, (), nullptr);
nsCOMPtr<nsIPresShell> shell;
GetDocShell()->GetPresShell(getter_AddRefs(shell));
if (shell && !shell->DidInitialReflow()) {
// Ensure that if someone plays with this document they will get
// layout happening.
nsRect r = shell->GetPresContext()->GetVisibleArea();
shell->InitialReflow(r.width, r.height);
}
return mOpenerScriptPrincipal;
}
PopupControlState
@ -1695,6 +1695,7 @@ static nsresult
CreateNativeGlobalForInner(JSContext* aCx,
nsGlobalWindow* aNewInner,
nsIURI* aURI,
bool aIsChrome,
nsIPrincipal* aPrincipal,
JSObject** aNativeGlobal,
nsIXPConnectJSObjectHolder** aHolder)
@ -1707,11 +1708,20 @@ CreateNativeGlobalForInner(JSContext* aCx,
MOZ_ASSERT(aHolder);
nsIXPConnect* xpc = nsContentUtils::XPConnect();
uint32_t flags = aIsChrome ? nsIXPConnect::FLAG_SYSTEM_GLOBAL_OBJECT : 0;
nsCOMPtr<nsIPrincipal> systemPrincipal;
if (aIsChrome) {
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
ssm->GetSystemPrincipal(getter_AddRefs(systemPrincipal));
MOZ_ASSERT(systemPrincipal);
}
nsRefPtr<nsIXPConnectJSObjectHolder> jsholder;
nsresult rv = xpc->InitClassesWithNewWrappedGlobal(
aCx, static_cast<nsIScriptGlobalObject*>(aNewInner),
aPrincipal, 0, getter_AddRefs(jsholder));
aIsChrome ? systemPrincipal.get() : aPrincipal, flags,
getter_AddRefs(jsholder));
NS_ENSURE_SUCCESS(rv, rv);
MOZ_ASSERT(jsholder);
@ -1834,6 +1844,8 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
bool thisChrome = IsChromeWindow();
bool isChrome = false;
nsCxPusher cxPusher;
if (!cxPusher.Push(cx)) {
return NS_ERROR_FAILURE;
@ -1868,15 +1880,7 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
// match the new document.
// NB: We don't just call currentInner->RefreshCompartmentPrincipals() here
// because we haven't yet set its mDoc to aDocument.
JSCompartment *compartment = js::GetObjectCompartment(currentInner->mJSObject);
#ifdef DEBUG
bool sameOrigin = false;
nsIPrincipal *existing =
nsJSPrincipals::get(JS_GetCompartmentPrincipals(compartment));
aDocument->NodePrincipal()->Equals(existing, &sameOrigin);
MOZ_ASSERT(sameOrigin);
#endif
JS_SetCompartmentPrincipals(compartment,
JS_SetCompartmentPrincipals(js::GetObjectCompartment(currentInner->mJSObject),
nsJSPrincipals::get(aDocument->NodePrincipal()));
} else {
if (aState) {
@ -1886,6 +1890,7 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
NS_ASSERTION(newInnerWindow, "Got a state without inner window");
} else if (thisChrome) {
newInnerWindow = new nsGlobalChromeWindow(this);
isChrome = true;
} else if (mIsModalContentWindow) {
newInnerWindow = new nsGlobalModalWindow(this);
} else {
@ -1910,7 +1915,7 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
// Every script context we are initialized with must create a
// new global.
rv = CreateNativeGlobalForInner(cx, newInnerWindow,
aDocument->GetDocumentURI(),
aDocument->GetDocumentURI(), isChrome,
aDocument->NodePrincipal(),
&newInnerWindow->mJSObject,
getter_AddRefs(mInnerWindowHolder));

View File

@ -342,7 +342,8 @@ public:
virtual NS_HIDDEN_(void) SetIsBackground(bool aIsBackground);
virtual NS_HIDDEN_(void) SetChromeEventHandler(nsIDOMEventTarget* aChromeEventHandler);
virtual NS_HIDDEN_(void) SetInitialPrincipalToSubject();
virtual NS_HIDDEN_(void) SetOpenerScriptPrincipal(nsIPrincipal* aPrincipal);
virtual NS_HIDDEN_(nsIPrincipal*) GetOpenerScriptPrincipal();
virtual NS_HIDDEN_(PopupControlState) PushPopupControlState(PopupControlState state, bool aForce) const;
virtual NS_HIDDEN_(void) PopPopupControlState(PopupControlState state) const;
@ -1013,6 +1014,8 @@ protected:
nsCOMPtr<nsIDOMStorage> mSessionStorage;
nsCOMPtr<nsIXPConnectJSObjectHolder> mInnerWindowHolder;
nsCOMPtr<nsIPrincipal> mOpenerScriptPrincipal; // strong; used to determine
// whether to clear scope
// These member variable are used only on inner windows.
nsRefPtr<nsEventListenerManager> mListenerManager;

View File

@ -48,8 +48,8 @@ class nsIArray;
class nsPIWindowRoot;
#define NS_PIDOMWINDOW_IID \
{ 0x0c5763c6, 0x5e87, 0x4f6f, \
{ 0xa2, 0xef, 0xcf, 0x4d, 0xeb, 0xd1, 0xbc, 0xc3 } }
{0x66660102, 0xd875, 0x47e2, \
{0xa1, 0xf7, 0x12, 0xbc, 0x83, 0xc9, 0x93, 0xa9}}
class nsPIDOMWindow : public nsIDOMWindowInternal
{
@ -280,9 +280,14 @@ public:
return win->mIsHandlingResizeEvent;
}
// Set the window up with an about:blank document with the current subject
// principal.
virtual void SetInitialPrincipalToSubject() = 0;
// Tell this window who opened it. This only has an effect if there is
// either no document currently in the window or if the document is the
// original document this window came with (an about:blank document either
// preloaded into it when it was created, or created by
// CreateAboutBlankContentViewer()).
virtual void SetOpenerScriptPrincipal(nsIPrincipal* aPrincipal) = 0;
// Ask this window who opened it.
virtual nsIPrincipal* GetOpenerScriptPrincipal() = 0;
virtual PopupControlState PushPopupControlState(PopupControlState aState,
bool aForce) const = 0;

View File

@ -586,21 +586,11 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow *aParent,
JSContext *cx = GetJSContextFromWindow(aParent);
bool windowTypeIsChrome = chromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME;
if (isCallerChrome && !hasChromeParent && !windowTypeIsChrome && cx) {
// open() is called from chrome on a non-chrome window, push the context of the
// callee onto the context stack to prevent the caller's priveleges from leaking
// into code that runs while opening the new window.
//
// The reasoning for this is in bug 289204. Basically, chrome sometimes does
// someContentWindow.open(untrustedURL), and wants to be insulated from nasty
// javascript: URLs and such. But there are also cases where we create a
// window parented to a content window (such as a download dialog), usually
// directly with nsIWindowWatcher. In those cases, we want the principal of
// the initial about:blank document to be system, so that the subsequent XUL
// load can reuse the inner window and avoid blowing away expandos. As such,
// we decide whether to load with the principal of the caller or of the parent
// based on whether the docshell type is chrome or content.
if (isCallerChrome && !hasChromeParent && cx) {
// open() is called from chrome on a non-chrome window, push
// the context of the callee onto the context stack to
// prevent the caller's priveleges from leaking into code
// that runs while opening the new window.
callerContextGuard.Push(cx);
}
@ -883,17 +873,32 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow *aParent,
// the JS stack, just use the principal of our parent window. In those
// cases we do _not_ set the parent window principal as the owner of the
// load--since we really don't know who the owner is, just leave it null.
nsIPrincipal* newWindowPrincipal = subjectPrincipal;
if (!newWindowPrincipal && aParent) {
nsCOMPtr<nsIScriptObjectPrincipal> sop(do_QueryInterface(aParent));
if (sop) {
newWindowPrincipal = sop->GetPrincipal();
}
}
bool isSystem;
rv = sm->IsSystemPrincipal(newWindowPrincipal, &isSystem);
if (NS_FAILED(rv) || isSystem) {
// Don't pass this principal along to content windows
int32_t itemType;
rv = newDocShellItem->GetItemType(&itemType);
if (NS_FAILED(rv) || itemType != nsIDocShellTreeItem::typeChrome) {
newWindowPrincipal = nullptr;
}
}
nsCOMPtr<nsPIDOMWindow> newWindow = do_QueryInterface(*_retval);
#ifdef DEBUG
nsCOMPtr<nsPIDOMWindow> newDebugWindow = do_GetInterface(newDocShell);
NS_ASSERTION(newWindow == newDebugWindow, "Different windows??");
#endif
// The principal of the initial about:blank document gets set up in
// nsWindowWatcher::AddWindow. Make sure to call it. In the common case
// this call already happened when the window was created, but
// SetInitialPrincipalToSubject is safe to call multiple times.
if (newWindow) {
newWindow->SetInitialPrincipalToSubject();
newWindow->SetOpenerScriptPrincipal(newWindowPrincipal);
}
}

View File

@ -1088,7 +1088,9 @@ XPCShellEnvironment::Init()
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
rv = xpc->InitClassesWithNewWrappedGlobal(cx, backstagePass,
principal, 0,
principal,
nsIXPConnect::
FLAG_SYSTEM_GLOBAL_OBJECT,
getter_AddRefs(holder));
if (NS_FAILED(rv)) {
NS_ERROR("InitClassesWithNewWrappedGlobal failed!");

View File

@ -1036,6 +1036,18 @@ JS_GetScriptTotalSize(JSContext *cx, JSScript *script)
return nbytes;
}
JS_PUBLIC_API(JSBool)
JS_IsSystemObject(JSContext *cx, JSObject *obj)
{
return obj->isSystem();
}
JS_PUBLIC_API(JSBool)
JS_MakeSystemObject(JSContext *cx, JSObject *obj)
{
return obj->setSystem(cx);
}
/************************************************************************/
JS_FRIEND_API(void)

View File

@ -389,6 +389,23 @@ JS_GetFunctionTotalSize(JSContext *cx, JSFunction *fun);
extern JS_PUBLIC_API(size_t)
JS_GetScriptTotalSize(JSContext *cx, JSScript *script);
/*
* Return true if obj is a "system" object, that is, one created by
* JS_NewSystemObject with the system flag set and not JS_NewObject.
*
* What "system" means is up to the API client.
*/
extern JS_PUBLIC_API(JSBool)
JS_IsSystemObject(JSContext *cx, JSObject *obj);
/*
* Mark an object as being a system object. This should be called immediately
* after allocating the object. A system object is an object for which
* JS_IsSystemObject returns true.
*/
extern JS_PUBLIC_API(JSBool)
JS_MakeSystemObject(JSContext *cx, JSObject *obj);
/************************************************************************/
extern JS_FRIEND_API(void)

View File

@ -196,20 +196,10 @@ JS_SetCompartmentPrincipals(JSCompartment *compartment, JSPrincipals *principals
if (principals == compartment->principals)
return;
// Any compartment with the trusted principals -- and there can be
// multiple -- is a system compartment.
JSPrincipals *trusted = compartment->rt->trustedPrincipals();
bool isSystem = principals && principals == trusted;
// Clear out the old principals, if any.
if (compartment->principals) {
JS_DropPrincipals(compartment->rt, compartment->principals);
compartment->principals = NULL;
// We'd like to assert that our new principals is always same-origin
// with the old one, but JSPrincipals doesn't give us a way to do that.
// But we can at least assert that we're not switching between system
// and non-system.
JS_ASSERT(compartment->isSystemCompartment == isSystem);
}
// Set up the new principals.
@ -218,8 +208,10 @@ JS_SetCompartmentPrincipals(JSCompartment *compartment, JSPrincipals *principals
compartment->principals = principals;
}
// Update the system flag.
compartment->isSystemCompartment = isSystem;
// Any compartment with the trusted principals -- and there can be
// multiple -- is a system compartment.
JSPrincipals *trusted = compartment->rt->trustedPrincipals();
compartment->isSystemCompartment = principals && principals == trusted;
}
JS_FRIEND_API(JSBool)

View File

@ -5623,6 +5623,7 @@ JSObject::dump()
fprintf(stderr, "flags:");
if (obj->isDelegate()) fprintf(stderr, " delegate");
if (obj->isSystem()) fprintf(stderr, " system");
if (!obj->isExtensible()) fprintf(stderr, " not_extensible");
if (obj->isIndexed()) fprintf(stderr, " indexed");

View File

@ -326,6 +326,14 @@ struct JSObject : public js::ObjectImpl
inline bool isBoundFunction() const;
/*
* The meaning of the system object bit is defined by the API client. It is
* set in JS_NewSystemObject and is queried by JS_IsSystemObject, but it
* has no intrinsic meaning to SpiderMonkey.
*/
inline bool isSystem() const;
inline bool setSystem(JSContext *cx);
inline bool hasSpecialEquality() const;
inline bool watched() const;

View File

@ -692,6 +692,16 @@ inline bool JSObject::setIteratedSingleton(JSContext *cx)
return setFlag(cx, js::BaseShape::ITERATED_SINGLETON);
}
inline bool JSObject::isSystem() const
{
return lastProperty()->hasObjectFlag(js::BaseShape::SYSTEM);
}
inline bool JSObject::setSystem(JSContext *cx)
{
return setFlag(cx, js::BaseShape::SYSTEM);
}
inline bool JSObject::setDelegate(JSContext *cx)
{
return setFlag(cx, js::BaseShape::DELEGATE, GENERATE_SHAPE);

View File

@ -255,14 +255,15 @@ class BaseShape : public js::gc::Cell
*/
DELEGATE = 0x8,
NOT_EXTENSIBLE = 0x10,
INDEXED = 0x20,
BOUND_FUNCTION = 0x40,
VAROBJ = 0x80,
WATCHED = 0x100,
ITERATED_SINGLETON = 0x200,
NEW_TYPE_UNKNOWN = 0x400,
UNCACHEABLE_PROTO = 0x800,
SYSTEM = 0x10,
NOT_EXTENSIBLE = 0x20,
INDEXED = 0x40,
BOUND_FUNCTION = 0x80,
VAROBJ = 0x100,
WATCHED = 0x200,
ITERATED_SINGLETON = 0x400,
NEW_TYPE_UNKNOWN = 0x800,
UNCACHEABLE_PROTO = 0x1000,
OBJECT_FLAG_MASK = 0x1ff8
};

View File

@ -303,7 +303,7 @@ interface nsIXPCFunctionThisTranslator : nsISupports
{ 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
%}
[uuid(bd300b18-1c34-4589-8285-23a12cc580ea)]
[uuid(26efd266-3e33-4dc9-8233-e13bb8d9c452)]
interface nsIXPConnect : nsISupports
{
%{ C++
@ -339,7 +339,7 @@ interface nsIXPConnect : nsISupports
in uint32_t aFlags);
const uint32_t INIT_JS_STANDARD_CLASSES = 1 << 0;
// Free bit here!
const uint32_t FLAG_SYSTEM_GLOBAL_OBJECT = 1 << 1;
const uint32_t OMIT_COMPONENTS_OBJECT = 1 << 2;
/**

View File

@ -645,7 +645,8 @@ mozJSComponentLoader::GlobalForLocation(nsIFile *aComponentFile,
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
rv = xpc->InitClassesWithNewWrappedGlobal(cx, backstagePass,
mSystemPrincipal,
0,
nsIXPConnect::
FLAG_SYSTEM_GLOBAL_OBJECT,
getter_AddRefs(holder));
NS_ENSURE_SUCCESS(rv, rv);

View File

@ -1863,7 +1863,8 @@ main(int argc, char **argv, char **envp)
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
rv = xpc->InitClassesWithNewWrappedGlobal(cx, backstagePass,
systemprincipal,
0,
nsIXPConnect::
FLAG_SYSTEM_GLOBAL_OBJECT,
getter_AddRefs(holder));
if (NS_FAILED(rv))
return 1;

View File

@ -611,6 +611,8 @@ xpc_NewSystemInheritingJSObject(JSContext *cx, JSClass *clasp, JSObject *proto,
} else {
obj = JS_NewObject(cx, clasp, proto, parent);
}
if (obj && JS_IsSystemObject(cx, parent) && !JS_MakeSystemObject(cx, obj))
obj = NULL;
return obj;
}

View File

@ -1176,6 +1176,11 @@ nsXPConnect::InitClassesWithNewWrappedGlobal(JSContext * aJSContext,
MOZ_ASSERT(!js::GetObjectParent(global));
JSAutoCompartment ac(ccx, global);
// Apply the system flag, if requested.
bool system = (aFlags & nsIXPConnect::FLAG_SYSTEM_GLOBAL_OBJECT) != 0;
if (system && !JS_MakeSystemObject(aJSContext, global))
return UnexpectedFailure(NS_ERROR_FAILURE);
if (!(aFlags & nsIXPConnect::OMIT_COMPONENTS_OBJECT)) {
// XPCCallContext gives us an active request needed to save/restore.
if (!nsXPCComponents::AttachComponentsObject(ccx, wrappedGlobal->GetScope(), global))

View File

@ -329,7 +329,19 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *obj, JSObject *wrappedProto, JSO
if (AccessCheck::isChrome(origin)) {
wrapper = &CrossCompartmentWrapper::singleton;
} else {
if (flags & WAIVE_XRAY_WRAPPER_FLAG) {
bool isSystem;
{
JSAutoEnterCompartment ac;
if (!ac.enter(cx, obj))
return nullptr;
JSObject *globalObj = JS_GetGlobalForObject(cx, obj);
JS_ASSERT(globalObj);
isSystem = JS_IsSystemObject(cx, globalObj);
}
if (isSystem) {
wrapper = &CrossCompartmentWrapper::singleton;
} else if (flags & WAIVE_XRAY_WRAPPER_FLAG) {
// If we waived the X-ray wrapper for this object, wrap it into a
// special wrapper to transitively maintain the X-ray waiver.
wrapper = &WaiveXrayWrapper::singleton;

View File

@ -19,7 +19,6 @@
#include "nsIWindowWatcher.h"
#include "nsPIWindowWatcher.h"
#include "nsIDOMWindow.h"
#include "nsPIDOMWindow.h"
#include "nsWebShellWindow.h"
#include "nsIEnumerator.h"
@ -451,11 +450,6 @@ nsAppShellService::GetApplicationProvidedHiddenWindow(bool* aAPHW)
NS_IMETHODIMP
nsAppShellService::RegisterTopLevelWindow(nsIXULWindow* aWindow)
{
nsCOMPtr<nsIDocShell> docShell;
aWindow->GetDocShell(getter_AddRefs(docShell));
nsCOMPtr<nsPIDOMWindow> domWindow(do_GetInterface(docShell));
domWindow->SetInitialPrincipalToSubject();
// tell the window mediator about the new window
nsCOMPtr<nsIWindowMediator> mediator
( do_GetService(NS_WINDOWMEDIATOR_CONTRACTID) );
@ -467,8 +461,16 @@ nsAppShellService::RegisterTopLevelWindow(nsIXULWindow* aWindow)
// tell the window watcher about the new window
nsCOMPtr<nsPIWindowWatcher> wwatcher ( do_GetService(NS_WINDOWWATCHER_CONTRACTID) );
NS_ASSERTION(wwatcher, "No windowwatcher?");
if (wwatcher && domWindow) {
wwatcher->AddWindow(domWindow, 0);
if (wwatcher) {
nsCOMPtr<nsIDocShell> docShell;
aWindow->GetDocShell(getter_AddRefs(docShell));
NS_ASSERTION(docShell, "Window has no docshell");
if (docShell) {
nsCOMPtr<nsIDOMWindow> domWindow(do_GetInterface(docShell));
NS_ASSERTION(domWindow, "Couldn't get DOM window.");
if (domWindow)
wwatcher->AddWindow(domWindow, 0);
}
}
// an ongoing attempt to quit is stopped by a newly opened window