bug 420425 restore frame targeting behavior for local file: apps, r=jst, sr=bzbarsky, blocking1.9+
authordveditz@cruzio.com
Wed, 19 Mar 2008 16:31:56 -0700
changeset 13337 6ccad1c20bbe9e6bcafbd44f0a6682aeb16b03bc
parent 13336 14b5b8491ba3b9538ca85506f62dda04a9a0f393
child 13338 90b0b6262a44356226fb44a60befb3d0783a23f5
push idunknown
push userunknown
push dateunknown
reviewersjst, bzbarsky, blocking1.9
bugs420425
milestone1.9b5pre
bug 420425 restore frame targeting behavior for local file: apps, r=jst, sr=bzbarsky, blocking1.9+
docshell/base/nsDocShell.cpp
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -1021,16 +1021,19 @@ nsDocShell::FirePageHideNotification(PRB
 }
 
 //
 // Bug 13871: Prevent frameset spoofing
 //
 // This routine answers: 'Is origin's document from same domain as
 // target's document?'
 //
+// file: uris are considered the same domain for the purpose of
+// frame navigation regardless of script accessibility (bug 420425)
+//
 /* static */
 PRBool
 nsDocShell::ValidateOrigin(nsIDocShellTreeItem* aOriginTreeItem,
                            nsIDocShellTreeItem* aTargetTreeItem)
 {
     nsCOMPtr<nsIScriptSecurityManager> securityManager =
         do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
     NS_ENSURE_TRUE(securityManager, PR_FALSE);
@@ -1061,20 +1064,42 @@ nsDocShell::ValidateOrigin(nsIDocShellTr
     
     // Get target principal
     nsCOMPtr<nsIDOMDocument> targetDOMDocument =
         do_GetInterface(aTargetTreeItem);
     nsCOMPtr<nsIDocument> targetDocument(do_QueryInterface(targetDOMDocument));
     NS_ENSURE_TRUE(targetDocument, PR_FALSE);
 
     PRBool equal;
-    return
-        NS_SUCCEEDED(originDocument->NodePrincipal()->
-                       Equals(targetDocument->NodePrincipal(), &equal)) &&
-        equal;
+    rv = originDocument->NodePrincipal()->
+            Equals(targetDocument->NodePrincipal(), &equal);
+    if (NS_SUCCEEDED(rv) && equal) {
+        return PR_TRUE;
+    }
+
+    // Not strictly equal, special case if both are file: uris
+    PRBool originIsFile = PR_FALSE;
+    PRBool targetIsFile = PR_FALSE;
+    nsCOMPtr<nsIURI> originURI;
+    nsCOMPtr<nsIURI> targetURI;
+    nsCOMPtr<nsIURI> innerOriginURI;
+    nsCOMPtr<nsIURI> innerTargetURI;
+
+    rv = originDocument->NodePrincipal()->GetURI(getter_AddRefs(originURI));
+    if (NS_SUCCEEDED(rv))
+        innerOriginURI = NS_GetInnermostURI(originURI);
+
+    rv = targetDocument->NodePrincipal()->GetURI(getter_AddRefs(targetURI));
+    if (NS_SUCCEEDED(rv))
+        innerTargetURI = NS_GetInnermostURI(targetURI);
+
+    return innerOriginURI && innerTargetURI &&
+        NS_SUCCEEDED(originURI->SchemeIs("file", &originIsFile)) &&
+        NS_SUCCEEDED(targetURI->SchemeIs("file", &targetIsFile)) &&
+        originIsFile && targetIsFile;
 }
 
 NS_IMETHODIMP
 nsDocShell::GetEldestPresContext(nsPresContext** aPresContext)
 {
     nsresult rv = NS_OK;
 
     NS_ENSURE_ARG_POINTER(aPresContext);
@@ -1910,16 +1935,17 @@ nsDocShell::CanAccessItem(nsIDocShellTre
     // XXXbz should we care if aAccessingItem or the document therein is
     // chrome?  Should those get extra privileges?
 
     // For historical context, see:
     // 
     // Bug 13871:  Prevent frameset spoofing
     // Bug 103638: Targets with same name in different windows open in wrong
     //             window with javascript
+    // Bug 408052: Adopt "ancestor" frame navigation policy
 
     // Now do a security check
     //
     // Allow navigation if
     //  1) aAccessingItem can script aTargetItem or one of its ancestors in
     //     the frame hierarchy or
     //  2) aTargetItem is a top-level frame and aAccessingItem is its descendant
     //  3) aTargetItem is a top-level frame and aAccessingItem can target