mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
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:
parent
cafa580be3
commit
424ea88da6
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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!");
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user