Bug 371127, support using domstorage from chrome, r=jst,sr=dveditz
authorenndeakin@sympatico.ca
Thu, 26 Apr 2007 05:56:03 -0700
changeset 834 d5600d516db0d7283f5fd0e4fe6824a51600bd3d
parent 833 857e9d5e0e5062002360233ff0edb1576e5fa3d6
child 835 dfaba0404aed38e5f0f676036da5e7568145b91f
push id1
push userbsmedberg@mozilla.com
push dateThu, 20 Mar 2008 16:49:24 +0000
treeherdermozilla-central@61007906a1f8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjst, dveditz
bugs371127
milestone1.9a4pre
Bug 371127, support using domstorage from chrome, r=jst,sr=dveditz
dom/src/base/nsDOMClassInfo.cpp
dom/src/storage/nsDOMStorage.cpp
--- a/dom/src/base/nsDOMClassInfo.cpp
+++ b/dom/src/base/nsDOMClassInfo.cpp
@@ -2458,18 +2458,17 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(ChromeWindow, nsIDOMWindow)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindow)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMJSWindow)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMWindowInternal)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMChromeWindow)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
-    // XXXjst: Do we want this on chrome windows?
-    // DOM_CLASSINFO_MAP_ENTRY(nsIDOMStorageWindow)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMStorageWindow)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMViewCSS)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMAbstractView)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(RangeException, nsIDOMRangeException)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMRangeException)
     DOM_CLASSINFO_MAP_ENTRY(nsIException)
   DOM_CLASSINFO_MAP_END
--- a/dom/src/storage/nsDOMStorage.cpp
+++ b/dom/src/storage/nsDOMStorage.cpp
@@ -294,28 +294,31 @@ nsDOMStorage::Init(nsIURI* aURI, const n
 }
 
 //static
 PRBool
 nsDOMStorage::CanUseStorage(nsIURI* aURI, PRPackedBool* aSessionOnly)
 {
   // check if the domain can use storage. Downgrade to session only if only
   // session storage may be used.
-  NS_ASSERTION(aURI && aSessionOnly, "null URI or session flag");
+  NS_ASSERTION(aSessionOnly, "null session flag");
+  *aSessionOnly = PR_FALSE;
 
   if (!nsContentUtils::GetBoolPref(kStorageEnabled))
     return PR_FALSE;
 
+  // chrome can always use storage regardless of permission preferences
+  if (nsContentUtils::IsCallerChrome())
+    return PR_TRUE;
+
   nsCOMPtr<nsIPermissionManager> permissionManager =
     do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
   if (!permissionManager)
     return PR_FALSE;
 
-  *aSessionOnly = PR_FALSE;
-
   PRUint32 perm;
   permissionManager->TestPermission(aURI, kPermissionType, &perm);
 
   if (perm == nsIPermissionManager::DENY_ACTION)
     return PR_FALSE;
 
   if (perm == nsICookiePermission::ACCESS_SESSION) {
     *aSessionOnly = PR_TRUE;
@@ -669,39 +672,51 @@ nsDOMStorage::SetDBValue(const nsAString
 #ifdef MOZ_STORAGE
   if (!UseDB())
     return NS_OK;
 
   nsresult rv = InitDB();
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Get the current domain for quota enforcement
+  nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
+  if (!ssm)
+    return NS_ERROR_FAILURE;
+
   nsCOMPtr<nsIPrincipal> subjectPrincipal;
-  nsContentUtils::GetSecurityManager()->
-    GetSubjectPrincipal(getter_AddRefs(subjectPrincipal));
+  ssm->GetSubjectPrincipal(getter_AddRefs(subjectPrincipal));
 
   nsAutoString currentDomain;
 
   if (subjectPrincipal) {
     nsCOMPtr<nsIURI> uri;
     rv = subjectPrincipal->GetURI(getter_AddRefs(uri));
 
     if (NS_SUCCEEDED(rv) && uri) {
-        nsCAutoString currentDomainAscii;
-        uri->GetAsciiHost(currentDomainAscii);
-        currentDomain = NS_ConvertUTF8toUTF16(currentDomainAscii);
+      nsCOMPtr<nsIURI> innerUri = NS_GetInnermostURI(uri);
+      if (!innerUri)
+        return NS_ERROR_UNEXPECTED;
+
+      nsCAutoString currentDomainAscii;
+      innerUri->GetAsciiHost(currentDomainAscii);
+      currentDomain = NS_ConvertUTF8toUTF16(currentDomainAscii);
     }
-    
+
     if (currentDomain.IsEmpty()) {
+      // allow chrome urls and trusted file urls to write using
+      // the storage's domain
+      if (nsContentUtils::IsCallerTrustedForWrite())
+        currentDomain = mDomain;
+      else
         return NS_ERROR_DOM_SECURITY_ERR;
     }
   } else {
-      currentDomain = mDomain;
+    currentDomain = mDomain;
   }
-  
+
   rv = gStorageDB->SetKey(mDomain, aKey, aValue, aSecure,
                           currentDomain, GetQuota(currentDomain));
   NS_ENSURE_SUCCESS(rv, rv);
 
   mItemsCached = PR_FALSE;
 
   BroadcastChangeNotification();
 #endif
@@ -860,26 +875,35 @@ nsDOMStorageList::NamedItem(const nsAStr
   nsCOMPtr<nsIURI> uri;
   nsCAutoString currentDomain;
   if (subjectPrincipal) {
     rv = subjectPrincipal->GetURI(getter_AddRefs(uri));
     if (NS_SUCCEEDED(rv) && uri) {
       PRPackedBool sessionOnly;
       if (!nsDOMStorage::CanUseStorage(uri, &sessionOnly))
         return NS_ERROR_DOM_SECURITY_ERR;
-      
+
+      nsCOMPtr<nsIURI> innerUri = NS_GetInnermostURI(uri);
+      if (!innerUri)
+        return NS_ERROR_UNEXPECTED;
+
+      uri = innerUri;
       rv = uri->GetAsciiHost(currentDomain);
       NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_SECURITY_ERR);
     }
   }
 
   PRBool isSystem;
   rv = ssm->SubjectPrincipalIsSystem(&isSystem);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  // allow code that has read privileges to get the storage for any domain
+  if (!isSystem && nsContentUtils::IsCallerTrustedForRead())
+    isSystem = PR_TRUE;
+
   if (isSystem || !currentDomain.IsEmpty()) {
     return GetStorageForDomain(uri, aDomain, NS_ConvertUTF8toUTF16(currentDomain),
                                isSystem, aStorage);
   }
 
   return NS_ERROR_DOM_SECURITY_ERR;
 }