Bug 1468592 - use nsIEffectiveTLDService::hasRootDomain instead of custom hasRootDomain implementations, r=valentin
authorAndrea Marchesini <amarchesini@mozilla.com>
Thu, 14 Jun 2018 04:31:14 -0700
changeset 422544 108e1a94637c
parent 422543 66ad37417e47
child 422545 07cda954e328
push id34138
push userdluca@mozilla.com
push date2018-06-15 02:39 +0000
treeherdermozilla-central@e51f8dbf0397 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvalentin
bugs1468592
milestone62.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 1468592 - use nsIEffectiveTLDService::hasRootDomain instead of custom hasRootDomain implementations, r=valentin
dom/push/PushService.jsm
dom/serviceworkers/ServiceWorkerManager.cpp
toolkit/modules/sessionstore/Utils.jsm
--- a/dom/push/PushService.jsm
+++ b/dom/push/PushService.jsm
@@ -27,16 +27,19 @@ const CONNECTION_PROTOCOLS = (function()
     const {PushServiceAndroidGCM} = ChromeUtils.import("resource://gre/modules/PushServiceAndroidGCM.jsm");
     return [PushServiceAndroidGCM];
   }
 })();
 
 XPCOMUtils.defineLazyServiceGetter(this, "gPushNotifier",
                                    "@mozilla.org/push/Notifier;1",
                                    "nsIPushNotifier");
+XPCOMUtils.defineLazyServiceGetter(this, "eTLDService",
+                                   "@mozilla.org/network/effective-tld-service;1",
+                                   "nsIEffectiveTLDService");
 
 var EXPORTED_SYMBOLS = ["PushService"];
 
 XPCOMUtils.defineLazyGetter(this, "console", () => {
   let {ConsoleAPI} = ChromeUtils.import("resource://gre/modules/Console.jsm", {});
   return new ConsoleAPI({
     maxLogLevelPref: "dom.push.loglevel",
     prefix: "PushService",
@@ -81,43 +84,16 @@ const UNINIT_EVENT = 3;
  */
 function errorWithResult(message, result = Cr.NS_ERROR_FAILURE) {
   let error = new Error(message);
   error.result = result;
   return error;
 }
 
 /**
- * Copied from ForgetAboutSite.jsm.
- *
- * Returns true if the string passed in is part of the root domain of the
- * current string.  For example, if this is "www.mozilla.org", and we pass in
- * "mozilla.org", this will return true.  It would return false the other way
- * around.
- */
-function hasRootDomain(str, aDomain)
-{
-  let index = str.indexOf(aDomain);
-  // If aDomain is not found, we know we do not have it as a root domain.
-  if (index == -1)
-    return false;
-
-  // If the strings are the same, we obviously have a match.
-  if (str == aDomain)
-    return true;
-
-  // Otherwise, we have aDomain as our root domain iff the index of aDomain is
-  // aDomain.length subtracted from our length and (since we do not have an
-  // exact match) the character before the index is a dot or slash.
-  let prevChar = str[index - 1];
-  return (index == (str.length - aDomain.length)) &&
-         (prevChar == "." || prevChar == "/");
-}
-
-/**
  * The implementation of the push system. It uses WebSockets
  * (PushServiceWebSocket) to communicate with the server and PushDB (IndexedDB)
  * for persistence.
  */
 var PushService = {
   _service: null,
   _state: PUSH_SERVICE_UNINIT,
   _db: null,
@@ -1129,17 +1105,17 @@ var PushService = {
       });
   },
 
   clear: function(info) {
     return this._checkActivated()
       .then(_ => {
         return this._dropRegistrationsIf(record =>
           info.domain == "*" ||
-          (record.uri && hasRootDomain(record.uri.prePath, info.domain))
+          (record.uri && eTLDService.hasRootDomain(record.uri.prePath, info.domain))
         );
       })
       .catch(e => {
         console.warn("clear: Error dropping subscriptions for domain",
           info.domain, e);
         return Promise.resolve();
       });
   },
--- a/dom/serviceworkers/ServiceWorkerManager.cpp
+++ b/dom/serviceworkers/ServiceWorkerManager.cpp
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ServiceWorkerManager.h"
 
 #include "nsAutoPtr.h"
 #include "nsIConsoleService.h"
 #include "nsIDocument.h"
+#include "nsIEffectiveTLDService.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIStreamLoader.h"
 #include "nsIHttpChannel.h"
 #include "nsIHttpChannelInternal.h"
 #include "nsIHttpHeaderVisitor.h"
 #include "nsINamed.h"
 #include "nsINetworkInterceptController.h"
 #include "nsIMutableArray.h"
@@ -2796,60 +2797,16 @@ ServiceWorkerManager::RemoveRegistration
 
   // When a registration is removed, we must clear its contents since the DOM
   // object may be held by content script.
   aRegistration->Clear();
 
   RemoveScopeAndRegistration(aRegistration);
 }
 
-namespace {
-/**
- * See toolkit/modules/sessionstore/Utils.jsm function hasRootDomain().
- *
- * Returns true if the |url| passed in is part of the given root |domain|.
- * For example, if |url| is "www.mozilla.org", and we pass in |domain| as
- * "mozilla.org", this will return true. It would return false the other way
- * around.
- */
-bool
-HasRootDomain(nsIURI* aURI, const nsACString& aDomain)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(aURI);
-
-  nsAutoCString host;
-  nsresult rv = aURI->GetHost(host);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return false;
-  }
-
-  nsACString::const_iterator start, end;
-  host.BeginReading(start);
-  host.EndReading(end);
-  if (!FindInReadable(aDomain, start, end)) {
-    return false;
-  }
-
-  if (host.Equals(aDomain)) {
-    return true;
-  }
-
-  // Beginning of the string matches, can't look at the previous char.
-  if (start.get() == host.BeginReading()) {
-    // Equals failed so this is fine.
-    return false;
-  }
-
-  char prevChar = *(--start);
-  return prevChar == '.';
-}
-
-} // namespace
-
 NS_IMETHODIMP
 ServiceWorkerManager::GetAllRegistrations(nsIArray** aResult)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   nsCOMPtr<nsIMutableArray> array(do_CreateInstance(NS_ARRAY_CONTRACTID));
   if (!array) {
     return NS_ERROR_OUT_OF_MEMORY;
@@ -2895,25 +2852,47 @@ ServiceWorkerManager::ForceUnregister(Re
   Unregister(aRegistration->Principal(), nullptr, NS_ConvertUTF8toUTF16(aRegistration->Scope()));
 }
 
 void
 ServiceWorkerManager::Remove(const nsACString& aHost)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
+  nsCOMPtr<nsIEffectiveTLDService> tldService =
+    do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
+  if (NS_WARN_IF(!tldService)) {
+    return;
+  }
+
   for (auto it1 = mRegistrationInfos.Iter(); !it1.Done(); it1.Next()) {
     ServiceWorkerManager::RegistrationDataPerPrincipal* data = it1.UserData();
     for (auto it2 = data->mInfos.Iter(); !it2.Done(); it2.Next()) {
       ServiceWorkerRegistrationInfo* reg = it2.UserData();
       nsCOMPtr<nsIURI> scopeURI;
       nsresult rv = NS_NewURI(getter_AddRefs(scopeURI), it2.Key(),
                               nullptr, nullptr);
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        continue;
+      }
+
+      nsAutoCString host;
+      rv = scopeURI->GetHost(host);
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        continue;
+      }
+
       // This way subdomains are also cleared.
-      if (NS_SUCCEEDED(rv) && HasRootDomain(scopeURI, aHost)) {
+      bool hasRootDomain = false;
+      rv = tldService->HasRootDomain(host, aHost, &hasRootDomain);
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        continue;
+      }
+
+      if (hasRootDomain) {
         ForceUnregister(data, reg);
       }
     }
   }
 }
 
 void
 ServiceWorkerManager::PropagateRemove(const nsACString& aHost)
