зеркало из https://github.com/mozilla/gecko-dev.git
Remove special-casing of about:blank for security purposes; give about:blank
pages the principal of whoever is responsible for loading them, when possible. Bug 332182, r=mrbkap, sr=jst
This commit is contained in:
Родитель
417c678f9a
Коммит
e9379f3679
|
@ -270,15 +270,10 @@ nsPrincipal::Equals(nsIPrincipal *aOther, PRBool *aResult)
|
|||
}
|
||||
|
||||
// Codebases are equal if they have the same origin.
|
||||
nsIURI *origin = mDomain ? mDomain : mCodebase;
|
||||
nsCOMPtr<nsIURI> otherOrigin;
|
||||
aOther->GetDomain(getter_AddRefs(otherOrigin));
|
||||
if (!otherOrigin) {
|
||||
aOther->GetURI(getter_AddRefs(otherOrigin));
|
||||
}
|
||||
|
||||
return nsScriptSecurityManager::GetScriptSecurityManager()
|
||||
->SecurityCompareURIs(origin, otherOrigin, aResult);
|
||||
*aResult =
|
||||
NS_SUCCEEDED(nsScriptSecurityManager::GetScriptSecurityManager()
|
||||
->CheckSameOriginPrincipal(this, aOther));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
*aResult = PR_TRUE;
|
||||
|
@ -288,32 +283,6 @@ nsPrincipal::Equals(nsIPrincipal *aOther, PRBool *aResult)
|
|||
NS_IMETHODIMP
|
||||
nsPrincipal::Subsumes(nsIPrincipal *aOther, PRBool *aResult)
|
||||
{
|
||||
// First, check if aOther is an about:blank principal. If it is, then we can
|
||||
// subsume it.
|
||||
|
||||
nsCOMPtr<nsIURI> otherOrigin;
|
||||
aOther->GetURI(getter_AddRefs(otherOrigin));
|
||||
|
||||
if (otherOrigin) {
|
||||
PRBool isAbout = PR_FALSE;
|
||||
if (NS_SUCCEEDED(otherOrigin->SchemeIs("about", &isAbout)) && isAbout) {
|
||||
nsCAutoString str;
|
||||
otherOrigin->GetSpec(str);
|
||||
|
||||
// Note: about:blank principals do not necessarily subsume about:blank
|
||||
// principals (unless aOther == this, which is checked in the Equals call
|
||||
// below).
|
||||
|
||||
if (str.Equals("about:blank")) {
|
||||
PRBool isEqual = PR_FALSE;
|
||||
if (NS_SUCCEEDED(otherOrigin->Equals(mCodebase, &isEqual)) && !isEqual) {
|
||||
*aResult = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Equals(aOther, aResult);
|
||||
}
|
||||
|
||||
|
|
|
@ -264,21 +264,12 @@ nsScriptSecurityManager::SecurityCompareURIs(nsIURI* aSourceURI,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!aTargetURI)
|
||||
if (!aTargetURI || !aSourceURI)
|
||||
{
|
||||
// return false
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!aSourceURI)
|
||||
{
|
||||
// Throw. If we don't, we might in some cases consider a system
|
||||
// principal as same-origin with an about:blank (see
|
||||
// CheckSameOriginPrincipalInternal). The fact that these methods are
|
||||
// asymmetric is highly unfortunate.
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
// If either URI is a nested URI, get the base URI
|
||||
nsCOMPtr<nsIURI> sourceBaseURI = NS_GetInnermostURI(aSourceURI);
|
||||
|
||||
|
@ -852,8 +843,14 @@ nsScriptSecurityManager::CheckSameOriginPrincipalInternal(nsIPrincipal* aSubject
|
|||
if (aSubject == aObject)
|
||||
return NS_OK;
|
||||
|
||||
// These booleans are only used when !aIsCheckConnect. Default
|
||||
// them to false, and change if that turns out wrong.
|
||||
PRBool subjectSetDomain = PR_FALSE;
|
||||
PRBool objectSetDomain = PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIURI> subjectURI;
|
||||
nsCOMPtr<nsIURI> objectURI;
|
||||
|
||||
if (aIsCheckConnect)
|
||||
{
|
||||
// Don't use domain for CheckConnect calls, since that's called for
|
||||
|
@ -864,12 +861,18 @@ nsScriptSecurityManager::CheckSameOriginPrincipalInternal(nsIPrincipal* aSubject
|
|||
else
|
||||
{
|
||||
aSubject->GetDomain(getter_AddRefs(subjectURI));
|
||||
if (!subjectURI)
|
||||
if (!subjectURI) {
|
||||
aSubject->GetURI(getter_AddRefs(subjectURI));
|
||||
} else {
|
||||
subjectSetDomain = PR_TRUE;
|
||||
}
|
||||
|
||||
aObject->GetDomain(getter_AddRefs(objectURI));
|
||||
if (!objectURI)
|
||||
if (!objectURI) {
|
||||
aObject->GetURI(getter_AddRefs(objectURI));
|
||||
} else {
|
||||
objectSetDomain = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool isSameOrigin = PR_FALSE;
|
||||
|
@ -888,37 +891,8 @@ nsScriptSecurityManager::CheckSameOriginPrincipalInternal(nsIPrincipal* aSubject
|
|||
if (aIsCheckConnect)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIURI> subjectDomain;
|
||||
aSubject->GetDomain(getter_AddRefs(subjectDomain));
|
||||
|
||||
nsCOMPtr<nsIURI> objectDomain;
|
||||
aObject->GetDomain(getter_AddRefs(objectDomain));
|
||||
|
||||
// If both or neither explicitly set their domain, allow the access
|
||||
if (!subjectDomain == !objectDomain)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Allow access to about:blank, except from null principals (which
|
||||
// never have access to anything but themselves). If SchemeIs
|
||||
// fails, just deny access -- better safe than sorry.
|
||||
// XXXbz when this gets removed, also remove the asymmetry between
|
||||
// aSourceURI and aTargetURI in SecurityCompareURIs.
|
||||
// XXXbz once this is removed, we can probably just make
|
||||
// nsPrincipal::Equals call CheckSameOriginPrincipal(), which will also
|
||||
// make sure it hits the domain check above. At the same time as we remove
|
||||
// this we should also be able to remove the about:blank hackery in
|
||||
// nsPrincipal::Subsumes.
|
||||
PRBool nullSubject = PR_FALSE;
|
||||
// Subject URI could be null here....
|
||||
if (subjectURI) {
|
||||
rv = subjectURI->SchemeIs(NS_NULLPRINCIPAL_SCHEME, &nullSubject);
|
||||
}
|
||||
if (NS_SUCCEEDED(rv) && !nullSubject) {
|
||||
nsXPIDLCString origin;
|
||||
rv = aObject->GetOrigin(getter_Copies(origin));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (nsCRT::strcasecmp(origin, "moz-safe-about:blank") == 0)
|
||||
if (subjectSetDomain == objectSetDomain)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -91,8 +91,8 @@ class nsIDocumentObserver;
|
|||
|
||||
// IID for the nsIDocument interface
|
||||
#define NS_IDOCUMENT_IID \
|
||||
{ 0x63f0c69a, 0x255a, 0x432f, \
|
||||
{ 0xa7, 0xe4, 0xaf, 0x81, 0x10, 0x56, 0x28, 0xef } }
|
||||
{ 0x3a5ce97e, 0x4f41, 0x42ef, \
|
||||
{ 0xa7, 0xc9, 0xcc, 0x3d, 0x4e, 0x7a, 0x3d, 0x00 } }
|
||||
|
||||
// Flag for AddStyleSheet().
|
||||
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
|
||||
|
@ -112,6 +112,7 @@ public:
|
|||
: nsINode(nsnull),
|
||||
mCharacterSet(NS_LITERAL_CSTRING("ISO-8859-1")),
|
||||
mNodeInfoManager(nsnull),
|
||||
mIsInitialDocumentInWindow(PR_FALSE),
|
||||
mPartID(0)
|
||||
{
|
||||
mParentPtrBits |= PARENT_BIT_INDOCUMENT;
|
||||
|
@ -286,6 +287,24 @@ public:
|
|||
mBidiEnabled = aBidiEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ask this document whether it's the initial document in its window.
|
||||
*/
|
||||
PRBool IsInitialDocument() const
|
||||
{
|
||||
return mIsInitialDocumentInWindow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell this document that it's the initial document in its window. See
|
||||
* comments on mIsInitialDocumentInWindow for when this should be called.
|
||||
*/
|
||||
void SetIsInitialDocument(PRBool aIsInitialDocument)
|
||||
{
|
||||
mIsInitialDocumentInWindow = aIsInitialDocument;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the bidi options for this document.
|
||||
* @see nsBidiUtils.h
|
||||
|
@ -829,7 +848,13 @@ protected:
|
|||
nsPropertyTable mPropertyTable;
|
||||
|
||||
// True if BIDI is enabled.
|
||||
PRBool mBidiEnabled;
|
||||
PRPackedBool mBidiEnabled;
|
||||
|
||||
// True if this document is the initial document for a window. This should
|
||||
// basically be true only for documents that exist in newly-opened windows or
|
||||
// documents created to satisfy a GetDocument() on a window when there's no
|
||||
// document in it.
|
||||
PRPackedBool mIsInitialDocumentInWindow;
|
||||
|
||||
// The bidi options for this document. What this bitfield means is
|
||||
// defined in nsBidiUtils.h
|
||||
|
|
|
@ -189,6 +189,13 @@ nsFrameLoader::LoadURI(nsIURI* aURI)
|
|||
// load instead of just forcing the system principal. That way if we have
|
||||
// something loaded already the principal used will be that of what we
|
||||
// already have loaded.
|
||||
|
||||
// XXX bz I'd love to nix this, but the problem is chrome calling
|
||||
// setAttribute() on an iframe or browser and passing in a javascript: URI.
|
||||
// We probably don't want to run that with chrome privileges... Though in
|
||||
// similar circumstances, if one sets window.location.href from chrome we
|
||||
// _do_ run that with chrome privileges, so maybe we should do the same
|
||||
// here?
|
||||
loadInfo->SetInheritOwner(PR_TRUE);
|
||||
|
||||
// Also, in this case we don't set a referrer, just in case.
|
||||
|
|
|
@ -2020,9 +2020,22 @@ nsHTMLDocument::OpenCommon(const nsACString& aContentType, PRBool aReplace)
|
|||
// Remember the old scope in case the call to SetNewDocument changes it.
|
||||
nsCOMPtr<nsIScriptGlobalObject> oldScope(do_QueryReferent(mScopeObject));
|
||||
|
||||
// If callerPrincipal doesn't match our principal. make sure that
|
||||
// SetNewDocument gives us a new inner window and clears our scope.
|
||||
if (!callerPrincipal ||
|
||||
NS_FAILED(nsContentUtils::GetSecurityManager()->
|
||||
CheckSameOriginPrincipal(callerPrincipal, NodePrincipal()))) {
|
||||
SetIsInitialDocument(PR_FALSE);
|
||||
}
|
||||
|
||||
rv = window->SetNewDocument(this, nsnull, PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Now make sure we're not flagged as the initial document anymore, now
|
||||
// that we've had stuff done to us. From now on, if anyone tries to
|
||||
// document.open() us, they get a new inner window.
|
||||
SetIsInitialDocument(PR_FALSE);
|
||||
|
||||
nsCOMPtr<nsIScriptGlobalObject> newScope(do_QueryReferent(mScopeObject));
|
||||
if (oldScope && newScope != oldScope) {
|
||||
nsContentUtils::ReparentContentWrappersInScope(oldScope, newScope);
|
||||
|
@ -2340,36 +2353,6 @@ nsHTMLDocument::ScriptWriteCommon(PRBool aNewlineTerminate)
|
|||
GetCurrentNativeCallContext(getter_AddRefs(ncc));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCAutoString spec;
|
||||
|
||||
if (mDocumentURI) {
|
||||
rv = mDocumentURI->GetSpec(spec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
if (!mDocumentURI || spec.EqualsLiteral("about:blank")) {
|
||||
// The current document's URI and principal are empty or "about:blank".
|
||||
// By writing to this document, the script acquires responsibility for the
|
||||
// document for security purposes. Thus a document.write of a script tag
|
||||
// ends up producing a script with the same principals as the script
|
||||
// that performed the write.
|
||||
nsIScriptSecurityManager *secMan = nsContentUtils::GetSecurityManager();
|
||||
|
||||
nsCOMPtr<nsIPrincipal> subject;
|
||||
rv = secMan->GetSubjectPrincipal(getter_AddRefs(subject));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (subject) {
|
||||
nsCOMPtr<nsIURI> subjectURI;
|
||||
subject->GetURI(getter_AddRefs(subjectURI));
|
||||
|
||||
if (subjectURI) {
|
||||
mDocumentURI = subjectURI;
|
||||
SetPrincipal(subject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ncc) {
|
||||
// We're called from JS, concatenate the extra arguments into
|
||||
// string_buffer
|
||||
|
|
|
@ -3245,21 +3245,20 @@ nsDocShell::Reload(PRUint32 aReloadFlags)
|
|||
rv = LoadHistoryEntry(mLSHE, loadType);
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIDOMDocument> domDoc(do_GetInterface(GetAsSupports(this)));
|
||||
nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDoc));
|
||||
|
||||
nsIPrincipal* principal = nsnull;
|
||||
nsAutoString contentTypeHint;
|
||||
nsCOMPtr<nsIDOMWindow> window(do_GetInterface((nsIDocShell*)this));
|
||||
if (window) {
|
||||
nsCOMPtr<nsIDOMDocument> document;
|
||||
window->GetDocument(getter_AddRefs(document));
|
||||
nsCOMPtr<nsIDOMNSDocument> doc(do_QueryInterface(document));
|
||||
if (doc) {
|
||||
doc->GetContentType(contentTypeHint);
|
||||
}
|
||||
if (doc) {
|
||||
principal = doc->NodePrincipal();
|
||||
doc->GetContentType(contentTypeHint);
|
||||
}
|
||||
|
||||
rv = InternalLoad(mCurrentURI,
|
||||
mReferrerURI,
|
||||
nsnull, // No owner
|
||||
INTERNAL_LOAD_FLAGS_INHERIT_OWNER, // Inherit owner from document
|
||||
principal,
|
||||
INTERNAL_LOAD_FLAGS_NONE, // Do not inherit owner from document
|
||||
nsnull, // No window target
|
||||
NS_LossyConvertUTF16toASCII(contentTypeHint).get(),
|
||||
nsnull, // No post data
|
||||
|
@ -4919,7 +4918,35 @@ nsDocShell::EnsureContentViewer()
|
|||
if (mIsBeingDestroyed)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return CreateAboutBlankContentViewer();
|
||||
nsIPrincipal* principal = nsnull;
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> piDOMWindow(do_QueryInterface(mScriptGlobal));
|
||||
if (piDOMWindow) {
|
||||
principal = piDOMWindow->GetOpenerScriptPrincipal();
|
||||
}
|
||||
|
||||
if (!principal) {
|
||||
principal = GetInheritedPrincipal(PR_FALSE);
|
||||
}
|
||||
|
||||
nsresult rv = CreateAboutBlankContentViewer();
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
mContentViewer->GetDOMDocument(getter_AddRefs(domDoc));
|
||||
nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDoc));
|
||||
NS_ASSERTION(doc,
|
||||
"Should have doc if CreateAboutBlankContentViewer "
|
||||
"succeeded!");
|
||||
|
||||
doc->SetIsInitialDocument(PR_TRUE);
|
||||
|
||||
if (principal) {
|
||||
doc->SetPrincipal(principal);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -6328,10 +6355,23 @@ nsDocShell::InternalLoad(nsIURI * aURI,
|
|||
|
||||
nsCOMPtr<nsISupports> owner(aOwner);
|
||||
//
|
||||
// Get an owner from the current document if necessary
|
||||
// Get an owner from the current document if necessary. Note that we only
|
||||
// do this for URIs that inherit a security context; in particular we do
|
||||
// NOT do this for about:blank. This way, random about:blank loads that
|
||||
// have no owner (which basically means they were done by someone from
|
||||
// chrome manually messing with our nsIWebNavigation or by C++ setting
|
||||
// document.location) don't get a funky principal. If callers want
|
||||
// something interesting to happen with the about:blank principal in this
|
||||
// case, they should pass an owner in.
|
||||
//
|
||||
if (!owner && (aFlags & INTERNAL_LOAD_FLAGS_INHERIT_OWNER))
|
||||
GetCurrentDocumentOwner(getter_AddRefs(owner));
|
||||
{
|
||||
PRBool inherits;
|
||||
if (!owner && (aFlags & INTERNAL_LOAD_FLAGS_INHERIT_OWNER) &&
|
||||
NS_SUCCEEDED(URIInheritsSecurityContext(aURI, &inherits)) &&
|
||||
inherits) {
|
||||
owner = GetInheritedPrincipal(PR_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Resolve the window target before going any further...
|
||||
|
@ -6339,6 +6379,11 @@ nsDocShell::InternalLoad(nsIURI * aURI,
|
|||
// load to it...
|
||||
//
|
||||
if (aWindowTarget && *aWindowTarget) {
|
||||
// We've already done our owner-inheriting. Mask out that bit, so we
|
||||
// don't try inheriting an owner from the target window if we came up
|
||||
// with a null owner above.
|
||||
aFlags = aFlags & ~INTERNAL_LOAD_FLAGS_INHERIT_OWNER;
|
||||
|
||||
// Locate the target DocShell.
|
||||
// This may involve creating a new toplevel window - if necessary.
|
||||
//
|
||||
|
@ -6724,42 +6769,51 @@ nsDocShell::InternalLoad(nsIURI * aURI,
|
|||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocShell::GetCurrentDocumentOwner(nsISupports ** aOwner)
|
||||
nsIPrincipal*
|
||||
nsDocShell::GetInheritedPrincipal(PRBool aConsiderCurrentDocument)
|
||||
{
|
||||
*aOwner = nsnull;
|
||||
nsCOMPtr<nsIDocument> document;
|
||||
//-- Get the current document
|
||||
if (mContentViewer) {
|
||||
|
||||
if (aConsiderCurrentDocument && mContentViewer) {
|
||||
nsCOMPtr<nsIDocumentViewer>
|
||||
docViewer(do_QueryInterface(mContentViewer));
|
||||
if (!docViewer)
|
||||
return;
|
||||
return nsnull;
|
||||
docViewer->GetDocument(getter_AddRefs(document));
|
||||
}
|
||||
else //-- If there's no document loaded yet, look at the parent (frameset)
|
||||
{
|
||||
|
||||
if (!document) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> parentItem;
|
||||
GetSameTypeParent(getter_AddRefs(parentItem));
|
||||
if (!parentItem)
|
||||
return;
|
||||
nsCOMPtr<nsIDOMWindowInternal>
|
||||
parentWindow(do_GetInterface(parentItem));
|
||||
if (!parentWindow)
|
||||
return;
|
||||
nsCOMPtr<nsIDOMDocument> parentDomDoc;
|
||||
parentWindow->GetDocument(getter_AddRefs(parentDomDoc));
|
||||
if (!parentDomDoc)
|
||||
return;
|
||||
document = do_QueryInterface(parentDomDoc);
|
||||
if (parentItem) {
|
||||
nsCOMPtr<nsIDOMDocument> parentDomDoc(do_GetInterface(parentItem));
|
||||
document = do_QueryInterface(parentDomDoc);
|
||||
}
|
||||
}
|
||||
|
||||
if (!document) {
|
||||
if (!aConsiderCurrentDocument) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// Make sure we end up with _something_ as the principal no matter
|
||||
// what.
|
||||
EnsureContentViewer(); // If this fails, we'll just get a null
|
||||
// docViewer and bail.
|
||||
|
||||
nsCOMPtr<nsIDocumentViewer>
|
||||
docViewer(do_QueryInterface(mContentViewer));
|
||||
if (!docViewer)
|
||||
return nsnull;
|
||||
docViewer->GetDocument(getter_AddRefs(document));
|
||||
}
|
||||
|
||||
//-- Get the document's principal
|
||||
if (document) {
|
||||
*aOwner = document->NodePrincipal();
|
||||
return document->NodePrincipal();
|
||||
}
|
||||
|
||||
NS_IF_ADDREF(*aOwner);
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -6927,19 +6981,22 @@ nsDocShell::DoURILoad(nsIURI * aURI,
|
|||
// provide their own security context.
|
||||
//
|
||||
// XXX: Is seems wrong that the owner is ignored - even if one is
|
||||
// supplied) unless the URI is javascript or data.
|
||||
// supplied) unless the URI is javascript or data or about:blank.
|
||||
// XXX: If this is ever changed, check all callers for what owners they're
|
||||
// passing in. In particular, see the code and comments in LoadURI
|
||||
// where we get the current document principal as the owner if called
|
||||
// where we fall back on inheriting the owner if called
|
||||
// from chrome. That would be very wrong if this code changed
|
||||
// anything but channels that can't provide their own security context!
|
||||
//
|
||||
// (Currently chrome URIs set the owner when they are created!
|
||||
// So setting a NULL owner would be bad!)
|
||||
//
|
||||
|
||||
PRBool inherit;
|
||||
// We expect URIInheritsSecurityContext to return success for an
|
||||
// about:blank URI, so don't call IsAboutBlank() if this call fails.
|
||||
rv = URIInheritsSecurityContext(aURI, &inherit);
|
||||
if (NS_SUCCEEDED(rv) && inherit) {
|
||||
if (NS_SUCCEEDED(rv) && (inherit || IsAboutBlank(aURI))) {
|
||||
channel->SetOwner(aOwner);
|
||||
}
|
||||
|
||||
|
@ -8815,9 +8872,27 @@ nsDocShell::Observe(nsISupports *aSubject, const char *aTopic,
|
|||
nsresult
|
||||
nsDocShell::URIInheritsSecurityContext(nsIURI* aURI, PRBool* aResult)
|
||||
{
|
||||
// Need to add explicit check for about:blank here too, in the
|
||||
// future. See bug 332182.
|
||||
// Note: about:blank URIs do NOT inherit the security context from the
|
||||
// current document, which is what this function tests for...
|
||||
return NS_URIChainHasFlags(aURI,
|
||||
nsIProtocolHandler::URI_HAS_NO_SECURITY_CONTEXT,
|
||||
aResult);
|
||||
}
|
||||
|
||||
/* static */
|
||||
PRBool
|
||||
nsDocShell::IsAboutBlank(nsIURI* aURI)
|
||||
{
|
||||
NS_PRECONDITION(aURI, "Must have URI");
|
||||
|
||||
// GetSpec can be expensive for some URIs, so check the scheme first.
|
||||
PRBool isAbout = PR_FALSE;
|
||||
if (NS_FAILED(aURI->SchemeIs("about", &isAbout)) || !isAbout) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsCAutoString str;
|
||||
aURI->GetSpec(str);
|
||||
return str.EqualsLiteral("about:blank");
|
||||
}
|
||||
|
||||
|
|
|
@ -231,7 +231,18 @@ protected:
|
|||
void SetupReferrerFromChannel(nsIChannel * aChannel);
|
||||
|
||||
NS_IMETHOD GetEldestPresContext(nsPresContext** aPresContext);
|
||||
void GetCurrentDocumentOwner(nsISupports ** aOwner);
|
||||
|
||||
// Get the principal that we'll set on the channel if we're inheriting. If
|
||||
// aConsiderCurrentDocument is true, we try to use the current document if
|
||||
// at all possible. If that fails, we fall back on the parent document.
|
||||
// If that fails too, we force creation of a content viewer and use the
|
||||
// resulting principal. If aConsiderCurrentDocument is false, we just look
|
||||
// at the parent.
|
||||
nsIPrincipal* GetInheritedPrincipal(PRBool aConsiderCurrentDocument);
|
||||
|
||||
// Actually open a channel and perform a URI load. Note: whatever owner is
|
||||
// passed to this function will be set on the channel. Callers who wish to
|
||||
// not have an owner on the channel should just pass null.
|
||||
virtual nsresult DoURILoad(nsIURI * aURI,
|
||||
nsIURI * aReferrer,
|
||||
PRBool aSendReferrer,
|
||||
|
@ -462,6 +473,9 @@ protected:
|
|||
|
||||
// Check whether aURI should inherit our security context
|
||||
static nsresult URIInheritsSecurityContext(nsIURI* aURI, PRBool* aResult);
|
||||
|
||||
// Check whether aURI is about:blank
|
||||
static PRBool IsAboutBlank(nsIURI* aURI);
|
||||
|
||||
protected:
|
||||
// Override the parent setter from nsDocLoader
|
||||
|
|
|
@ -72,9 +72,8 @@ class nsPresContext;
|
|||
struct nsTimeout;
|
||||
|
||||
#define NS_PIDOMWINDOW_IID \
|
||||
{ /* 4602B87E-879E-49D1-96FE-C87FDD915348} */ \
|
||||
0x4602b87e, 0x879e, 0x49d1, \
|
||||
{ 0x96, 0xfe, 0xc8, 0x7f, 0xdd, 0x91, 0x53, 0x48 } }
|
||||
{ 0xbebce53b, 0xa4ec, 0x49e5, \
|
||||
{ 0x82, 0x8e, 0x23, 0x08, 0x61, 0x2b, 0x41, 0x9b } }
|
||||
|
||||
class nsPIDOMWindow : public nsIDOMWindowInternal
|
||||
{
|
||||
|
@ -245,7 +244,14 @@ public:
|
|||
return win->mIsHandlingResizeEvent;
|
||||
}
|
||||
|
||||
// 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,
|
||||
PRBool aForce) const = 0;
|
||||
|
|
|
@ -305,6 +305,22 @@ static const char sJSStackContractID[] = "@mozilla.org/js/xpc/ContextStack;1";
|
|||
static const char kCryptoContractID[] = NS_CRYPTO_CONTRACTID;
|
||||
static const char kPkcs11ContractID[] = NS_PKCS11_CONTRACTID;
|
||||
|
||||
static PRBool
|
||||
IsAboutBlank(nsIURI* aURI)
|
||||
{
|
||||
NS_PRECONDITION(aURI, "Must have URI");
|
||||
|
||||
// GetSpec can be expensive for some URIs, so check the scheme first.
|
||||
PRBool isAbout = PR_FALSE;
|
||||
if (NS_FAILED(aURI->SchemeIs("about", &isAbout)) || !isAbout) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsCAutoString str;
|
||||
aURI->GetSpec(str);
|
||||
return str.EqualsLiteral("about:blank");
|
||||
}
|
||||
|
||||
/**
|
||||
* An indirect observer object that means we don't have to implement nsIObserver
|
||||
* on nsGlobalWindow, where any script could see it.
|
||||
|
@ -779,45 +795,35 @@ PRBool
|
|||
nsGlobalWindow::WouldReuseInnerWindow(nsIDocument *aNewDocument)
|
||||
{
|
||||
// We reuse the inner window when:
|
||||
// a. We are currently at about:blank
|
||||
// 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 URI has the same origin as the script opener uri for our current
|
||||
// window.
|
||||
// -- The new document has the same origin as what we have loaded right now.
|
||||
|
||||
if (!mDoc || !aNewDocument) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsIURI* curURI = mDoc->GetDocumentURI();
|
||||
if (!curURI) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool isAbout;
|
||||
if (NS_FAILED(curURI->SchemeIs("about", &isAbout)) || !isAbout) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsCAutoString uri;
|
||||
curURI->GetSpec(uri);
|
||||
if (!uri.EqualsLiteral("about:blank")) {
|
||||
if (!mDoc->IsInitialDocument()) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Great, we're an about:blank document, check for one of the other
|
||||
NS_ASSERTION(IsAboutBlank(mDoc->GetDocumentURI()),
|
||||
"How'd this happen?");
|
||||
|
||||
// Great, we're the original document, check for one of the other
|
||||
// conditions.
|
||||
if (mDoc == aNewDocument) {
|
||||
// aClearScopeHint is false.
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if (mOpenerScriptPrincipal && nsContentUtils::GetSecurityManager() &&
|
||||
if (nsContentUtils::GetSecurityManager() &&
|
||||
NS_SUCCEEDED(nsContentUtils::GetSecurityManager()->
|
||||
CheckSameOriginPrincipal(mOpenerScriptPrincipal,
|
||||
CheckSameOriginPrincipal(mDoc->NodePrincipal(),
|
||||
aNewDocument->NodePrincipal()))) {
|
||||
// The origin is the same.
|
||||
return PR_TRUE;
|
||||
|
@ -842,9 +848,39 @@ nsGlobalWindow::SetOpenerScriptPrincipal(nsIPrincipal* aPrincipal)
|
|||
{
|
||||
FORWARD_TO_OUTER_VOID(SetOpenerScriptPrincipal, (aPrincipal));
|
||||
|
||||
if (mDoc) {
|
||||
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
|
||||
// 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 && IsAboutBlank(uri) &&
|
||||
IsAboutBlank(mDoc->GetDocumentURI()),
|
||||
"Unexpected original document");
|
||||
#endif
|
||||
|
||||
// Set the opener principal on our document; given the above check, this
|
||||
// is safe.
|
||||
mDoc->SetPrincipal(aPrincipal);
|
||||
}
|
||||
|
||||
mOpenerScriptPrincipal = aPrincipal;
|
||||
}
|
||||
|
||||
nsIPrincipal*
|
||||
nsGlobalWindow::GetOpenerScriptPrincipal()
|
||||
{
|
||||
FORWARD_TO_OUTER(GetOpenerScriptPrincipal, (), nsnull);
|
||||
|
||||
return mOpenerScriptPrincipal;
|
||||
}
|
||||
|
||||
PopupControlState
|
||||
PushPopupControlState(PopupControlState aState, PRBool aForce)
|
||||
{
|
||||
|
@ -1667,6 +1703,8 @@ nsGlobalWindow::SetOpenerWindow(nsIDOMWindowInternal* aOpener,
|
|||
NS_ASSERTION(!aOriginalOpener || !mSetOpenerWindowCalled,
|
||||
"aOriginalOpener is true, but not first call to "
|
||||
"SetOpenerWindow!");
|
||||
NS_ASSERTION(aOpener || !aOriginalOpener,
|
||||
"Shouldn't set mHadOriginalOpener if aOpener is null");
|
||||
|
||||
mOpener = aOpener;
|
||||
if (aOriginalOpener) {
|
||||
|
@ -3533,6 +3571,7 @@ nsGlobalWindow::Focus()
|
|||
if (mDocShell) {
|
||||
// Don't look for a presshell if we're a root chrome window that's got
|
||||
// about:blank loaded. We don't want to focus our widget in that case.
|
||||
// XXXbz should we really be checking for IsInitialDocument() instead?
|
||||
PRBool lookForPresShell = PR_TRUE;
|
||||
PRInt32 itemType = nsIDocShellTreeItem::typeContent;
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(mDocShell));
|
||||
|
@ -3544,12 +3583,8 @@ nsGlobalWindow::Focus()
|
|||
nsCOMPtr<nsIDocument> doc(do_QueryInterface(mDocument));
|
||||
NS_ASSERTION(doc, "Bogus doc?");
|
||||
nsIURI* ourURI = doc->GetDocumentURI();
|
||||
PRBool isAbout;
|
||||
if (ourURI && NS_SUCCEEDED(ourURI->SchemeIs("about", &isAbout)) &&
|
||||
isAbout) {
|
||||
nsCAutoString spec;
|
||||
ourURI->GetSpec(spec);
|
||||
lookForPresShell = !spec.EqualsLiteral("about:blank");
|
||||
if (ourURI) {
|
||||
lookForPresShell = !IsAboutBlank(ourURI);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6045,63 +6080,42 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
|
|||
|
||||
// success!
|
||||
|
||||
if (domReturn) {
|
||||
// Save the principal of the calling script
|
||||
// We need it to decide whether to clear the scope in SetNewDocument
|
||||
NS_ASSERTION(nsContentUtils::GetSecurityManager(),
|
||||
"No Security Manager Found!");
|
||||
// Note that the opener script principal is not relevant for openDialog
|
||||
// callers, since those already have chrome privileges. So we
|
||||
// only want to do this when aDoJSFixups is true.
|
||||
if (aDoJSFixups && nsContentUtils::GetSecurityManager()) {
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
nsContentUtils::GetSecurityManager()->
|
||||
GetSubjectPrincipal(getter_AddRefs(principal));
|
||||
if (principal) {
|
||||
nsCOMPtr<nsPIDOMWindow> domReturnPrivate(do_QueryInterface(domReturn));
|
||||
domReturnPrivate->SetOpenerScriptPrincipal(principal);
|
||||
}
|
||||
}
|
||||
domReturn.swap(*aReturn);
|
||||
|
||||
domReturn.swap(*aReturn);
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (aDoJSFixups) {
|
||||
nsCOMPtr<nsIDOMChromeWindow> chrome_win(do_QueryInterface(*aReturn));
|
||||
if (!chrome_win) {
|
||||
// A new non-chrome window was created from a call to
|
||||
// window.open() from JavaScript, make sure there's a document in
|
||||
// the new window. We do this by simply asking the new window for
|
||||
// its document, this will synchronously create an empty document
|
||||
// if there is no document in the window.
|
||||
// XXXbz should this just use EnsureInnerWindow()?
|
||||
if (aDoJSFixups) {
|
||||
nsCOMPtr<nsIDOMChromeWindow> chrome_win(do_QueryInterface(*aReturn));
|
||||
if (!chrome_win) {
|
||||
// A new non-chrome window was created from a call to
|
||||
// window.open() from JavaScript, make sure there's a document in
|
||||
// the new window. We do this by simply asking the new window for
|
||||
// its document, this will synchronously create an empty document
|
||||
// if there is no document in the window.
|
||||
// XXXbz should this just use EnsureInnerWindow()?
|
||||
#ifdef DEBUG_jst
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> pidomwin(do_QueryInterface(*aReturn));
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> pidomwin(do_QueryInterface(*aReturn));
|
||||
|
||||
nsIDOMDocument *temp = pidomwin->GetExtantDocument();
|
||||
nsIDOMDocument *temp = pidomwin->GetExtantDocument();
|
||||
|
||||
NS_ASSERTION(temp, "No document in new window!!!");
|
||||
}
|
||||
NS_ASSERTION(temp, "No document in new window!!!");
|
||||
}
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> doc;
|
||||
(*aReturn)->GetDocument(getter_AddRefs(doc));
|
||||
}
|
||||
nsCOMPtr<nsIDOMDocument> doc;
|
||||
(*aReturn)->GetDocument(getter_AddRefs(doc));
|
||||
}
|
||||
}
|
||||
|
||||
if (checkForPopup) {
|
||||
if (abuseLevel >= openControlled) {
|
||||
nsGlobalWindow *opened = NS_STATIC_CAST(nsGlobalWindow *, *aReturn);
|
||||
if (!opened->IsPopupSpamWindow()) {
|
||||
opened->SetPopupSpamWindow(PR_TRUE);
|
||||
++gOpenPopupSpamCount;
|
||||
}
|
||||
if (checkForPopup) {
|
||||
if (abuseLevel >= openControlled) {
|
||||
nsGlobalWindow *opened = NS_STATIC_CAST(nsGlobalWindow *, *aReturn);
|
||||
if (!opened->IsPopupSpamWindow()) {
|
||||
opened->SetPopupSpamWindow(PR_TRUE);
|
||||
++gOpenPopupSpamCount;
|
||||
}
|
||||
if (abuseLevel >= openAbused)
|
||||
FireAbuseEvents(PR_FALSE, PR_TRUE, aUrl, aName, aOptions);
|
||||
}
|
||||
if (abuseLevel >= openAbused)
|
||||
FireAbuseEvents(PR_FALSE, PR_TRUE, aUrl, aName, aOptions);
|
||||
}
|
||||
|
||||
// copy the session storage data over to the new window if
|
||||
|
|
|
@ -237,6 +237,7 @@ public:
|
|||
virtual NS_HIDDEN_(nsIFocusController*) GetRootFocusController();
|
||||
|
||||
virtual NS_HIDDEN_(void) SetOpenerScriptPrincipal(nsIPrincipal* aPrincipal);
|
||||
virtual NS_HIDDEN_(nsIPrincipal*) GetOpenerScriptPrincipal();
|
||||
|
||||
virtual NS_HIDDEN_(PopupControlState) PushPopupControlState(PopupControlState state, PRBool aForce) const;
|
||||
virtual NS_HIDDEN_(void) PopPopupControlState(PopupControlState state) const;
|
||||
|
|
|
@ -200,10 +200,8 @@ nsresult nsJSThunk::EvaluateScript(nsIChannel *aChannel)
|
|||
if (!principal)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
//-- Don't run if the script principal is different from the
|
||||
// principal of the context, with two exceptions: we allow
|
||||
// the script to run if the script has the system principal
|
||||
// or the context is about:blank.
|
||||
//-- Don't run if the script principal is different from the principal
|
||||
// of the context, unless the script has the system principal.
|
||||
nsCOMPtr<nsIPrincipal> objectPrincipal;
|
||||
rv = securityManager->GetObjectPrincipal(
|
||||
(JSContext*)scriptContext->GetNativeContext(),
|
||||
|
@ -231,38 +229,12 @@ nsresult nsJSThunk::EvaluateScript(nsIChannel *aChannel)
|
|||
}
|
||||
}
|
||||
else {
|
||||
// No owner from channel, use the object principals.
|
||||
rv = securityManager->GetObjectPrincipal(
|
||||
(JSContext*)scriptContext->GetNativeContext(),
|
||||
globalJSObject,
|
||||
getter_AddRefs(principal));
|
||||
|
||||
// Paranoia check: If we don't have an owner, make sure that we're
|
||||
// not giving this javascript URL the principals of some other
|
||||
// random page, so if the principals aren't for about:blank, don't use
|
||||
// them.
|
||||
// XXX We can't just create new about:blank principals since caps
|
||||
// refuses to treat two about:blank principals as equal.
|
||||
if (principal) {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = principal->GetURI(getter_AddRefs(uri));
|
||||
if (!uri) {
|
||||
rv = NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCAutoString spec;
|
||||
uri->GetSpec(spec);
|
||||
if (!spec.EqualsLiteral("about:blank")) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv) || !principal) {
|
||||
// If all else fails, use a null principal
|
||||
principal = do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
|
||||
}
|
||||
// No owner from channel, use the null principal for lack of anything
|
||||
// better. Note that we do not use the object principal here because
|
||||
// that would give the javascript: URL the principals of whatever page
|
||||
// we might be remotely associated with, which is a good recipe for XSS
|
||||
// issues.
|
||||
principal = do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
|
||||
|
||||
if (NS_FAILED(rv) || !principal) {
|
||||
return NS_ERROR_FAILURE;
|
||||
|
|
|
@ -63,6 +63,7 @@ REQUIRES = xpcom \
|
|||
embed_base \
|
||||
intl \
|
||||
layout \
|
||||
uriloader \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = nsPrompt.cpp \
|
||||
|
|
|
@ -53,11 +53,13 @@
|
|||
#include "nsIDocShellLoadInfo.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsIDocShellTreeOwner.h"
|
||||
#include "nsIDocumentLoader.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIDOMChromeWindow.h"
|
||||
#include "nsIDOMWindowInternal.h"
|
||||
#include "nsIScriptObjectPrincipal.h"
|
||||
#include "nsIScreen.h"
|
||||
#include "nsIScreenManager.h"
|
||||
#include "nsIScriptContext.h"
|
||||
|
@ -793,6 +795,42 @@ nsWindowWatcher::OpenWindowJSInternal(nsIDOMWindow *aParent,
|
|||
}
|
||||
}
|
||||
|
||||
// Now we have to set the right opener principal on the new window. Note
|
||||
// that we have to do this _before_ starting any URI loads, thanks to the
|
||||
// sync nature of javascript: loads. Since this is the only place where we
|
||||
// set said opener principal, we need to do it for all URIs, including
|
||||
// chrome ones. So to deal with the mess that is bug 79775, just press on in
|
||||
// a reasonable way even if GetSubjectPrincipal fails. In that case, just
|
||||
// use a null subjectPrincipal.
|
||||
nsCOMPtr<nsIPrincipal> subjectPrincipal;
|
||||
if (NS_FAILED(sm->GetSubjectPrincipal(getter_AddRefs(subjectPrincipal)))) {
|
||||
subjectPrincipal = nsnull;
|
||||
}
|
||||
|
||||
if (windowIsNew) {
|
||||
// Now set the opener principal on the new window. Note that we need to do
|
||||
// this no matter whether we were opened from JS; if there is nothing on
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> newWindow = do_QueryInterface(*_retval);
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsPIDOMWindow> newDebugWindow = do_GetInterface(newDocShell);
|
||||
NS_ASSERTION(newWindow == newDebugWindow, "Different windows??");
|
||||
#endif
|
||||
if (newWindow) {
|
||||
newWindow->SetOpenerScriptPrincipal(newWindowPrincipal);
|
||||
}
|
||||
}
|
||||
|
||||
if (uriToLoad) { // get the script principal and pass it to docshell
|
||||
JSContextAutoPopper contextGuard;
|
||||
|
||||
|
@ -812,15 +850,8 @@ nsWindowWatcher::OpenWindowJSInternal(nsIDOMWindow *aParent,
|
|||
newDocShell->CreateLoadInfo(getter_AddRefs(loadInfo));
|
||||
NS_ENSURE_TRUE(loadInfo, NS_ERROR_FAILURE);
|
||||
|
||||
if (!uriToLoadIsChrome) {
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
if (NS_FAILED(sm->GetSubjectPrincipal(getter_AddRefs(principal))))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (principal) {
|
||||
nsCOMPtr<nsISupports> owner(do_QueryInterface(principal));
|
||||
loadInfo->SetOwner(owner);
|
||||
}
|
||||
if (subjectPrincipal) {
|
||||
loadInfo->SetOwner(subjectPrincipal);
|
||||
}
|
||||
|
||||
// Set the new window's referrer from the calling context's document:
|
||||
|
@ -1625,6 +1656,27 @@ nsWindowWatcher::ReadyOpenedDocShellItem(nsIDocShellTreeItem *aOpenedItem,
|
|||
if (aParent) {
|
||||
nsCOMPtr<nsIDOMWindowInternal> internalParent(do_QueryInterface(aParent));
|
||||
piOpenedWindow->SetOpenerWindow(internalParent, aWindowIsNew); // damnit
|
||||
|
||||
if (aWindowIsNew) {
|
||||
#ifdef DEBUG
|
||||
// Assert that we're not loading things right now. If we are, when
|
||||
// that load completes it will clobber whatever principals we set up
|
||||
// on this new window!
|
||||
nsCOMPtr<nsIDocumentLoader> docloader =
|
||||
do_QueryInterface(aOpenedItem);
|
||||
NS_ASSERTION(docloader, "How can we not have a docloader here?");
|
||||
|
||||
nsCOMPtr<nsIChannel> chan;
|
||||
docloader->GetDocumentChannel(getter_AddRefs(chan));
|
||||
NS_ASSERTION(!chan, "Why is there a document channel?");
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIDocument> doc =
|
||||
do_QueryInterface(piOpenedWindow->GetExtantDocument());
|
||||
if (doc) {
|
||||
doc->SetIsInitialDocument(PR_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
rv = CallQueryInterface(piOpenedWindow, aOpenedWindow);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче