Bug 1683299 - Introduce site quota for legacy LocalStorage; r=janv, a=RyanVM
authorTom Tung <ttung@mozilla.com>
Thu, 14 Jan 2021 16:01:17 +0000
changeset 627405 854247b3a4ebc2bdb2a8674e2aaaec547ef4702f
parent 627404 716b5f48799e16a56ff592ec9230508965a4b8fe
child 627406 a2ed4a64e27ad80288dba88d9bd6c331d6e47ba4
push id15031
push userryanvm@gmail.com
push dateFri, 15 Jan 2021 19:25:13 +0000
treeherdermozilla-beta@38febe1e15c4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjanv, RyanVM
bugs1683299
milestone85.0
Bug 1683299 - Introduce site quota for legacy LocalStorage; r=janv, a=RyanVM This patch: - adds a new pref for site quota. - sets 25 MB as the default site qutoa. - renames LocalStorageManager::GetQuota() to LocalStorageManager::GetOriginQuota(). - adds LocalStorageManager::GetSiteQuota(). - updates LocalStorage quota tests. Differential Revision: https://phabricator.services.mozilla.com/D101756
dom/localstorage/test/unit/test_groupLimit.js
dom/storage/LocalStorageCache.cpp
dom/storage/LocalStorageManager.cpp
dom/storage/LocalStorageManager.h
dom/storage/SessionStorageCache.cpp
dom/tests/mochitest/localstorage/test_localStorageQuota.html
dom/tests/mochitest/localstorage/test_localStorageQuotaPrivateBrowsing_perwindowpb.html
dom/tests/mochitest/localstorage/test_localStorageQuotaSessionOnly.html
dom/tests/mochitest/localstorage/test_localStorageQuotaSessionOnly2.html
modules/libpref/init/StaticPrefList.yaml
--- a/dom/localstorage/test/unit/test_groupLimit.js
+++ b/dom/localstorage/test/unit/test_groupLimit.js
@@ -20,16 +20,17 @@ async function testSteps() {
   const data = {};
   data.sizeKB = 5 * 1024;
   data.key = "A";
   data.value = repeatChar(data.sizeKB * 1024 - data.key.length, ".");
   data.urlCount = groupLimitKB / data.sizeKB;
 
   info("Setting pref");
 
+  Services.prefs.setBoolPref("dom.storage.next_gen", true);
   Services.prefs.setBoolPref("dom.storage.snapshot_reusing", false);
 
   info("Setting limits");
 
   setGlobalLimit(globalLimitKB);
 
   let request = clear();
   await requestFinished(request);
--- a/dom/storage/LocalStorageCache.cpp
+++ b/dom/storage/LocalStorageCache.cpp
@@ -189,17 +189,17 @@ bool LocalStorageCache::ProcessUsageDelt
 
 bool LocalStorageCache::ProcessUsageDelta(uint32_t aGetDataSetIndex,
                                           const int64_t aDelta,
                                           const MutationSource aSource) {
   // Check limit per this origin
   Data& data = mData[aGetDataSetIndex];
   uint64_t newOriginUsage = data.mOriginQuotaUsage + aDelta;
   if (aSource == ContentMutation && aDelta > 0 &&
-      newOriginUsage > LocalStorageManager::GetQuota()) {
+      newOriginUsage > LocalStorageManager::GetOriginQuota()) {
     return false;
   }
 
   // Now check eTLD+1 limit
   if (mUsage &&
       !mUsage->CheckAndSetETLD1UsageDelta(aGetDataSetIndex, aDelta, aSource)) {
     return false;
   }
@@ -604,17 +604,17 @@ void StorageUsage::LoadUsage(const int64
 
 bool StorageUsage::CheckAndSetETLD1UsageDelta(
     uint32_t aDataSetIndex, const int64_t aDelta,
     const LocalStorageCache::MutationSource aSource) {
   MOZ_ASSERT(NS_IsMainThread());
 
   int64_t newUsage = mUsage[aDataSetIndex] + aDelta;
   if (aSource == LocalStorageCache::ContentMutation && aDelta > 0 &&
-      newUsage > LocalStorageManager::GetQuota()) {
+      newUsage > LocalStorageManager::GetSiteQuota()) {
     return false;
   }
 
   mUsage[aDataSetIndex] = newUsage;
   return true;
 }
 
 }  // namespace dom
--- a/dom/storage/LocalStorageManager.cpp
+++ b/dom/storage/LocalStorageManager.cpp
@@ -28,20 +28,27 @@
 namespace mozilla {
 namespace dom {
 
 using namespace StorageUtils;
 
 LocalStorageManager* LocalStorageManager::sSelf = nullptr;
 
 // static
-uint32_t LocalStorageManager::GetQuota() {
+uint32_t LocalStorageManager::GetOriginQuota() {
   return StaticPrefs::dom_storage_default_quota() * 1024;  // pref is in kBs
 }
 
+// static
+uint32_t LocalStorageManager::GetSiteQuota() {
+  return std::max(StaticPrefs::dom_storage_default_quota(),
+                  StaticPrefs::dom_storage_default_site_quota()) *
+         1024;  // pref is in kBs
+}
+
 NS_IMPL_ISUPPORTS(LocalStorageManager, nsIDOMStorageManager,
                   nsILocalStorageManager)
 
 LocalStorageManager::LocalStorageManager() : mCaches(8) {
   MOZ_ASSERT(!NextGenLocalStorageEnabled());
 
   StorageObserver* observer = StorageObserver::Self();
   NS_ASSERTION(
--- a/dom/storage/LocalStorageManager.h
+++ b/dom/storage/LocalStorageManager.h
@@ -32,17 +32,20 @@ class LocalStorageManager final : public
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMSTORAGEMANAGER
   NS_DECL_NSILOCALSTORAGEMANAGER
 
  public:
   LocalStorageManager();
 
   // Reads the preference for DOM storage quota
-  static uint32_t GetQuota();
+  static uint32_t GetOriginQuota();
+
+  // Reads the preference for DOM storage site quota
+  static uint32_t GetSiteQuota();
 
   // Gets (but not ensures) cache for the given scope
   LocalStorageCache* GetCache(const nsACString& aOriginSuffix,
                               const nsACString& aOriginNoSuffix);
 
   // Returns object keeping usage cache for the scope.
   already_AddRefed<StorageUsage> GetOriginUsage(
       const nsACString& aOriginNoSuffix, uint32_t aPrivateBrowsingId);
--- a/dom/storage/SessionStorageCache.cpp
+++ b/dom/storage/SessionStorageCache.cpp
@@ -322,17 +322,17 @@ void SessionStorageCache::ClearActor() {
   MOZ_ASSERT(mActor);
 
   mActor = nullptr;
 }
 
 bool SessionStorageCache::DataSet::ProcessUsageDelta(int64_t aDelta) {
   // Check limit per this origin
   uint64_t newOriginUsage = mOriginQuotaUsage + aDelta;
-  if (aDelta > 0 && newOriginUsage > LocalStorageManager::GetQuota()) {
+  if (aDelta > 0 && newOriginUsage > LocalStorageManager::GetOriginQuota()) {
     return false;
   }
 
   // Update size in our data set
   mOriginQuotaUsage = newOriginUsage;
   return true;
 }
 
--- a/dom/tests/mochitest/localstorage/test_localStorageQuota.html
+++ b/dom/tests/mochitest/localstorage/test_localStorageQuota.html
@@ -112,17 +112,17 @@ function doStep()
 {
 }
 
 SimpleTest.waitForExplicitFinish();
 
 function startTest() {
   // Initialy setup the quota to testing value of 1024B and
   // set a 500 bytes key with name length 1 (allocate 501 bytes)
-  SpecialPowers.pushPrefEnv({"set": [["dom.storage.default_quota", 1], ["security.mixed_content.block_display_content", false], ["security.mixed_content.block_active_content", false]]}, doNextTest);
+  SpecialPowers.pushPrefEnv({"set": [["dom.storage.default_quota", 1], ["dom.storage.default_site_quota", 1], ["security.mixed_content.block_display_content", false], ["security.mixed_content.block_active_content", false]]}, doNextTest);
 }
 </script>
 
 </head>
 
 <body onload="startTest();">
   <iframe src="" name="frame"></iframe>
 </body>
--- a/dom/tests/mochitest/localstorage/test_localStorageQuotaPrivateBrowsing_perwindowpb.html
+++ b/dom/tests/mochitest/localstorage/test_localStorageQuotaPrivateBrowsing_perwindowpb.html
@@ -9,18 +9,20 @@
 SimpleTest.waitForExplicitFinish();
 
 const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 const CONTENT_PAGE = "http://mochi.test:8888/chrome/dom/tests/mochitest/localstorage/page_blank.html";
 const slavePath = "/chrome/dom/tests/mochitest/localstorage/";
 var currentTest = 1;
 var quota = Services.prefs.getIntPref("dom.storage.default_quota", 5 * 1024);
+var siteQuota = Services.prefs.getIntPref("dom.storage.default_site_quota", 25 * 1024);
 Services.prefs.setIntPref("browser.startup.page", 0);
 Services.prefs.setIntPref("dom.storage.default_quota", 1);
+Services.prefs.setIntPref("dom.storage.default_site_quota", 1);
 
 var slaveLoadsPending = 1;
 var slaveOrigin = "";
 var slave = null;
 var failureRegExp = new RegExp("^FAILURE");
 
 function startTest() {
   testOnWindow(true, function(aWindow) {
@@ -123,16 +125,17 @@ function doNextTest(aWindow) {
         slaveOrigin = "https://test2.example.com";
         slave.location = slaveOrigin + slavePath + "frameQuota.html?clear";
       }
       break;
 
     default:
       Services.prefs.clearUserPref("browser.startup.page")
       Services.prefs.setIntPref("dom.storage.default_quota", quota);
+      Services.prefs.setIntPref("dom.storage.default_site_quota", siteQuota);
       aWindow.close();
       SimpleTest.finish();
   }
 
   ++currentTest;
 }
 
 function onMessageReceived(event, aWindow) {
--- a/dom/tests/mochitest/localstorage/test_localStorageQuotaSessionOnly.html
+++ b/dom/tests/mochitest/localstorage/test_localStorageQuotaSessionOnly.html
@@ -116,17 +116,17 @@ function startTest() {
     {
       type: "cookie",
       allow: SpecialPowers.Ci.nsICookiePermission.ACCESS_SESSION,
       context: "https://test2.example.com",
     },
   ], function() {
     // Initialy setup the quota to testing value of 1024B and
     // set a 500 bytes key with name length 1 (allocate 501 bytes)
-    SpecialPowers.pushPrefEnv({"set": [["dom.storage.default_quota", 1], ["security.mixed_content.block_display_content", false], ["security.mixed_content.block_active_content", false]]}, doNextTest);
+    SpecialPowers.pushPrefEnv({"set": [["dom.storage.default_quota", 1], ["dom.storage.default_site_quota", 1], ["security.mixed_content.block_display_content", false], ["security.mixed_content.block_active_content", false]]}, doNextTest);
   });
 }
 </script>
 
 </head>
 
 <body onload="startTest();">
   <iframe src="" name="frame"></iframe>
--- a/dom/tests/mochitest/localstorage/test_localStorageQuotaSessionOnly2.html
+++ b/dom/tests/mochitest/localstorage/test_localStorageQuotaSessionOnly2.html
@@ -79,17 +79,17 @@ function doStep()
 {
 }
 
 SimpleTest.waitForExplicitFinish();
 
 function startTest() {
   // Initialy setup the quota to testing value of 1024B and
   // set a 500 bytes key with name length 1 (allocate 501 bytes)
-  SpecialPowers.pushPrefEnv({"set": [["dom.storage.default_quota", 1], ["security.mixed_content.block_display_content", false], ["security.mixed_content.block_active_content", false]]}, function() {
+  SpecialPowers.pushPrefEnv({"set": [["dom.storage.default_quota", 1], ["dom.storage.default_site_quota", 1], ["security.mixed_content.block_display_content", false], ["security.mixed_content.block_active_content", false]]}, function() {
       SpecialPowers.pushPermissions([{'type': 'cookie', 'allow': SpecialPowers.Ci.nsICookiePermission.ACCESS_SESSION, 'context': document}], doNextTest);
   });
 }
 </script>
 
 </head>
 
 <body onload="startTest();">
--- a/modules/libpref/init/StaticPrefList.yaml
+++ b/modules/libpref/init/StaticPrefList.yaml
@@ -2870,16 +2870,22 @@
 # cases. Measured in KiBs.
 - name: dom.storage.default_quota
   type: RelaxedAtomicUint32
   # Only allow relatively small amounts of data since performance of the
   # synchronous IO is very bad. We are enforcing simple per-origin quota only.
   value: 5 * 1024
   mirror: always
 
+# Per-site quota for legacy LocalStorage implementation.
+- name: dom.storage.default_site_quota
+  type: RelaxedAtomicUint32
+  value: 25 * 1024
+  mirror: always
+
 # Whether or not LSNG (Next Generation Local Storage) is enabled.
 # See bug 1517090 for enabling this on Nightly.
 # See bug 1534736 for changing it to EARLY_BETA_OR_EARLIER.
 # See bug 1539835 for enabling this unconditionally.
 # See bug 1619948 for changing it back to EARLY_BETA_OR_EARLIER.
 - name: dom.storage.next_gen
   type: RelaxedAtomicBool
   value: @IS_EARLY_BETA_OR_EARLIER@