LCOV - code coverage report
Current view: top level - caps - OriginAttributes.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 46 135 34.1 %
Date: 2017-07-14 16:53:18 Functions: 7 11 63.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=2 sw=2 et tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "mozilla/OriginAttributes.h"
       8             : #include "mozilla/Preferences.h"
       9             : #include "mozilla/dom/URLSearchParams.h"
      10             : #include "mozilla/dom/quota/QuotaManager.h"
      11             : #include "nsIEffectiveTLDService.h"
      12             : #include "nsIURI.h"
      13             : #include "nsIURIWithPrincipal.h"
      14             : 
      15             : namespace mozilla {
      16             : 
      17             : using dom::URLParams;
      18             : 
      19             : bool OriginAttributes::sFirstPartyIsolation = false;
      20             : bool OriginAttributes::sRestrictedOpenerAccess = false;
      21             : 
      22             : void
      23           3 : OriginAttributes::InitPrefs()
      24             : {
      25           3 :   MOZ_ASSERT(NS_IsMainThread());
      26             :   static bool sInited = false;
      27           3 :   if (!sInited) {
      28           3 :     sInited = true;
      29             :     Preferences::AddBoolVarCache(&sFirstPartyIsolation,
      30           3 :                                  "privacy.firstparty.isolate");
      31             :     Preferences::AddBoolVarCache(&sRestrictedOpenerAccess,
      32           3 :                                  "privacy.firstparty.isolate.restrict_opener_access");
      33             :   }
      34           3 : }
      35             : 
      36             : void
      37          10 : OriginAttributes::SetFirstPartyDomain(const bool aIsTopLevelDocument,
      38             :                                       nsIURI* aURI)
      39             : {
      40          10 :   bool isFirstPartyEnabled = IsFirstPartyEnabled();
      41             : 
      42             :   // If the pref is off or this is not a top level load, bail out.
      43          10 :   if (!isFirstPartyEnabled || !aIsTopLevelDocument) {
      44          20 :     return;
      45             :   }
      46             : 
      47             :   nsCOMPtr<nsIEffectiveTLDService> tldService =
      48           0 :     do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
      49           0 :   MOZ_ASSERT(tldService);
      50           0 :   if (!tldService) {
      51           0 :     return;
      52             :   }
      53             : 
      54           0 :   nsAutoCString baseDomain;
      55           0 :   nsresult rv = tldService->GetBaseDomain(aURI, 0, baseDomain);
      56           0 :   if (NS_SUCCEEDED(rv)) {
      57           0 :     mFirstPartyDomain = NS_ConvertUTF8toUTF16(baseDomain);
      58           0 :     return;
      59             :   }
      60             : 
      61           0 :   nsAutoCString scheme;
      62           0 :   rv = aURI->GetScheme(scheme);
      63           0 :   NS_ENSURE_SUCCESS_VOID(rv);
      64           0 :   if (scheme.EqualsLiteral("about")) {
      65           0 :     mFirstPartyDomain.AssignLiteral(ABOUT_URI_FIRST_PARTY_DOMAIN);
      66           0 :   } else if (scheme.EqualsLiteral("blob")) {
      67           0 :     nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(aURI);
      68           0 :     if (uriPrinc) {
      69           0 :       nsCOMPtr<nsIPrincipal> principal;
      70           0 :       rv = uriPrinc->GetPrincipal(getter_AddRefs(principal));
      71           0 :       NS_ENSURE_SUCCESS_VOID(rv);
      72             : 
      73           0 :       MOZ_ASSERT(principal, "blob URI but no principal.");
      74           0 :       if (principal) {
      75           0 :         mFirstPartyDomain = principal->OriginAttributesRef().mFirstPartyDomain;
      76             :       }
      77             :     }
      78             :   }
      79             : }
      80             : 
      81             : void
      82           1 : OriginAttributes::SetFirstPartyDomain(const bool aIsTopLevelDocument,
      83             :                                       const nsACString& aDomain)
      84             : {
      85           1 :   bool isFirstPartyEnabled = IsFirstPartyEnabled();
      86             : 
      87             :   // If the pref is off or this is not a top level load, bail out.
      88           1 :   if (!isFirstPartyEnabled || !aIsTopLevelDocument) {
      89           1 :     return;
      90             :   }
      91             : 
      92           0 :   mFirstPartyDomain = NS_ConvertUTF8toUTF16(aDomain);
      93             : }
      94             : 
      95             : void
      96         549 : OriginAttributes::CreateSuffix(nsACString& aStr) const
      97             : {
      98        1098 :   URLParams params;
      99        1098 :   nsAutoString value;
     100             : 
     101             :   //
     102             :   // Important: While serializing any string-valued attributes, perform a
     103             :   // release-mode assertion to make sure that they don't contain characters that
     104             :   // will break the quota manager when it uses the serialization for file
     105             :   // naming.
     106             :   //
     107             : 
     108         549 :   if (mAppId != nsIScriptSecurityManager::NO_APP_ID) {
     109           0 :     value.AppendInt(mAppId);
     110           0 :     params.Set(NS_LITERAL_STRING("appId"), value);
     111             :   }
     112             : 
     113         549 :   if (mInIsolatedMozBrowser) {
     114           0 :     params.Set(NS_LITERAL_STRING("inBrowser"), NS_LITERAL_STRING("1"));
     115             :   }
     116             : 
     117         549 :   if (mUserContextId != nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID) {
     118           0 :     value.Truncate();
     119           0 :     value.AppendInt(mUserContextId);
     120           0 :     params.Set(NS_LITERAL_STRING("userContextId"), value);
     121             :   }
     122             : 
     123             : 
     124         549 :   if (mPrivateBrowsingId) {
     125           0 :     value.Truncate();
     126           0 :     value.AppendInt(mPrivateBrowsingId);
     127           0 :     params.Set(NS_LITERAL_STRING("privateBrowsingId"), value);
     128             :   }
     129             : 
     130         549 :   if (!mFirstPartyDomain.IsEmpty()) {
     131          11 :     MOZ_RELEASE_ASSERT(mFirstPartyDomain.FindCharInSet(dom::quota::QuotaManager::kReplaceChars) == kNotFound);
     132          11 :     params.Set(NS_LITERAL_STRING("firstPartyDomain"), mFirstPartyDomain);
     133             :   }
     134             : 
     135         549 :   aStr.Truncate();
     136             : 
     137         549 :   params.Serialize(value);
     138         549 :   if (!value.IsEmpty()) {
     139          11 :     aStr.AppendLiteral("^");
     140          11 :     aStr.Append(NS_ConvertUTF16toUTF8(value));
     141             :   }
     142             : 
     143             : // In debug builds, check the whole string for illegal characters too (just in case).
     144             : #ifdef DEBUG
     145        1098 :   nsAutoCString str;
     146         549 :   str.Assign(aStr);
     147         549 :   MOZ_ASSERT(str.FindCharInSet(dom::quota::QuotaManager::kReplaceChars) == kNotFound);
     148             : #endif
     149         549 : }
     150             : 
     151             : void
     152           0 : OriginAttributes::CreateAnonymizedSuffix(nsACString& aStr) const
     153             : {
     154           0 :   OriginAttributes attrs = *this;
     155             : 
     156           0 :   if (!attrs.mFirstPartyDomain.IsEmpty()) {
     157           0 :     attrs.mFirstPartyDomain.AssignLiteral("_anonymizedFirstPartyDomain_");
     158             :   }
     159             : 
     160           0 :   attrs.CreateSuffix(aStr);
     161           0 : }
     162             : 
     163             : namespace {
     164             : 
     165             : class MOZ_STACK_CLASS PopulateFromSuffixIterator final
     166             :   : public URLParams::ForEachIterator
     167             : {
     168             : public:
     169           0 :   explicit PopulateFromSuffixIterator(OriginAttributes* aOriginAttributes)
     170           0 :     : mOriginAttributes(aOriginAttributes)
     171             :   {
     172           0 :     MOZ_ASSERT(aOriginAttributes);
     173             :     // If mPrivateBrowsingId is passed in as >0 and is not present in the suffix,
     174             :     // then it will remain >0 when it should be 0 according to the suffix. Set to 0 before
     175             :     // iterating to fix this.
     176           0 :     mOriginAttributes->mPrivateBrowsingId = 0;
     177           0 :   }
     178             : 
     179           0 :   bool URLParamsIterator(const nsString& aName,
     180             :                          const nsString& aValue) override
     181             :   {
     182           0 :     if (aName.EqualsLiteral("appId")) {
     183             :       nsresult rv;
     184           0 :       int64_t val  = aValue.ToInteger64(&rv);
     185           0 :       NS_ENSURE_SUCCESS(rv, false);
     186           0 :       NS_ENSURE_TRUE(val <= UINT32_MAX, false);
     187           0 :       mOriginAttributes->mAppId = static_cast<uint32_t>(val);
     188             : 
     189           0 :       return true;
     190             :     }
     191             : 
     192           0 :     if (aName.EqualsLiteral("inBrowser")) {
     193           0 :       if (!aValue.EqualsLiteral("1")) {
     194           0 :         return false;
     195             :       }
     196             : 
     197           0 :       mOriginAttributes->mInIsolatedMozBrowser = true;
     198           0 :       return true;
     199             :     }
     200             : 
     201           0 :     if (aName.EqualsLiteral("addonId")) {
     202             :       // No longer supported. Silently ignore so that legacy origin strings
     203             :       // don't cause failures.
     204           0 :       return true;
     205             :     }
     206             : 
     207           0 :     if (aName.EqualsLiteral("userContextId")) {
     208             :       nsresult rv;
     209           0 :       int64_t val  = aValue.ToInteger64(&rv);
     210           0 :       NS_ENSURE_SUCCESS(rv, false);
     211           0 :       NS_ENSURE_TRUE(val <= UINT32_MAX, false);
     212           0 :       mOriginAttributes->mUserContextId  = static_cast<uint32_t>(val);
     213             : 
     214           0 :       return true;
     215             :     }
     216             : 
     217           0 :     if (aName.EqualsLiteral("privateBrowsingId")) {
     218             :       nsresult rv;
     219           0 :       int64_t val = aValue.ToInteger64(&rv);
     220           0 :       NS_ENSURE_SUCCESS(rv, false);
     221           0 :       NS_ENSURE_TRUE(val >= 0 && val <= UINT32_MAX, false);
     222           0 :       mOriginAttributes->mPrivateBrowsingId = static_cast<uint32_t>(val);
     223             : 
     224           0 :       return true;
     225             :     }
     226             : 
     227           0 :     if (aName.EqualsLiteral("firstPartyDomain")) {
     228           0 :       MOZ_RELEASE_ASSERT(mOriginAttributes->mFirstPartyDomain.IsEmpty());
     229           0 :       mOriginAttributes->mFirstPartyDomain.Assign(aValue);
     230           0 :       return true;
     231             :     }
     232             : 
     233             :     // No other attributes are supported.
     234           0 :     return false;
     235             :   }
     236             : 
     237             : private:
     238             :   OriginAttributes* mOriginAttributes;
     239             : };
     240             : 
     241             : } // namespace
     242             : 
     243             : bool
     244          47 : OriginAttributes::PopulateFromSuffix(const nsACString& aStr)
     245             : {
     246          47 :   if (aStr.IsEmpty()) {
     247          47 :     return true;
     248             :   }
     249             : 
     250           0 :   if (aStr[0] != '^') {
     251           0 :     return false;
     252             :   }
     253             : 
     254           0 :   URLParams params;
     255           0 :   params.ParseInput(Substring(aStr, 1, aStr.Length() - 1));
     256             : 
     257           0 :   PopulateFromSuffixIterator iterator(this);
     258           0 :   return params.ForEach(iterator);
     259             : }
     260             : 
     261             : bool
     262          84 : OriginAttributes::PopulateFromOrigin(const nsACString& aOrigin,
     263             :                                      nsACString& aOriginNoSuffix)
     264             : {
     265             :   // RFindChar is only available on nsCString.
     266         168 :   nsCString origin(aOrigin);
     267          84 :   int32_t pos = origin.RFindChar('^');
     268             : 
     269          84 :   if (pos == kNotFound) {
     270          84 :     aOriginNoSuffix = origin;
     271          84 :     return true;
     272             :   }
     273             : 
     274           0 :   aOriginNoSuffix = Substring(origin, 0, pos);
     275           0 :   return PopulateFromSuffix(Substring(origin, pos));
     276             : }
     277             : 
     278             : void
     279         105 : OriginAttributes::SyncAttributesWithPrivateBrowsing(bool aInPrivateBrowsing)
     280             : {
     281         105 :   mPrivateBrowsingId = aInPrivateBrowsing ? 1 : 0;
     282         105 : }
     283             : 
     284             : /* static */
     285             : bool
     286           0 : OriginAttributes::IsPrivateBrowsing(const nsACString& aOrigin)
     287             : {
     288           0 :   nsAutoCString dummy;
     289           0 :   OriginAttributes attrs;
     290           0 :   if (NS_WARN_IF(!attrs.PopulateFromOrigin(aOrigin, dummy))) {
     291           0 :     return false;
     292             :   }
     293             : 
     294           0 :   return !!attrs.mPrivateBrowsingId;
     295             : }
     296             : 
     297             : } // namespace mozilla

Generated by: LCOV version 1.13