--- a/toolkit/modules/sessionstore/Utils.jsm
+++ b/toolkit/modules/sessionstore/Utils.jsm
@@ -12,16 +12,20 @@ ChromeUtils.import("resource://gre/modul
 ChromeUtils.defineModuleGetter(this, "NetUtil",
                                "resource://gre/modules/NetUtil.jsm");
 XPCOMUtils.defineLazyServiceGetter(this, "serializationHelper",
                                    "@mozilla.org/network/serialization-helper;1",
                                    "nsISerializationHelper");
 XPCOMUtils.defineLazyServiceGetter(this, "ssu",
                                    "@mozilla.org/browser/sessionstore/utils;1",
                                    "nsISessionStoreUtils");
+XPCOMUtils.defineLazyServiceGetter(this, "eTLDService",
+                                   "@mozilla.org/network/effective-tld-service;1",
+                                   "nsIEffectiveTLDService");
+
 XPCOMUtils.defineLazyGetter(this, "SERIALIZED_SYSTEMPRINCIPAL", function() {
   return Utils.serializePrincipal(Services.scriptSecurityManager.getSystemPrincipal());
 });
 
 function debug(msg) {
   Services.console.logStringMessage("Utils: " + msg);
 }
 
@@ -84,26 +88,17 @@ var Utils = Object.freeze({
 
     try {
       host = this.makeURI(url).host;
     } catch (e) {
       // The given URL probably doesn't have a host.
       return false;
     }
 
-    let index = host.indexOf(domain);
-    if (index == -1)
-      return false;
-
-    if (host == domain)
-      return true;
-
-    let prevChar = host[index - 1];
-    return (index == (host.length - domain.length)) &&
-           (prevChar == "." || prevChar == "/");
+   return eTLDService.hasRootDomain(host, domain);
   },
 
   shallowCopy(obj) {
     let retval = {};
 
     for (let key of Object.keys(obj)) {
       retval[key] = obj[key];
     }