Bug 1286798 - Part 12: Honor the storage preference and cookie settings in all LocalStorage API methods; r=asuth
authorJan Varga <jan.varga@gmail.com>
Thu, 29 Nov 2018 21:47:52 +0100
changeset 508010 a4324eecfb06d326abe06677339bf153c627af33
parent 508009 4e938b6813e3e8dcb10998d89243678463f4b42a
child 508011 c63189db48cb7b515e53c33bc3203a92761e1d32
push id1905
push userffxbld-merge
push dateMon, 21 Jan 2019 12:33:13 +0000
treeherdermozilla-release@c2fca1944d8c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersasuth
bugs1286798
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1286798 - Part 12: Honor the storage preference and cookie settings in all LocalStorage API methods; r=asuth
dom/base/nsGlobalWindowInner.cpp
dom/localstorage/LSObject.cpp
dom/tests/mochitest/localstorage/mochitest.ini
dom/tests/mochitest/localstorage/test_cookieBlock.html
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -5825,17 +5825,17 @@ nsGlobalWindowInner::ObserveStorageNotif
     }
   }
 
   // Clone the storage event included in the observer notification. We want
   // to dispatch clones rather than the original event.
   IgnoredErrorResult error;
   RefPtr<StorageEvent> clonedEvent =
     CloneStorageEvent(eventType, aEvent, error);
-  if (error.Failed()) {
+  if (error.Failed() || !clonedEvent) {
     return;
   }
 
   clonedEvent->SetTrusted(true);
 
   if (fireMozStorageChanged) {
     WidgetEvent* internalEvent = clonedEvent->WidgetEventPtr();
     internalEvent->mFlags.mOnlyChromeDispatch = true;
--- a/dom/localstorage/LSObject.cpp
+++ b/dom/localstorage/LSObject.cpp
@@ -291,16 +291,21 @@ LSObject::GetOriginQuotaUsage() const
 }
 
 uint32_t
 LSObject::GetLength(nsIPrincipal& aSubjectPrincipal,
                     ErrorResult& aError)
 {
   AssertIsOnOwningThread();
 
+  if (!CanUseStorage(aSubjectPrincipal)) {
+    aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
+    return 0;
+  }
+
   nsresult rv = EnsureDatabase();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     aError.Throw(rv);
     return 0;
   }
 
   uint32_t result;
   rv = mDatabase->GetLength(&result);
@@ -315,16 +320,21 @@ LSObject::GetLength(nsIPrincipal& aSubje
 void
 LSObject::Key(uint32_t aIndex,
               nsAString& aResult,
               nsIPrincipal& aSubjectPrincipal,
               ErrorResult& aError)
 {
   AssertIsOnOwningThread();
 
+  if (!CanUseStorage(aSubjectPrincipal)) {
+    aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
+    return;
+  }
+
   nsresult rv = EnsureDatabase();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     aError.Throw(rv);
     return;
   }
 
   nsString result;
   rv = mDatabase->GetKey(aIndex, result);
@@ -339,16 +349,21 @@ LSObject::Key(uint32_t aIndex,
 void
 LSObject::GetItem(const nsAString& aKey,
                   nsAString& aResult,
                   nsIPrincipal& aSubjectPrincipal,
                   ErrorResult& aError)
 {
   AssertIsOnOwningThread();
 
+  if (!CanUseStorage(aSubjectPrincipal)) {
+    aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
+    return;
+  }
+
   nsresult rv = EnsureDatabase();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     aError.Throw(rv);
     return;
   }
 
   nsString result;
   rv = mDatabase->GetItem(aKey, result);
@@ -360,16 +375,22 @@ LSObject::GetItem(const nsAString& aKey,
   aResult = result;
 }
 
 void
 LSObject::GetSupportedNames(nsTArray<nsString>& aNames)
 {
   AssertIsOnOwningThread();
 
+  if (!CanUseStorage(*nsContentUtils::SubjectPrincipal())) {
+    // Return just an empty array.
+    aNames.Clear();
+    return;
+  }
+
   nsresult rv = EnsureDatabase();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return;
   }
 
   rv = mDatabase->GetKeys(aNames);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return;
@@ -379,16 +400,21 @@ LSObject::GetSupportedNames(nsTArray<nsS
 void
 LSObject::SetItem(const nsAString& aKey,
                   const nsAString& aValue,
                   nsIPrincipal& aSubjectPrincipal,
                   ErrorResult& aError)
 {
   AssertIsOnOwningThread();
 
+  if (!CanUseStorage(aSubjectPrincipal)) {
+    aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
+    return;
+  }
+
   nsresult rv = EnsureDatabase();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     aError.Throw(rv);
     return;
   }
 
   bool changed;
   nsString oldValue;
@@ -405,16 +431,21 @@ LSObject::SetItem(const nsAString& aKey,
 
 void
 LSObject::RemoveItem(const nsAString& aKey,
                      nsIPrincipal& aSubjectPrincipal,
                      ErrorResult& aError)
 {
   AssertIsOnOwningThread();
 
+  if (!CanUseStorage(aSubjectPrincipal)) {
+    aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
+    return;
+  }
+
   nsresult rv = EnsureDatabase();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     aError.Throw(rv);
     return;
   }
 
   bool changed;
   nsString oldValue;
@@ -430,16 +461,21 @@ LSObject::RemoveItem(const nsAString& aK
 }
 
 void
 LSObject::Clear(nsIPrincipal& aSubjectPrincipal,
                 ErrorResult& aError)
 {
   AssertIsOnOwningThread();
 
+  if (!CanUseStorage(aSubjectPrincipal)) {
+    aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
+    return;
+  }
+
   nsresult rv = EnsureDatabase();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     aError.Throw(rv);
     return;
   }
 
   bool changed;
   rv = mDatabase->Clear(&changed);
--- a/dom/tests/mochitest/localstorage/mochitest.ini
+++ b/dom/tests/mochitest/localstorage/mochitest.ini
@@ -26,17 +26,17 @@ skip-if = os == "android" || verify # bu
 [test_cookieBlock.html]
 [test_cookieSession.html]
 [test_embededNulls.html]
 [test_keySync.html]
 [test_localStorageBase.html]
 skip-if = e10s
 [test_localStorageBaseSessionOnly.html]
 [test_localStorageCookieSettings.html]
-#[test_localStorageEnablePref.html]
+[test_localStorageEnablePref.html]
 [test_localStorageKeyOrder.html]
 [test_localStorageOriginsDiff.html]
 [test_localStorageOriginsDomainDiffs.html]
 [test_localStorageOriginsEquals.html]
 skip-if = toolkit == 'android'
 [test_localStorageOriginsPortDiffs.html]
 [test_localStorageOriginsSchemaDiffs.html]
 skip-if = toolkit == 'android' #TIMED_OUT
--- a/dom/tests/mochitest/localstorage/test_cookieBlock.html
+++ b/dom/tests/mochitest/localstorage/test_cookieBlock.html
@@ -25,16 +25,20 @@ function startTest()
     ok(true, "Exception for localStorage.getItem, ACCESS_DENY");
   }
 
   SimpleTest.finish();
 }
 
 SimpleTest.waitForExplicitFinish();
 
+// Initialize storage before setting the cookie, otherwise we won't be testing
+// the checks in setItem/getItem methods.
+var storage = localStorage;
+
 SpecialPowers.pushPermissions([{'type': 'cookie', 'allow': false, 'context': document}], startTest);
 
 </script>
 
 </head>
 
 <body>