author | Andrea Marchesini <amarchesini@mozilla.com> |
Wed, 13 Jun 2018 12:29:39 -0700 | |
changeset 422424 | ca68fa3212d349d7edac9777b259039c22fae998 |
parent 422423 | b75ad30847fe46f49fcd93975de49609bd820248 |
child 422425 | 73a994c463a0b1f6cab41b8c48f04cb99a1c0008 |
push id | 104254 |
push user | amarchesini@mozilla.com |
push date | Wed, 13 Jun 2018 19:29:54 +0000 |
treeherder | mozilla-inbound@ca68fa3212d3 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | smaug |
bugs | 1468503 |
milestone | 62.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
|
--- a/netwerk/dns/nsEffectiveTLDService.cpp +++ b/netwerk/dns/nsEffectiveTLDService.cpp @@ -341,8 +341,40 @@ bool nsEffectiveTLDService::LookupForAdd(const nsACString& aHost, TLDCacheEntry** aEntry) { MOZ_ASSERT(NS_IsMainThread()); const uint32_t hash = HashString(aHost.BeginReading(), aHost.Length()); *aEntry = &mMruTable[hash % kTableSize]; return (*aEntry)->mHost == aHost; } + +NS_IMETHODIMP +nsEffectiveTLDService::HasRootDomain(const nsACString& aInput, + const nsACString& aHost, + bool* aResult) +{ + if (NS_WARN_IF(!aResult)) { + return NS_ERROR_FAILURE; + } + + *aResult = false; + + // If the strings are the same, we obviously have a match. + if (aInput == aHost) { + *aResult = true; + return NS_OK; + } + + // If aHost is not found, we know we do not have it as a root domain. + int32_t index = nsAutoCString(aInput).Find(aHost.BeginReading()); + if (index == kNotFound) { + return NS_OK; + } + + // Otherwise, we have aHost as our root domain iff the index of aHost is + // aHost.length subtracted from our length and (since we do not have an + // exact match) the character before the index is a dot or slash. + *aResult = index > 0 && + (uint32_t)index == aInput.Length() - aHost.Length() && + (aInput[index - 1] == '.' || aInput[index - 1] == '/'); + return NS_OK; +}
--- a/netwerk/dns/nsIEffectiveTLDService.idl +++ b/netwerk/dns/nsIEffectiveTLDService.idl @@ -116,10 +116,21 @@ interface nsIEffectiveTLDService : nsISu * "bbc.co.uk" would throw NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS. * * @param aHost The host to be analyzed. Any additional parts (e.g. scheme, * port, or path) will cause this method to throw. ASCII/ACE and * UTF8 encodings are acceptable as input; normalization will * be performed as specified in getBaseDomain(). */ ACString getNextSubDomain(in AUTF8String aHost); + + /** + * Returns true if the |aInput| in is part of the root domain of |aHost|. + * For example, if |aInput| is "www.mozilla.org", and we pass in + * "mozilla.org" as |aHost|, this will return true. It would return false + * the other way around. + * + * @param aInput The host to be analyzed. + * @param aHost The host to compare to. + */ + bool hasRootDomain(in AUTF8String aInput, in AUTF8String aHost); };
--- a/toolkit/components/cleardata/ClearDataService.js +++ b/toolkit/components/cleardata/ClearDataService.js @@ -13,16 +13,19 @@ XPCOMUtils.defineLazyModuleGetters(this, OfflineAppCacheHelper: "resource://gre/modules/offlineAppCache.jsm", ServiceWorkerCleanUp: "resource://gre/modules/ServiceWorkerCleanUp.jsm", PlacesUtils: "resource://gre/modules/PlacesUtils.jsm", }); XPCOMUtils.defineLazyServiceGetter(this, "sas", "@mozilla.org/storage/activity-service;1", "nsIStorageActivityService"); +XPCOMUtils.defineLazyServiceGetter(this, "eTLDService", + "@mozilla.org/network/effective-tld-service;1", + "nsIEffectiveTLDService"); // A Cleaner is an object with 3 methods. These methods must return a Promise // object. Here a description of these methods: // * deleteAll() - this method _must_ exist. When called, it deletes all the // data owned by the cleaner. // * deleteByPrincipal() - this method is implemented only if the cleaner knows // how to delete data by nsIPrincipal. If not // implemented, deleteByHost will be used instead. @@ -183,17 +186,17 @@ const PluginDataCleaner = { new Promise(aResolve => setTimeout(aResolve, 10000 /* 10 seconds */)) ]); }, }; const DownloadsCleaner = { deleteByHost(aHost, aOriginAttributes) { return Downloads.getList(Downloads.ALL).then(aList => { - aList.removeFinished(aDownload => hasRootDomain( + aList.removeFinished(aDownload => eTLDService.hasRootDomain( Services.io.newURI(aDownload.source.url).host, aHost)); }); }, deleteByRange(aFrom, aTo) { // Convert microseconds back to milliseconds for date comparisons. let rangeBeginMs = aFrom / 1000; let rangeEndMs = aTo / 1000; @@ -208,17 +211,17 @@ const DownloadsCleaner = { return Downloads.getList(Downloads.ALL).then(aList => { aList.removeFinished(null); }); }, }; const PasswordsCleaner = { deleteByHost(aHost, aOriginAttributes) { - return this._deleteInternal(aLogin => hasRootDomain(aLogin.hostname, aHost)); + return this._deleteInternal(aLogin => eTLDService.hasRootDomain(aLogin.hostname, aHost)); }, deleteAll() { return this._deleteInternal(() => true); }, _deleteInternal(aCb) { return new Promise(aResolve => { @@ -485,17 +488,17 @@ const AuthCacheCleaner = { const PermissionsCleaner = { deleteByHost(aHost, aOriginAttributes) { return new Promise(aResolve => { let enumerator = Services.perms.enumerator; while (enumerator.hasMoreElements()) { let perm = enumerator.getNext().QueryInterface(Ci.nsIPermission); try { - if (hasRootDomain(perm.principal.URI.host, aHost)) { + if (eTLDService.hasRootDomain(perm.principal.URI.host, aHost)) { Services.perms.removePermission(perm); } } catch (ex) { // Ignore entry } } aResolve(); @@ -561,17 +564,17 @@ const SecuritySettingsCleaner = { for (let type of [Ci.nsISiteSecurityService.HEADER_HSTS, Ci.nsISiteSecurityService.HEADER_HPKP]) { // Also remove HSTS/HPKP/OMS information for subdomains by enumerating // the information in the site security service. let enumerator = sss.enumerate(type); while (enumerator.hasMoreElements()) { let entry = enumerator.getNext(); let hostname = entry.QueryInterface(Ci.nsISiteSecurityState).hostname; - if (hasRootDomain(hostname, aHost)) { + if (eTLDService.hasRootDomain(hostname, aHost)) { // This uri is used as a key to remove the state. let uri = Services.io.newURI("https://" + hostname); sss.removeState(type, uri, 0, entry.originAttributes); } } } aResolve(); @@ -759,32 +762,8 @@ ClearDataService.prototype = Object.free return aHelper(c.cleaner).catch(() => { resultFlags |= c.flag; }); }); Promise.all(promises).then(() => { aCallback.onDataDeleted(resultFlags); }); return Cr.NS_OK; }, }); this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ClearDataService]); - -/** - * 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 == "/"); -}