LCOV - code coverage report
Current view: top level - chrome - nsChromeRegistryChrome.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 116 435 26.7 %
Date: 2018-08-07 16:35:00 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=2 sts=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/dom/ContentParent.h"
       8             : #include "RegistryMessageUtils.h"
       9             : #include "nsResProtocolHandler.h"
      10             : 
      11             : #include "nsChromeRegistryChrome.h"
      12             : 
      13             : #if defined(XP_WIN)
      14             : #include <windows.h>
      15             : #elif defined(XP_MACOSX)
      16             : #include <CoreServices/CoreServices.h>
      17             : #endif
      18             : 
      19             : #include "nsArrayEnumerator.h"
      20             : #include "nsComponentManager.h"
      21             : #include "nsEnumeratorUtils.h"
      22             : #include "nsNetUtil.h"
      23             : #include "nsStringEnumerator.h"
      24             : #include "nsTextFormatter.h"
      25             : #include "nsXPCOMCIDInternal.h"
      26             : 
      27             : #include "mozilla/LookAndFeel.h"
      28             : #include "mozilla/Unused.h"
      29             : #include "mozilla/intl/LocaleService.h"
      30             : 
      31             : #include "nsIObserverService.h"
      32             : #include "nsIPrefBranch.h"
      33             : #include "nsIPrefService.h"
      34             : #include "mozilla/Preferences.h"
      35             : #include "nsIResProtocolHandler.h"
      36             : #include "nsIScriptError.h"
      37             : #include "nsIXULRuntime.h"
      38             : 
      39             : #define SELECTED_SKIN_PREF   "general.skins.selectedSkin"
      40             : #define PACKAGE_OVERRIDE_BRANCH "chrome.override_package."
      41             : 
      42             : using namespace mozilla;
      43             : using mozilla::dom::ContentParent;
      44             : using mozilla::dom::PContentParent;
      45             : using mozilla::intl::LocaleService;
      46             : 
      47             : // We use a "best-fit" algorithm for matching locales and themes.
      48             : // 1) the exact selected locale/theme
      49             : // 2) (locales only) same language, different country
      50             : //    e.g. en-GB is the selected locale, only en-US is available
      51             : // 3) any available locale/theme
      52             : 
      53             : /**
      54             :  * Match the language-part of two lang-COUNTRY codes, hopefully but
      55             :  * not guaranteed to be in the form ab-CD or abz-CD. "ab" should also
      56             :  * work, any other garbage-in will produce undefined results as long
      57             :  * as it does not crash.
      58             :  */
      59             : static bool
      60           0 : LanguagesMatch(const nsACString& a, const nsACString& b)
      61             : {
      62           0 :   if (a.Length() < 2 || b.Length() < 2)
      63             :     return false;
      64             : 
      65           0 :   nsACString::const_iterator as, ae, bs, be;
      66           0 :   a.BeginReading(as);
      67           0 :   a.EndReading(ae);
      68           0 :   b.BeginReading(bs);
      69           0 :   b.EndReading(be);
      70             : 
      71           0 :   while (*as == *bs) {
      72           0 :     if (*as == '-')
      73             :       return true;
      74             : 
      75           0 :     ++as; ++bs;
      76             : 
      77             :     // reached the end
      78           0 :     if (as == ae && bs == be)
      79             :       return true;
      80             : 
      81             :     // "a" is short
      82           0 :     if (as == ae)
      83           0 :       return (*bs == '-');
      84             : 
      85             :     // "b" is short
      86           0 :     if (bs == be)
      87           0 :       return (*as == '-');
      88             :   }
      89             : 
      90             :   return false;
      91             : }
      92             : 
      93           0 : nsChromeRegistryChrome::nsChromeRegistryChrome()
      94             :   : mProfileLoaded(false)
      95           0 :   , mDynamicRegistration(true)
      96             : {
      97           0 : }
      98             : 
      99           0 : nsChromeRegistryChrome::~nsChromeRegistryChrome()
     100             : {
     101           0 : }
     102             : 
     103             : nsresult
     104           0 : nsChromeRegistryChrome::Init()
     105             : {
     106           0 :   nsresult rv = nsChromeRegistry::Init();
     107           0 :   if (NS_FAILED(rv))
     108             :     return rv;
     109             : 
     110           0 :   mSelectedSkin = NS_LITERAL_CSTRING("classic/1.0");
     111             : 
     112           0 :   bool safeMode = false;
     113           0 :   nsCOMPtr<nsIXULRuntime> xulrun (do_GetService(XULAPPINFO_SERVICE_CONTRACTID));
     114           0 :   if (xulrun)
     115           0 :     xulrun->GetInSafeMode(&safeMode);
     116             : 
     117           0 :   nsCOMPtr<nsIPrefService> prefserv (do_GetService(NS_PREFSERVICE_CONTRACTID));
     118           0 :   nsCOMPtr<nsIPrefBranch> prefs;
     119             : 
     120           0 :   if (prefserv) {
     121           0 :     if (safeMode) {
     122           0 :       prefserv->GetDefaultBranch(nullptr, getter_AddRefs(prefs));
     123             :     } else {
     124           0 :       prefs = do_QueryInterface(prefserv);
     125             :     }
     126             :   }
     127             : 
     128           0 :   if (!prefs) {
     129           0 :     NS_WARNING("Could not get pref service!");
     130             :   } else {
     131           0 :     nsAutoCString provider;
     132           0 :     rv = prefs->GetCharPref(SELECTED_SKIN_PREF, provider);
     133           0 :     if (NS_SUCCEEDED(rv))
     134           0 :       mSelectedSkin = provider;
     135             : 
     136           0 :     rv = prefs->AddObserver(SELECTED_SKIN_PREF, this, true);
     137             :   }
     138             : 
     139           0 :   nsCOMPtr<nsIObserverService> obsService = mozilla::services::GetObserverService();
     140           0 :   if (obsService) {
     141           0 :     obsService->AddObserver(this, "profile-initial-state", true);
     142           0 :     obsService->AddObserver(this, "intl:app-locales-changed", true);
     143             :   }
     144             : 
     145             :   return NS_OK;
     146             : }
     147             : 
     148             : NS_IMETHODIMP
     149           0 : nsChromeRegistryChrome::CheckForOSAccessibility()
     150             : {
     151             :   int32_t useAccessibilityTheme =
     152           0 :     LookAndFeel::GetInt(LookAndFeel::eIntID_UseAccessibilityTheme, 0);
     153             : 
     154           0 :   if (useAccessibilityTheme) {
     155             :     /* Set the skin to classic and remove pref observers */
     156           0 :     if (!mSelectedSkin.EqualsLiteral("classic/1.0")) {
     157           0 :       mSelectedSkin.AssignLiteral("classic/1.0");
     158           0 :       RefreshSkins();
     159             :     }
     160             : 
     161           0 :     nsCOMPtr<nsIPrefBranch> prefs (do_GetService(NS_PREFSERVICE_CONTRACTID));
     162           0 :     if (prefs) {
     163           0 :       prefs->RemoveObserver(SELECTED_SKIN_PREF, this);
     164             :     }
     165             :   }
     166             : 
     167           0 :   return NS_OK;
     168             : }
     169             : 
     170             : NS_IMETHODIMP
     171           0 : nsChromeRegistryChrome::GetLocalesForPackage(const nsACString& aPackage,
     172             :                                        nsIUTF8StringEnumerator* *aResult)
     173             : {
     174           0 :   nsCString realpackage;
     175           0 :   nsresult rv = OverrideLocalePackage(aPackage, realpackage);
     176           0 :   if (NS_FAILED(rv))
     177             :     return rv;
     178             : 
     179           0 :   nsTArray<nsCString> *a = new nsTArray<nsCString>;
     180           0 :   if (!a)
     181             :     return NS_ERROR_OUT_OF_MEMORY;
     182             : 
     183             :   PackageEntry* entry;
     184           0 :   if (mPackagesHash.Get(realpackage, &entry)) {
     185           0 :     entry->locales.EnumerateToArray(a);
     186             :   }
     187             : 
     188           0 :   rv = NS_NewAdoptingUTF8StringEnumerator(aResult, a);
     189           0 :   if (NS_FAILED(rv))
     190           0 :     delete a;
     191             : 
     192             :   return rv;
     193             : }
     194             : 
     195             : NS_IMETHODIMP
     196           0 : nsChromeRegistryChrome::IsLocaleRTL(const nsACString& package, bool *aResult)
     197             : {
     198           0 :   *aResult = false;
     199             : 
     200           0 :   nsAutoCString locale;
     201           0 :   GetSelectedLocale(package, false, locale);
     202           0 :   if (locale.Length() < 2)
     203             :     return NS_OK;
     204             : 
     205           0 :   *aResult = GetDirectionForLocale(locale);
     206           0 :   return NS_OK;
     207             : }
     208             : 
     209             : /**
     210             :  * This method negotiates only between the app locale and the available
     211             :  * chrome packages.
     212             :  *
     213             :  * If you want to get the current application's UI locale, please use
     214             :  * LocaleService::GetAppLocaleAsLangTag.
     215             :  */
     216             : nsresult
     217           0 : nsChromeRegistryChrome::GetSelectedLocale(const nsACString& aPackage,
     218             :                                           bool aAsBCP47,
     219             :                                           nsACString& aLocale)
     220             : {
     221           0 :   nsAutoCString reqLocale;
     222           0 :   if (aPackage.EqualsLiteral("global")) {
     223           0 :     LocaleService::GetInstance()->GetAppLocaleAsLangTag(reqLocale);
     224             :   } else {
     225           0 :     AutoTArray<nsCString, 10> requestedLocales;
     226           0 :     LocaleService::GetInstance()->GetRequestedLocales(requestedLocales);
     227           0 :     reqLocale.Assign(requestedLocales[0]);
     228             :   }
     229             : 
     230           0 :   nsCString realpackage;
     231           0 :   nsresult rv = OverrideLocalePackage(aPackage, realpackage);
     232           0 :   if (NS_FAILED(rv))
     233             :     return rv;
     234             :   PackageEntry* entry;
     235           0 :   if (!mPackagesHash.Get(realpackage, &entry))
     236             :     return NS_ERROR_FILE_NOT_FOUND;
     237             : 
     238           0 :   aLocale = entry->locales.GetSelected(reqLocale, nsProviderArray::LOCALE);
     239           0 :   if (aLocale.IsEmpty())
     240             :     return NS_ERROR_FAILURE;
     241             : 
     242           0 :   if (aAsBCP47) {
     243           0 :     SanitizeForBCP47(aLocale);
     244             :   }
     245             : 
     246             :   return NS_OK;
     247             : }
     248             : 
     249             : nsresult
     250           0 : nsChromeRegistryChrome::OverrideLocalePackage(const nsACString& aPackage,
     251             :                                               nsACString& aOverride)
     252             : {
     253           0 :   const nsACString& pref = NS_LITERAL_CSTRING(PACKAGE_OVERRIDE_BRANCH) + aPackage;
     254           0 :   nsAutoCString override;
     255             :   nsresult rv =
     256           0 :     mozilla::Preferences::GetCString(PromiseFlatCString(pref).get(), override);
     257           0 :   if (NS_SUCCEEDED(rv)) {
     258             :     aOverride = override;
     259             :   } else {
     260             :     aOverride = aPackage;
     261             :   }
     262           0 :   return NS_OK;
     263             : }
     264             : 
     265             : NS_IMETHODIMP
     266           0 : nsChromeRegistryChrome::Observe(nsISupports *aSubject, const char *aTopic,
     267             :                                 const char16_t *someData)
     268             : {
     269           0 :   nsresult rv = NS_OK;
     270             : 
     271           0 :   if (!strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic)) {
     272           0 :     nsCOMPtr<nsIPrefBranch> prefs (do_QueryInterface(aSubject));
     273           0 :     NS_ASSERTION(prefs, "Bad observer call!");
     274             : 
     275           0 :     NS_ConvertUTF16toUTF8 pref(someData);
     276             : 
     277           0 :     if (pref.EqualsLiteral(SELECTED_SKIN_PREF)) {
     278           0 :       nsAutoCString provider;
     279           0 :       rv = prefs->GetCharPref(pref.get(), provider);
     280           0 :       if (NS_FAILED(rv)) {
     281           0 :         NS_ERROR("Couldn't get new skin pref!");
     282           0 :         return rv;
     283             :       }
     284             : 
     285           0 :       mSelectedSkin = provider;
     286           0 :       RefreshSkins();
     287             :     } else {
     288           0 :       NS_ERROR("Unexpected pref!");
     289             :     }
     290             :   }
     291           0 :   else if (!strcmp("profile-initial-state", aTopic)) {
     292           0 :     mProfileLoaded = true;
     293             :   }
     294           0 :   else if (!strcmp("intl:app-locales-changed", aTopic)) {
     295           0 :     if (mProfileLoaded) {
     296           0 :       FlushAllCaches();
     297             :     }
     298             :   }
     299             :   else {
     300           0 :     NS_ERROR("Unexpected observer topic!");
     301             :   }
     302             : 
     303             :   return rv;
     304             : }
     305             : 
     306             : NS_IMETHODIMP
     307           0 : nsChromeRegistryChrome::CheckForNewChrome()
     308             : {
     309           0 :   mPackagesHash.Clear();
     310           0 :   mOverlayHash.Clear();
     311           0 :   mOverrideTable.Clear();
     312             : 
     313           0 :   mDynamicRegistration = false;
     314             : 
     315           0 :   nsComponentManagerImpl::gComponentManager->RereadChromeManifests();
     316             : 
     317           0 :   mDynamicRegistration = true;
     318             : 
     319           0 :   SendRegisteredChrome(nullptr);
     320           0 :   return NS_OK;
     321             : }
     322             : 
     323             : static void
     324         345 : SerializeURI(nsIURI* aURI,
     325             :              SerializedURI& aSerializedURI)
     326             : {
     327         345 :   if (!aURI)
     328             :     return;
     329             : 
     330         207 :   aURI->GetSpec(aSerializedURI.spec);
     331             : }
     332             : 
     333             : void
     334           1 : nsChromeRegistryChrome::SendRegisteredChrome(
     335             :     mozilla::dom::PContentParent* aParent)
     336             : {
     337           2 :   InfallibleTArray<ChromePackage> packages;
     338           0 :   InfallibleTArray<SubstitutionMapping> resources;
     339           0 :   InfallibleTArray<OverrideMapping> overrides;
     340             : 
     341          75 :   for (auto iter = mPackagesHash.Iter(); !iter.Done(); iter.Next()) {
     342           0 :     ChromePackage chromePackage;
     343           0 :     ChromePackageFromPackageEntry(iter.Key(), iter.UserData(), &chromePackage,
     344           0 :                                   mSelectedSkin);
     345           0 :     packages.AppendElement(chromePackage);
     346             :   }
     347             : 
     348             :   // If we were passed a parent then a new child process has been created and
     349             :   // has requested all of the chrome so send it the resources too. Otherwise
     350             :   // resource mappings are sent by the resource protocol handler dynamically.
     351           1 :   if (aParent) {
     352           0 :     nsCOMPtr<nsIIOService> io (do_GetIOService());
     353           0 :     NS_ENSURE_TRUE_VOID(io);
     354             : 
     355           2 :     nsCOMPtr<nsIProtocolHandler> ph;
     356           0 :     nsresult rv = io->GetProtocolHandler("resource", getter_AddRefs(ph));
     357           0 :     NS_ENSURE_SUCCESS_VOID(rv);
     358             : 
     359           3 :     nsCOMPtr<nsIResProtocolHandler> irph (do_QueryInterface(ph));
     360           0 :     nsResProtocolHandler* rph = static_cast<nsResProtocolHandler*>(irph.get());
     361           0 :     rv = rph->CollectSubstitutions(resources);
     362           0 :     NS_ENSURE_SUCCESS_VOID(rv);
     363             :   }
     364             : 
     365          39 :   for (auto iter = mOverrideTable.Iter(); !iter.Done(); iter.Next()) {
     366           0 :     SerializedURI chromeURI, overrideURI;
     367             : 
     368          18 :     SerializeURI(iter.Key(), chromeURI);
     369           0 :     SerializeURI(iter.UserData(), overrideURI);
     370             : 
     371          54 :     OverrideMapping override = { chromeURI, overrideURI };
     372           0 :     overrides.AppendElement(override);
     373             :   }
     374             : 
     375           2 :   nsAutoCString appLocale;
     376           0 :   LocaleService::GetInstance()->GetAppLocaleAsLangTag(appLocale);
     377             : 
     378           1 :   if (aParent) {
     379           0 :     bool success = aParent->SendRegisterChrome(packages, resources, overrides,
     380           0 :                                                appLocale, false);
     381           0 :     NS_ENSURE_TRUE_VOID(success);
     382             :   } else {
     383           0 :     nsTArray<ContentParent*> parents;
     384           0 :     ContentParent::GetAll(parents);
     385           0 :     if (!parents.Length())
     386           0 :       return;
     387             : 
     388           0 :     for (uint32_t i = 0; i < parents.Length(); i++) {
     389             :       DebugOnly<bool> success =
     390           0 :         parents[i]->SendRegisterChrome(packages, resources, overrides,
     391           0 :                                        appLocale, true);
     392           0 :       NS_WARNING_ASSERTION(success,
     393             :                            "couldn't reset a child's registered chrome");
     394             :     }
     395             :   }
     396             : }
     397             : 
     398             : /* static */ void
     399          91 : nsChromeRegistryChrome::ChromePackageFromPackageEntry(const nsACString& aPackageName,
     400             :                                                       PackageEntry* aPackage,
     401             :                                                       ChromePackage* aChromePackage,
     402             :                                                       const nsCString& aSelectedSkin)
     403             : {
     404         182 :   nsAutoCString appLocale;
     405           0 :   LocaleService::GetInstance()->GetAppLocaleAsLangTag(appLocale);
     406             : 
     407         182 :   SerializeURI(aPackage->baseURI, aChromePackage->contentBaseURI);
     408           0 :   SerializeURI(aPackage->locales.GetBase(appLocale, nsProviderArray::LOCALE),
     409           0 :                aChromePackage->localeBaseURI);
     410           0 :   SerializeURI(aPackage->skins.GetBase(aSelectedSkin, nsProviderArray::ANY),
     411           0 :                aChromePackage->skinBaseURI);
     412           0 :   aChromePackage->package = aPackageName;
     413           0 :   aChromePackage->flags = aPackage->flags;
     414           0 : }
     415             : 
     416             : static bool
     417          90 : CanLoadResource(nsIURI* aResourceURI)
     418             : {
     419          90 :   bool isLocalResource = false;
     420             :   (void)NS_URIChainHasFlags(aResourceURI,
     421             :                             nsIProtocolHandler::URI_IS_LOCAL_RESOURCE,
     422          90 :                             &isLocalResource);
     423           0 :   return isLocalResource;
     424             : }
     425             : 
     426             : nsIURI*
     427         364 : nsChromeRegistryChrome::GetBaseURIFromPackage(const nsCString& aPackage,
     428             :                                               const nsCString& aProvider,
     429             :                                               const nsCString& aPath)
     430             : {
     431             :   PackageEntry* entry;
     432         364 :   if (!mPackagesHash.Get(aPackage, &entry)) {
     433           0 :     if (!mInitialized)
     434             :       return nullptr;
     435             : 
     436           0 :     LogMessage("No chrome package registered for chrome://%s/%s/%s",
     437           0 :                aPackage.get(), aProvider.get(), aPath.get());
     438             : 
     439           0 :     return nullptr;
     440             :   }
     441             : 
     442         364 :   if (aProvider.EqualsLiteral("locale")) {
     443           0 :     nsAutoCString appLocale;
     444           0 :     LocaleService::GetInstance()->GetAppLocaleAsLangTag(appLocale);
     445           0 :     return entry->locales.GetBase(appLocale, nsProviderArray::LOCALE);
     446             :   }
     447         317 :   else if (aProvider.EqualsLiteral("skin")) {
     448           0 :     return entry->skins.GetBase(mSelectedSkin, nsProviderArray::ANY);
     449             :   }
     450         275 :   else if (aProvider.EqualsLiteral("content")) {
     451           0 :     return entry->baseURI;
     452             :   }
     453             :   return nullptr;
     454             : }
     455             : 
     456             : nsresult
     457         664 : nsChromeRegistryChrome::GetFlagsFromPackage(const nsCString& aPackage,
     458             :                                             uint32_t* aFlags)
     459             : {
     460             :   PackageEntry* entry;
     461         664 :   if (!mPackagesHash.Get(aPackage, &entry))
     462             :     return NS_ERROR_FILE_NOT_FOUND;
     463             : 
     464         664 :   *aFlags = entry->flags;
     465           0 :   return NS_OK;
     466             : }
     467             : 
     468             : nsChromeRegistryChrome::ProviderEntry*
     469         308 : nsChromeRegistryChrome::nsProviderArray::GetProvider(const nsACString& aPreferred, MatchType aType)
     470             : {
     471         616 :   size_t i = mArray.Length();
     472           0 :   if (!i)
     473             :     return nullptr;
     474             : 
     475             :   ProviderEntry* found = nullptr;  // Only set if we find a partial-match locale
     476             :   ProviderEntry* entry = nullptr;
     477             : 
     478         164 :   while (i--) {
     479           0 :     entry = &mArray[i];
     480           0 :     if (aPreferred.Equals(entry->provider))
     481             :       return entry;
     482             : 
     483           0 :     if (aType != LOCALE)
     484             :       continue;
     485             : 
     486           0 :     if (LanguagesMatch(aPreferred, entry->provider)) {
     487             :       found = entry;
     488             :       continue;
     489             :     }
     490             : 
     491           0 :     if (!found && entry->provider.EqualsLiteral("en-US"))
     492           0 :       found = entry;
     493             :   }
     494             : 
     495           0 :   if (!found && aType != EXACT)
     496             :     return entry;
     497             : 
     498           0 :   return found;
     499             : }
     500             : 
     501             : nsIURI*
     502         271 : nsChromeRegistryChrome::nsProviderArray::GetBase(const nsACString& aPreferred, MatchType aType)
     503             : {
     504         271 :   ProviderEntry* provider = GetProvider(aPreferred, aType);
     505             : 
     506         271 :   if (!provider)
     507             :     return nullptr;
     508             : 
     509         326 :   return provider->baseURI;
     510             : }
     511             : 
     512             : const nsACString&
     513           3 : nsChromeRegistryChrome::nsProviderArray::GetSelected(const nsACString& aPreferred, MatchType aType)
     514             : {
     515           3 :   ProviderEntry* entry = GetProvider(aPreferred, aType);
     516             : 
     517           3 :   if (entry)
     518           0 :     return entry->provider;
     519             : 
     520           2 :   return EmptyCString();
     521             : }
     522             : 
     523             : void
     524          34 : nsChromeRegistryChrome::nsProviderArray::SetBase(const nsACString& aProvider, nsIURI* aBaseURL)
     525             : {
     526          34 :   ProviderEntry* provider = GetProvider(aProvider, EXACT);
     527             : 
     528          34 :   if (provider) {
     529           0 :     provider->baseURI = aBaseURL;
     530           0 :     return;
     531             :   }
     532             : 
     533             :   // no existing entries, add a new one
     534          34 :   mArray.AppendElement(ProviderEntry(aProvider, aBaseURL));
     535             : }
     536             : 
     537             : void
     538           0 : nsChromeRegistryChrome::nsProviderArray::EnumerateToArray(nsTArray<nsCString> *a)
     539             : {
     540           0 :   int32_t i = mArray.Length();
     541           0 :   while (i--) {
     542           0 :     a->AppendElement(mArray[i].provider);
     543             :   }
     544           0 : }
     545             : 
     546             : void
     547           0 : nsChromeRegistryChrome::OverlayListEntry::AddURI(nsIURI* aURI)
     548             : {
     549           0 :   int32_t i = mArray.Count();
     550           0 :   while (i--) {
     551             :     bool equals;
     552           0 :     if (NS_SUCCEEDED(aURI->Equals(mArray[i], &equals)) && equals)
     553           0 :       return;
     554             :   }
     555             : 
     556           0 :   mArray.AppendObject(aURI);
     557             : }
     558             : 
     559             : void
     560           0 : nsChromeRegistryChrome::OverlayListHash::Add(nsIURI* aBase, nsIURI* aOverlay)
     561             : {
     562           0 :   OverlayListEntry* entry = mTable.PutEntry(aBase);
     563           0 :   if (entry)
     564           0 :     entry->AddURI(aOverlay);
     565           0 : }
     566             : 
     567             : const nsCOMArray<nsIURI>*
     568           3 : nsChromeRegistryChrome::OverlayListHash::GetArray(nsIURI* aBase)
     569             : {
     570           6 :   OverlayListEntry* entry = mTable.GetEntry(aBase);
     571           0 :   if (!entry)
     572             :     return nullptr;
     573             : 
     574           0 :   return &entry->mArray;
     575             : }
     576             : 
     577             : #ifdef MOZ_XUL
     578             : NS_IMETHODIMP
     579           3 : nsChromeRegistryChrome::GetXULOverlays(nsIURI *aChromeURL,
     580             :                                        nsISimpleEnumerator **aResult)
     581             : {
     582           6 :   nsCOMPtr<nsIURI> chromeURLWithoutHash;
     583           0 :   if (aChromeURL) {
     584           0 :     aChromeURL->CloneIgnoringRef(getter_AddRefs(chromeURLWithoutHash));
     585             :   }
     586           3 :   const nsCOMArray<nsIURI>* parray = mOverlayHash.GetArray(chromeURLWithoutHash);
     587           0 :   if (!parray)
     588           0 :     return NS_NewEmptyEnumerator(aResult);
     589             : 
     590           0 :   return NS_NewArrayEnumerator(aResult, *parray);
     591             : }
     592             : #endif // MOZ_XUL
     593             : 
     594             : nsIURI*
     595           0 : nsChromeRegistry::ManifestProcessingContext::GetManifestURI()
     596             : {
     597         216 :   if (!mManifestURI) {
     598           0 :     nsCString uri;
     599           0 :     mFile.GetURIString(uri);
     600           0 :     NS_NewURI(getter_AddRefs(mManifestURI), uri);
     601             :   }
     602           0 :   return mManifestURI;
     603             : }
     604             : 
     605             : already_AddRefed<nsIURI>
     606           1 : nsChromeRegistry::ManifestProcessingContext::ResolveURI(const char* uri)
     607             : {
     608         108 :   nsIURI* baseuri = GetManifestURI();
     609         108 :   if (!baseuri)
     610             :     return nullptr;
     611             : 
     612         216 :   nsCOMPtr<nsIURI> resolved;
     613           0 :   nsresult rv = NS_NewURI(getter_AddRefs(resolved), uri, baseuri);
     614           0 :   if (NS_FAILED(rv))
     615             :     return nullptr;
     616             : 
     617         108 :   return resolved.forget();
     618             : }
     619             : 
     620             : static void
     621          72 : EnsureLowerCase(char *aBuf)
     622             : {
     623        1618 :   for (; *aBuf; ++aBuf) {
     624           0 :     char ch = *aBuf;
     625           0 :     if (ch >= 'A' && ch <= 'Z')
     626           0 :       *aBuf = ch + 'a' - 'A';
     627             :   }
     628           0 : }
     629             : 
     630             : static void
     631          73 : SendManifestEntry(const ChromeRegistryItem &aItem)
     632             : {
     633           0 :   nsTArray<ContentParent*> parents;
     634          73 :   ContentParent::GetAll(parents);
     635          73 :   if (!parents.Length())
     636          73 :     return;
     637             : 
     638           0 :   for (uint32_t i = 0; i < parents.Length(); i++) {
     639           0 :     Unused << parents[i]->SendRegisterChromeItem(aItem);
     640             :   }
     641             : }
     642             : 
     643             : void
     644           0 : nsChromeRegistryChrome::ManifestContent(ManifestProcessingContext& cx, int lineno,
     645             :                                         char *const * argv, int flags)
     646             : {
     647           0 :   char* package = argv[0];
     648          21 :   char* uri = argv[1];
     649             : 
     650           0 :   EnsureLowerCase(package);
     651             : 
     652           0 :   nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
     653          21 :   if (!resolved) {
     654           0 :     LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
     655           0 :                           "During chrome registration, unable to create URI '%s'.", uri);
     656           0 :     return;
     657             :   }
     658             : 
     659          21 :   if (!CanLoadResource(resolved)) {
     660           0 :     LogMessageWithContext(resolved, lineno, nsIScriptError::warningFlag,
     661             :                           "During chrome registration, cannot register non-local URI '%s' as content.",
     662           0 :                           uri);
     663           0 :     return;
     664             :   }
     665             : 
     666           0 :   nsDependentCString packageName(package);
     667          21 :   PackageEntry* entry = mPackagesHash.LookupOrAdd(packageName);
     668           0 :   entry->baseURI = resolved;
     669           0 :   entry->flags = flags;
     670             : 
     671           1 :   if (mDynamicRegistration) {
     672           1 :     ChromePackage chromePackage;
     673          21 :     ChromePackageFromPackageEntry(packageName, entry, &chromePackage,
     674          21 :                                   mSelectedSkin);
     675           0 :     SendManifestEntry(chromePackage);
     676             :   }
     677             : }
     678             : 
     679             : void
     680          23 : nsChromeRegistryChrome::ManifestLocale(ManifestProcessingContext& cx, int lineno,
     681             :                                        char *const * argv, int flags)
     682             : {
     683           0 :   char* package = argv[0];
     684           0 :   char* provider = argv[1];
     685           0 :   char* uri = argv[2];
     686             : 
     687           0 :   EnsureLowerCase(package);
     688             : 
     689           0 :   nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
     690           0 :   if (!resolved) {
     691           0 :     LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
     692           0 :                           "During chrome registration, unable to create URI '%s'.", uri);
     693           0 :     return;
     694             :   }
     695             : 
     696           0 :   if (!CanLoadResource(resolved)) {
     697           0 :     LogMessageWithContext(resolved, lineno, nsIScriptError::warningFlag,
     698             :                           "During chrome registration, cannot register non-local URI '%s' as content.",
     699           0 :                           uri);
     700           0 :     return;
     701             :   }
     702             : 
     703           0 :   nsDependentCString packageName(package);
     704          23 :   PackageEntry* entry = mPackagesHash.LookupOrAdd(packageName);
     705           0 :   entry->locales.SetBase(nsDependentCString(provider), resolved);
     706             : 
     707           1 :   if (mDynamicRegistration) {
     708           1 :     ChromePackage chromePackage;
     709           0 :     ChromePackageFromPackageEntry(packageName, entry, &chromePackage,
     710          23 :                                   mSelectedSkin);
     711          23 :     SendManifestEntry(chromePackage);
     712             :   }
     713             : 
     714             :   // We use mainPackage as the package we track for reporting new locales being
     715             :   // registered. For most cases it will be "global", but for Fennec it will be
     716             :   // "browser".
     717          46 :   nsAutoCString mainPackage;
     718          46 :   nsresult rv = OverrideLocalePackage(NS_LITERAL_CSTRING("global"), mainPackage);
     719           0 :   if (NS_FAILED(rv)) {
     720           0 :     return;
     721             :   }
     722             : }
     723             : 
     724             : void
     725           0 : nsChromeRegistryChrome::ManifestSkin(ManifestProcessingContext& cx, int lineno,
     726             :                                      char *const * argv, int flags)
     727             : {
     728          11 :   char* package = argv[0];
     729          11 :   char* provider = argv[1];
     730          11 :   char* uri = argv[2];
     731             : 
     732          11 :   EnsureLowerCase(package);
     733             : 
     734           0 :   nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
     735           0 :   if (!resolved) {
     736           0 :     LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
     737           0 :                           "During chrome registration, unable to create URI '%s'.", uri);
     738           0 :     return;
     739             :   }
     740             : 
     741           0 :   if (!CanLoadResource(resolved)) {
     742           0 :     LogMessageWithContext(resolved, lineno, nsIScriptError::warningFlag,
     743             :                           "During chrome registration, cannot register non-local URI '%s' as content.",
     744           0 :                           uri);
     745           0 :     return;
     746             :   }
     747             : 
     748           0 :   nsDependentCString packageName(package);
     749          11 :   PackageEntry* entry = mPackagesHash.LookupOrAdd(packageName);
     750           0 :   entry->skins.SetBase(nsDependentCString(provider), resolved);
     751             : 
     752           1 :   if (mDynamicRegistration) {
     753           1 :     ChromePackage chromePackage;
     754           1 :     ChromePackageFromPackageEntry(packageName, entry, &chromePackage,
     755          11 :                                   mSelectedSkin);
     756          11 :     SendManifestEntry(chromePackage);
     757             :   }
     758             : }
     759             : 
     760             : void
     761           0 : nsChromeRegistryChrome::ManifestOverlay(ManifestProcessingContext& cx, int lineno,
     762             :                                         char *const * argv, int flags)
     763             : {
     764           0 :   char* base = argv[0];
     765           0 :   char* overlay = argv[1];
     766             : 
     767           0 :   nsCOMPtr<nsIURI> baseuri = cx.ResolveURI(base);
     768           0 :   nsCOMPtr<nsIURI> overlayuri = cx.ResolveURI(overlay);
     769           0 :   if (!baseuri || !overlayuri) {
     770           0 :     LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
     771           0 :                           "During chrome registration, unable to create URI.");
     772           0 :     return;
     773             :   }
     774             : 
     775           0 :   if (!CanLoadResource(overlayuri)) {
     776           0 :     LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
     777           0 :                           "Cannot register non-local URI '%s' as an overlay.", overlay);
     778           0 :     return;
     779             :   }
     780             : 
     781           0 :   nsCOMPtr<nsIURI> baseuriWithoutHash;
     782           0 :   baseuri->CloneIgnoringRef(getter_AddRefs(baseuriWithoutHash));
     783             : 
     784           0 :   mOverlayHash.Add(baseuriWithoutHash, overlayuri);
     785             : }
     786             : 
     787             : void
     788           1 : nsChromeRegistryChrome::ManifestOverride(ManifestProcessingContext& cx, int lineno,
     789             :                                          char *const * argv, int flags)
     790             : {
     791           1 :   char* chrome = argv[0];
     792           1 :   char* resolved = argv[1];
     793             : 
     794           1 :   nsCOMPtr<nsIURI> chromeuri = cx.ResolveURI(chrome);
     795          36 :   nsCOMPtr<nsIURI> resolveduri = cx.ResolveURI(resolved);
     796          36 :   if (!chromeuri || !resolveduri) {
     797           0 :     LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
     798           0 :                           "During chrome registration, unable to create URI.");
     799           0 :     return;
     800             :   }
     801             : 
     802          18 :   if (cx.mType == NS_SKIN_LOCATION) {
     803           0 :     bool chromeSkinOnly = false;
     804           0 :     nsresult rv = chromeuri->SchemeIs("chrome", &chromeSkinOnly);
     805           0 :     chromeSkinOnly = chromeSkinOnly && NS_SUCCEEDED(rv);
     806           0 :     if (chromeSkinOnly) {
     807           0 :       rv = resolveduri->SchemeIs("chrome", &chromeSkinOnly);
     808           0 :       chromeSkinOnly = chromeSkinOnly && NS_SUCCEEDED(rv);
     809             :     }
     810           0 :     if (chromeSkinOnly) {
     811           0 :       nsAutoCString chromePath, resolvedPath;
     812           0 :       chromeuri->GetPathQueryRef(chromePath);
     813           0 :       resolveduri->GetPathQueryRef(resolvedPath);
     814           0 :       chromeSkinOnly = StringBeginsWith(chromePath, NS_LITERAL_CSTRING("/skin/")) &&
     815           0 :                        StringBeginsWith(resolvedPath, NS_LITERAL_CSTRING("/skin/"));
     816             :     }
     817           0 :     if (!chromeSkinOnly) {
     818           0 :       LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
     819             :                             "Cannot register non-chrome://.../skin/ URIs '%s' and '%s' as overrides and/or to be overridden from a skin manifest.",
     820           0 :                             chrome, resolved);
     821           0 :       return;
     822             :     }
     823             :   }
     824             : 
     825           1 :   if (!CanLoadResource(resolveduri)) {
     826           0 :     LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
     827           0 :                           "Cannot register non-local URI '%s' for an override.", resolved);
     828           0 :     return;
     829             :   }
     830          36 :   mOverrideTable.Put(chromeuri, resolveduri);
     831             : 
     832          18 :   if (mDynamicRegistration) {
     833          36 :     SerializedURI serializedChrome;
     834           0 :     SerializedURI serializedOverride;
     835             : 
     836          18 :     SerializeURI(chromeuri, serializedChrome);
     837           0 :     SerializeURI(resolveduri, serializedOverride);
     838             : 
     839           0 :     OverrideMapping override = { serializedChrome, serializedOverride };
     840           1 :     SendManifestEntry(override);
     841             :   }
     842             : }
     843             : 
     844             : void
     845           0 : nsChromeRegistryChrome::ManifestResource(ManifestProcessingContext& cx, int lineno,
     846             :                                          char *const * argv, int flags)
     847             : {
     848           1 :   char* package = argv[0];
     849           1 :   char* uri = argv[1];
     850             : 
     851           1 :   EnsureLowerCase(package);
     852          34 :   nsDependentCString host(package);
     853             : 
     854           1 :   nsCOMPtr<nsIIOService> io = mozilla::services::GetIOService();
     855           1 :   if (!io) {
     856           0 :     NS_WARNING("No IO service trying to process chrome manifests");
     857           0 :     return;
     858             :   }
     859             : 
     860           1 :   nsCOMPtr<nsIProtocolHandler> ph;
     861           1 :   nsresult rv = io->GetProtocolHandler("resource", getter_AddRefs(ph));
     862          17 :   if (NS_FAILED(rv))
     863           0 :     return;
     864             : 
     865          51 :   nsCOMPtr<nsIResProtocolHandler> rph = do_QueryInterface(ph);
     866             : 
     867          34 :   nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
     868           0 :   if (!resolved) {
     869           0 :     LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
     870           0 :                           "During chrome registration, unable to create URI '%s'.", uri);
     871           0 :     return;
     872             :   }
     873             : 
     874          17 :   if (!CanLoadResource(resolved)) {
     875           0 :     LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
     876             :                           "Warning: cannot register non-local URI '%s' as a resource.",
     877           0 :                           uri);
     878           0 :     return;
     879             :   }
     880             : 
     881             :   // By default, Firefox resources are not content-accessible unless the
     882             :   // manifests opts in.
     883           0 :   bool contentAccessible = (flags & nsChromeRegistry::CONTENT_ACCESSIBLE);
     884             : 
     885          17 :   uint32_t substitutionFlags = 0;
     886          17 :   if (contentAccessible) {
     887           6 :     substitutionFlags |= nsIResProtocolHandler::ALLOW_CONTENT_ACCESS;
     888             :   }
     889          34 :   rv = rph->SetSubstitutionWithFlags(host, resolved, substitutionFlags);
     890          17 :   if (NS_FAILED(rv)) {
     891           0 :     LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
     892             :                           "Warning: cannot set substitution for '%s'.",
     893           0 :                           uri);
     894             :   }
     895             : }

Generated by: LCOV version 1.13-14-ga5dd952