Fixing orange on tinderbox. The problem was that when we were tearing down a window and releasing its document we didn't remember the document principals, so any security checks that happened after a window was torn down failed. Partial backout of the fix for bug 296639. r=dbaron@mozilla.org

This commit is contained in:
jst%mozilla.jstenback.com 2005-07-31 16:44:28 +00:00
Родитель 2b423c88c0
Коммит 25b2243cdc
2 изменённых файлов: 41 добавлений и 7 удалений

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

@ -524,6 +524,9 @@ nsGlobalWindow::SetNewDocument(nsIDOMDocument* aDocument,
PRBool aClearScopeHint, PRBool aClearScopeHint,
PRBool aIsInternalCall) PRBool aIsInternalCall)
{ {
NS_WARN_IF_FALSE(mDocumentPrincipal == nsnull,
"mDocumentPrincipal prematurely set!");
if (!aIsInternalCall && IsInnerWindow()) { if (!aIsInternalCall && IsInnerWindow()) {
return GetOuterWindowInternal()->SetNewDocument(aDocument, return GetOuterWindowInternal()->SetNewDocument(aDocument,
aRemoveEventListeners, aRemoveEventListeners,
@ -536,6 +539,11 @@ nsGlobalWindow::SetNewDocument(nsIDOMDocument* aDocument,
return NS_ERROR_INVALID_ARG; return NS_ERROR_INVALID_ARG;
} }
NS_ASSERTION(!GetCurrentInnerWindow() ||
GetCurrentInnerWindow()->GetExtantDocument() == mDocument,
"Uh, mDocument doesn't match the current inner window "
"document!");
nsCOMPtr<nsIDocument> newDoc(do_QueryInterface(aDocument)); nsCOMPtr<nsIDocument> newDoc(do_QueryInterface(aDocument));
NS_ENSURE_TRUE(newDoc, NS_ERROR_FAILURE); NS_ENSURE_TRUE(newDoc, NS_ERROR_FAILURE);
@ -658,12 +666,17 @@ nsGlobalWindow::SetNewDocument(nsIDOMDocument* aDocument,
} }
} }
// Remember the old document's principal.
nsIPrincipal *oldPrincipal = nsnull;
if (oldDoc) {
oldPrincipal = oldDoc->GetPrincipal();
}
// Drop our reference to the navigator object unless we're reusing // Drop our reference to the navigator object unless we're reusing
// the existing inner window or the new document is from the same // the existing inner window or the new document is from the same
// origin as the old document. // origin as the old document.
nsIPrincipal *oldPrincipal; if (!reUseInnerWindow && mNavigator && oldPrincipal) {
if (!reUseInnerWindow && mNavigator && oldDoc &&
(oldPrincipal = oldDoc->GetPrincipal())) {
nsIPrincipal *newPrincipal = newDoc->GetPrincipal(); nsIPrincipal *newPrincipal = newDoc->GetPrincipal();
rv = NS_ERROR_FAILURE; rv = NS_ERROR_FAILURE;
@ -812,9 +825,11 @@ nsGlobalWindow::SetNewDocument(nsIDOMDocument* aDocument,
::JS_ClearRegExpStatics(cx); ::JS_ClearRegExpStatics(cx);
} }
// Make the current inner window release its strong references to // Make the current inner window release its strong references
// the document to prevent it from keeping everything around. // to the document to prevent it from keeping everything
// around. But remember the document's principal.
currentInner->mDocument = nsnull; currentInner->mDocument = nsnull;
currentInner->mDocumentPrincipal = oldPrincipal;
} }
mInnerWindow = newInnerWindow; mInnerWindow = newInnerWindow;
@ -925,11 +940,25 @@ nsGlobalWindow::SetDocShell(nsIDocShell* aDocShell)
::JS_ClearScope(cx, currentInner->mJSObject); ::JS_ClearScope(cx, currentInner->mJSObject);
::JS_ClearWatchPointsForObject(cx, currentInner->mJSObject); ::JS_ClearWatchPointsForObject(cx, currentInner->mJSObject);
if (currentInner->mDocument) {
nsCOMPtr<nsIDocument> doc =
do_QueryInterface(currentInner->mDocument);
// Remember the document's principal.
currentInner->mDocumentPrincipal = doc->GetPrincipal();
}
// Release the current inner window's document references. // Release the current inner window's document references.
currentInner->mDocument = nsnull; currentInner->mDocument = nsnull;
nsWindowSH::InvalidateGlobalScopePolluter(cx, currentInner->mJSObject); nsWindowSH::InvalidateGlobalScopePolluter(cx, currentInner->mJSObject);
} }
nsCOMPtr<nsIDocument> doc =
do_QueryInterface(mDocument);
// Remember the document's principal.
mDocumentPrincipal = doc->GetPrincipal();
// Release the our document reference // Release the our document reference
mDocument = nsnull; mDocument = nsnull;
@ -1322,8 +1351,6 @@ nsGlobalWindow::SetNewArguments(JSObject *aArguments)
nsIPrincipal* nsIPrincipal*
nsGlobalWindow::GetPrincipal() nsGlobalWindow::GetPrincipal()
{ {
// XXXjst: figure out inner window stuff...
if (mDocument) { if (mDocument) {
// If we have a document, get the principal from the document // If we have a document, get the principal from the document
nsCOMPtr<nsIDocument> doc(do_QueryInterface(mDocument)); nsCOMPtr<nsIDocument> doc(do_QueryInterface(mDocument));
@ -1332,6 +1359,10 @@ nsGlobalWindow::GetPrincipal()
return doc->GetPrincipal(); return doc->GetPrincipal();
} }
if (mDocumentPrincipal) {
return mDocumentPrincipal;
}
// If we don't have a principal and we don't have a document we // If we don't have a principal and we don't have a document we
// ask the parent window for the principal. This can happen when // ask the parent window for the principal. This can happen when
// loading a frameset that has a <frame src="javascript:xxx">, in // loading a frameset that has a <frame src="javascript:xxx">, in

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

@ -408,6 +408,9 @@ protected:
// This member variable is used only on the inner window. // This member variable is used only on the inner window.
nsCOMPtr<nsIEventListenerManager> mListenerManager; nsCOMPtr<nsIEventListenerManager> mListenerManager;
// This member variable is used on both inner and the outer windows.
nsCOMPtr<nsIPrincipal> mDocumentPrincipal;
friend class nsDOMScriptableHelper; friend class nsDOMScriptableHelper;
friend class nsDOMWindowUtils; friend class nsDOMWindowUtils;
static nsIScriptSecurityManager *sSecMan; static nsIScriptSecurityManager *sSecMan;