LCOV - code coverage report
Current view: top level - chrome - nsChromeRegistry.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 138 345 40.0 %
Date: 2017-07-14 16:53:18 Functions: 14 26 53.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=2 sw=2 et tw=78: */
       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 "nsChromeRegistry.h"
       8             : #include "nsChromeRegistryChrome.h"
       9             : #include "nsChromeRegistryContent.h"
      10             : 
      11             : #include "nsCOMPtr.h"
      12             : #include "nsError.h"
      13             : #include "nsEscape.h"
      14             : #include "nsNetUtil.h"
      15             : #include "nsString.h"
      16             : #include "nsQueryObject.h"
      17             : 
      18             : #include "mozilla/dom/URL.h"
      19             : #include "nsIConsoleService.h"
      20             : #include "nsIDocument.h"
      21             : #include "nsIDOMDocument.h"
      22             : #include "nsIDOMWindowCollection.h"
      23             : #include "nsIDOMWindow.h"
      24             : #include "nsIObserverService.h"
      25             : #include "nsIPresShell.h"
      26             : #include "nsIScriptError.h"
      27             : #include "nsIWindowMediator.h"
      28             : #include "nsIPrefService.h"
      29             : #include "mozilla/Preferences.h"
      30             : #include "mozilla/Printf.h"
      31             : #include "mozilla/StyleSheet.h"
      32             : #include "mozilla/StyleSheetInlines.h"
      33             : #include "mozilla/dom/Location.h"
      34             : 
      35             : #ifdef ENABLE_INTL_API
      36             : #include "unicode/uloc.h"
      37             : #endif
      38             : 
      39             : nsChromeRegistry* nsChromeRegistry::gChromeRegistry;
      40             : 
      41             : // DO NOT use namespace mozilla; it'll break due to a naming conflict between
      42             : // mozilla::TextRange and a TextRange in OSX headers.
      43             : using mozilla::StyleSheet;
      44             : using mozilla::dom::IsChromeURI;
      45             : using mozilla::dom::Location;
      46             : 
      47             : ////////////////////////////////////////////////////////////////////////////////
      48             : 
      49             : void
      50           0 : nsChromeRegistry::LogMessage(const char* aMsg, ...)
      51             : {
      52             :   nsCOMPtr<nsIConsoleService> console
      53           0 :     (do_GetService(NS_CONSOLESERVICE_CONTRACTID));
      54           0 :   if (!console)
      55           0 :     return;
      56             : 
      57             :   va_list args;
      58           0 :   va_start(args, aMsg);
      59           0 :   mozilla::SmprintfPointer formatted = mozilla::Vsmprintf(aMsg, args);
      60           0 :   va_end(args);
      61           0 :   if (!formatted)
      62           0 :     return;
      63             : 
      64           0 :   console->LogStringMessage(NS_ConvertUTF8toUTF16(formatted.get()).get());
      65             : }
      66             : 
      67             : void
      68           0 : nsChromeRegistry::LogMessageWithContext(nsIURI* aURL, uint32_t aLineNumber, uint32_t flags,
      69             :                                         const char* aMsg, ...)
      70             : {
      71             :   nsresult rv;
      72             : 
      73             :   nsCOMPtr<nsIConsoleService> console
      74           0 :     (do_GetService(NS_CONSOLESERVICE_CONTRACTID));
      75             : 
      76             :   nsCOMPtr<nsIScriptError> error
      77           0 :     (do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
      78           0 :   if (!console || !error)
      79           0 :     return;
      80             : 
      81             :   va_list args;
      82           0 :   va_start(args, aMsg);
      83           0 :   mozilla::SmprintfPointer formatted = mozilla::Vsmprintf(aMsg, args);
      84           0 :   va_end(args);
      85           0 :   if (!formatted)
      86           0 :     return;
      87             : 
      88           0 :   nsCString spec;
      89           0 :   if (aURL)
      90           0 :     aURL->GetSpec(spec);
      91             : 
      92           0 :   rv = error->Init(NS_ConvertUTF8toUTF16(formatted.get()),
      93           0 :                    NS_ConvertUTF8toUTF16(spec),
      94           0 :                    EmptyString(),
      95           0 :                    aLineNumber, 0, flags, "chrome registration");
      96             : 
      97           0 :   if (NS_FAILED(rv))
      98           0 :     return;
      99             : 
     100           0 :   console->LogMessage(error);
     101             : }
     102             : 
     103           0 : nsChromeRegistry::~nsChromeRegistry()
     104             : {
     105           0 :   gChromeRegistry = nullptr;
     106           0 : }
     107             : 
     108         981 : NS_INTERFACE_MAP_BEGIN(nsChromeRegistry)
     109         981 :   NS_INTERFACE_MAP_ENTRY(nsIChromeRegistry)
     110          88 :   NS_INTERFACE_MAP_ENTRY(nsIXULChromeRegistry)
     111          30 :   NS_INTERFACE_MAP_ENTRY(nsIToolkitChromeRegistry)
     112             : #ifdef MOZ_XUL
     113          23 :   NS_INTERFACE_MAP_ENTRY(nsIXULOverlayProvider)
     114             : #endif
     115          10 :   NS_INTERFACE_MAP_ENTRY(nsIObserver)
     116           8 :   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
     117           4 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIChromeRegistry)
     118           0 : NS_INTERFACE_MAP_END
     119             : 
     120        1468 : NS_IMPL_ADDREF(nsChromeRegistry)
     121        1458 : NS_IMPL_RELEASE(nsChromeRegistry)
     122             : 
     123             : ////////////////////////////////////////////////////////////////////////////////
     124             : // nsIChromeRegistry methods:
     125             : 
     126             : already_AddRefed<nsIChromeRegistry>
     127           4 : nsChromeRegistry::GetService()
     128             : {
     129           4 :   if (!gChromeRegistry)
     130             :   {
     131             :     // We don't actually want this ref, we just want the service to
     132             :     // initialize if it hasn't already.
     133             :     nsCOMPtr<nsIChromeRegistry> reg(
     134           4 :         do_GetService(NS_CHROMEREGISTRY_CONTRACTID));
     135           2 :     if (!gChromeRegistry)
     136           0 :       return nullptr;
     137             :   }
     138           8 :   nsCOMPtr<nsIChromeRegistry> registry = gChromeRegistry;
     139           4 :   return registry.forget();
     140             : }
     141             : 
     142             : nsresult
     143           3 : nsChromeRegistry::Init()
     144             : {
     145             :   // This initialization process is fairly complicated and may cause reentrant
     146             :   // getservice calls to resolve chrome URIs (especially locale files). We
     147             :   // don't want that, so we inform the protocol handler about our existence
     148             :   // before we are actually fully initialized.
     149           3 :   gChromeRegistry = this;
     150             : 
     151           3 :   mInitialized = true;
     152             : 
     153           3 :   return NS_OK;
     154             : }
     155             : 
     156             : nsresult
     157         822 : nsChromeRegistry::GetProviderAndPath(nsIURL* aChromeURL,
     158             :                                      nsACString& aProvider, nsACString& aPath)
     159             : {
     160             :   nsresult rv;
     161             : 
     162             : #ifdef DEBUG
     163             :   bool isChrome;
     164         822 :   aChromeURL->SchemeIs("chrome", &isChrome);
     165         822 :   NS_ASSERTION(isChrome, "Non-chrome URI?");
     166             : #endif
     167             : 
     168        1644 :   nsAutoCString path;
     169         822 :   rv = aChromeURL->GetPath(path);
     170         822 :   NS_ENSURE_SUCCESS(rv, rv);
     171             : 
     172         822 :   if (path.Length() < 3) {
     173           0 :     LogMessage("Invalid chrome URI: %s", path.get());
     174           0 :     return NS_ERROR_FAILURE;
     175             :   }
     176             : 
     177         822 :   path.SetLength(nsUnescapeCount(path.BeginWriting()));
     178         822 :   NS_ASSERTION(path.First() == '/', "Path should always begin with a slash!");
     179             : 
     180         822 :   int32_t slash = path.FindChar('/', 1);
     181         822 :   if (slash == 1) {
     182           0 :     LogMessage("Invalid chrome URI: %s", path.get());
     183           0 :     return NS_ERROR_FAILURE;
     184             :   }
     185             : 
     186         822 :   if (slash == -1) {
     187           0 :     aPath.Truncate();
     188             :   }
     189             :   else {
     190         822 :     if (slash == (int32_t) path.Length() - 1)
     191           3 :       aPath.Truncate();
     192             :     else
     193         819 :       aPath.Assign(path.get() + slash + 1, path.Length() - slash - 1);
     194             : 
     195         822 :     --slash;
     196             :   }
     197             : 
     198         822 :   aProvider.Assign(path.get() + 1, slash);
     199         822 :   return NS_OK;
     200             : }
     201             : 
     202             : 
     203             : nsresult
     204         589 : nsChromeRegistry::Canonify(nsIURL* aChromeURL)
     205             : {
     206         589 :   NS_NAMED_LITERAL_CSTRING(kSlash, "/");
     207             : 
     208             :   nsresult rv;
     209             : 
     210        1178 :   nsAutoCString provider, path;
     211         589 :   rv = GetProviderAndPath(aChromeURL, provider, path);
     212         589 :   NS_ENSURE_SUCCESS(rv, rv);
     213             : 
     214         589 :   if (path.IsEmpty()) {
     215           6 :     nsAutoCString package;
     216           3 :     rv = aChromeURL->GetHost(package);
     217           3 :     NS_ENSURE_SUCCESS(rv, rv);
     218             : 
     219             :     // we re-use the "path" local string to build a new URL path
     220           3 :     path.Assign(kSlash + provider + kSlash + package);
     221           3 :     if (provider.EqualsLiteral("content")) {
     222           1 :       path.AppendLiteral(".xul");
     223             :     }
     224           2 :     else if (provider.EqualsLiteral("locale")) {
     225           0 :       path.AppendLiteral(".dtd");
     226             :     }
     227           2 :     else if (provider.EqualsLiteral("skin")) {
     228           2 :       path.AppendLiteral(".css");
     229             :     }
     230             :     else {
     231           0 :       return NS_ERROR_INVALID_ARG;
     232             :     }
     233           3 :     aChromeURL->SetPath(path);
     234             :   }
     235             :   else {
     236             :     // prevent directory traversals ("..")
     237             :     // path is already unescaped once, but uris can get unescaped twice
     238         586 :     const char* pos = path.BeginReading();
     239         586 :     const char* end = path.EndReading();
     240       25118 :     while (pos < end) {
     241       12266 :       switch (*pos) {
     242             :         case ':':
     243           0 :           return NS_ERROR_DOM_BAD_URI;
     244             :         case '.':
     245         583 :           if (pos[1] == '.')
     246           0 :             return NS_ERROR_DOM_BAD_URI;
     247         583 :           break;
     248             :         case '%':
     249             :           // chrome: URIs with double-escapes are trying to trick us.
     250             :           // watch for %2e, and %25 in case someone triple unescapes
     251           0 :           if (pos[1] == '2' &&
     252           0 :                ( pos[2] == 'e' || pos[2] == 'E' ||
     253           0 :                  pos[2] == '5' ))
     254           0 :             return NS_ERROR_DOM_BAD_URI;
     255           0 :           break;
     256             :         case '?':
     257             :         case '#':
     258         180 :           pos = end;
     259         180 :           continue;
     260             :       }
     261       12086 :       ++pos;
     262             :     }
     263             :   }
     264             : 
     265         589 :   return NS_OK;
     266             : }
     267             : 
     268             : NS_IMETHODIMP
     269         207 : nsChromeRegistry::ConvertChromeURL(nsIURI* aChromeURI, nsIURI* *aResult)
     270             : {
     271             :   nsresult rv;
     272         207 :   if (NS_WARN_IF(!aChromeURI)) {
     273           0 :     return NS_ERROR_INVALID_ARG;
     274             :   }
     275             : 
     276         207 :   if (mOverrideTable.Get(aChromeURI, aResult))
     277           0 :     return NS_OK;
     278             : 
     279         414 :   nsCOMPtr<nsIURL> chromeURL (do_QueryInterface(aChromeURI));
     280         207 :   NS_ENSURE_TRUE(chromeURL, NS_NOINTERFACE);
     281             : 
     282         414 :   nsAutoCString package, provider, path;
     283         207 :   rv = chromeURL->GetHostPort(package);
     284         207 :   NS_ENSURE_SUCCESS(rv, rv);
     285             : 
     286         207 :   rv = GetProviderAndPath(chromeURL, provider, path);
     287         207 :   NS_ENSURE_SUCCESS(rv, rv);
     288             : 
     289         207 :   nsIURI* baseURI = GetBaseURIFromPackage(package, provider, path);
     290             : 
     291             :   uint32_t flags;
     292         207 :   rv = GetFlagsFromPackage(package, &flags);
     293         207 :   if (NS_FAILED(rv))
     294           0 :     return rv;
     295             : 
     296         207 :   if (!baseURI) {
     297           0 :     LogMessage("No chrome package registered for chrome://%s/%s/%s",
     298           0 :                package.get(), provider.get(), path.get());
     299           0 :     return NS_ERROR_FILE_NOT_FOUND;
     300             :   }
     301             : 
     302         207 :   return NS_NewURI(aResult, path, nullptr, baseURI);
     303             : }
     304             : 
     305             : ////////////////////////////////////////////////////////////////////////
     306             : 
     307             : // theme stuff
     308             : 
     309             : 
     310           0 : static void FlushSkinBindingsForWindow(nsPIDOMWindowOuter* aWindow)
     311             : {
     312             :   // Get the document.
     313           0 :   nsCOMPtr<nsIDocument> document = aWindow->GetDoc();
     314           0 :   if (!document)
     315           0 :     return;
     316             : 
     317             :   // Annihilate all XBL bindings.
     318           0 :   document->FlushSkinBindings();
     319             : }
     320             : 
     321             : // XXXbsmedberg: move this to nsIWindowMediator
     322           0 : NS_IMETHODIMP nsChromeRegistry::RefreshSkins()
     323             : {
     324             :   nsCOMPtr<nsIWindowMediator> windowMediator
     325           0 :     (do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
     326           0 :   if (!windowMediator)
     327           0 :     return NS_OK;
     328             : 
     329           0 :   nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
     330           0 :   windowMediator->GetEnumerator(nullptr, getter_AddRefs(windowEnumerator));
     331             :   bool more;
     332           0 :   windowEnumerator->HasMoreElements(&more);
     333           0 :   while (more) {
     334           0 :     nsCOMPtr<nsISupports> protoWindow;
     335           0 :     windowEnumerator->GetNext(getter_AddRefs(protoWindow));
     336           0 :     if (protoWindow) {
     337           0 :       nsCOMPtr<nsPIDOMWindowOuter> domWindow = do_QueryInterface(protoWindow);
     338           0 :       if (domWindow)
     339           0 :         FlushSkinBindingsForWindow(domWindow);
     340             :     }
     341           0 :     windowEnumerator->HasMoreElements(&more);
     342             :   }
     343             : 
     344           0 :   FlushSkinCaches();
     345             : 
     346           0 :   windowMediator->GetEnumerator(nullptr, getter_AddRefs(windowEnumerator));
     347           0 :   windowEnumerator->HasMoreElements(&more);
     348           0 :   while (more) {
     349           0 :     nsCOMPtr<nsISupports> protoWindow;
     350           0 :     windowEnumerator->GetNext(getter_AddRefs(protoWindow));
     351           0 :     if (protoWindow) {
     352           0 :       nsCOMPtr<nsPIDOMWindowOuter> domWindow = do_QueryInterface(protoWindow);
     353           0 :       if (domWindow)
     354           0 :         RefreshWindow(domWindow);
     355             :     }
     356           0 :     windowEnumerator->HasMoreElements(&more);
     357             :   }
     358             : 
     359           0 :   return NS_OK;
     360             : }
     361             : 
     362             : void
     363           0 : nsChromeRegistry::FlushSkinCaches()
     364             : {
     365             :   nsCOMPtr<nsIObserverService> obsSvc =
     366           0 :     mozilla::services::GetObserverService();
     367           0 :   NS_ASSERTION(obsSvc, "Couldn't get observer service.");
     368             : 
     369           0 :   obsSvc->NotifyObservers(static_cast<nsIChromeRegistry*>(this),
     370           0 :                           NS_CHROME_FLUSH_SKINS_TOPIC, nullptr);
     371           0 : }
     372             : 
     373             : // XXXbsmedberg: move this to windowmediator
     374           0 : nsresult nsChromeRegistry::RefreshWindow(nsPIDOMWindowOuter* aWindow)
     375             : {
     376             :   // Deal with our subframes first.
     377           0 :   nsCOMPtr<nsIDOMWindowCollection> frames = aWindow->GetFrames();
     378             :   uint32_t length;
     379           0 :   frames->GetLength(&length);
     380             :   uint32_t j;
     381           0 :   for (j = 0; j < length; j++) {
     382           0 :     nsCOMPtr<mozIDOMWindowProxy> childWin;
     383           0 :     frames->Item(j, getter_AddRefs(childWin));
     384           0 :     nsCOMPtr<nsPIDOMWindowOuter> piWindow = nsPIDOMWindowOuter::From(childWin);
     385           0 :     RefreshWindow(piWindow);
     386             :   }
     387             : 
     388             :   nsresult rv;
     389             :   // Get the document.
     390           0 :   nsCOMPtr<nsIDocument> document = aWindow->GetDoc();
     391           0 :   if (!document)
     392           0 :     return NS_OK;
     393             : 
     394             :   // Deal with the agent sheets first.  Have to do all the style sets by hand.
     395           0 :   nsCOMPtr<nsIPresShell> shell = document->GetShell();
     396           0 :   if (shell) {
     397             :     // Reload only the chrome URL agent style sheets.
     398           0 :     nsTArray<RefPtr<StyleSheet>> agentSheets;
     399           0 :     rv = shell->GetAgentStyleSheets(agentSheets);
     400           0 :     NS_ENSURE_SUCCESS(rv, rv);
     401             : 
     402           0 :     nsTArray<RefPtr<StyleSheet>> newAgentSheets;
     403           0 :     for (StyleSheet* sheet : agentSheets) {
     404           0 :       nsIURI* uri = sheet->GetSheetURI();
     405             : 
     406           0 :       if (IsChromeURI(uri)) {
     407             :         // Reload the sheet.
     408           0 :         RefPtr<StyleSheet> newSheet;
     409           0 :         rv = document->LoadChromeSheetSync(uri, true, &newSheet);
     410           0 :         if (NS_FAILED(rv)) return rv;
     411           0 :         if (newSheet) {
     412           0 :           rv = newAgentSheets.AppendElement(newSheet) ? NS_OK : NS_ERROR_FAILURE;
     413           0 :           if (NS_FAILED(rv)) return rv;
     414             :         }
     415             :       }
     416             :       else {  // Just use the same sheet.
     417           0 :         rv = newAgentSheets.AppendElement(sheet) ? NS_OK : NS_ERROR_FAILURE;
     418           0 :         if (NS_FAILED(rv)) return rv;
     419             :       }
     420             :     }
     421             : 
     422           0 :     rv = shell->SetAgentStyleSheets(newAgentSheets);
     423           0 :     NS_ENSURE_SUCCESS(rv, rv);
     424             :   }
     425             : 
     426           0 :   int32_t count = document->GetNumberOfStyleSheets();
     427             : 
     428             :   // Build an array of style sheets we need to reload.
     429           0 :   nsTArray<RefPtr<StyleSheet>> oldSheets(count);
     430           0 :   nsTArray<RefPtr<StyleSheet>> newSheets(count);
     431             : 
     432             :   // Iterate over the style sheets.
     433           0 :   for (int32_t i = 0; i < count; i++) {
     434             :     // Get the style sheet
     435           0 :     StyleSheet* styleSheet = document->GetStyleSheetAt(i);
     436           0 :     oldSheets.AppendElement(styleSheet);
     437             :   }
     438             : 
     439             :   // Iterate over our old sheets and kick off a sync load of the new
     440             :   // sheet if and only if it's a non-inline sheet with a chrome URL.
     441           0 :   for (StyleSheet* sheet : oldSheets) {
     442           0 :     MOZ_ASSERT(sheet, "GetStyleSheetAt shouldn't return nullptr for "
     443             :                       "in-range sheet indexes");
     444           0 :     nsIURI* uri = sheet->GetSheetURI();
     445             : 
     446           0 :     if (!sheet->IsInline() && IsChromeURI(uri)) {
     447             :       // Reload the sheet.
     448           0 :       RefPtr<StyleSheet> newSheet;
     449             :       // XXX what about chrome sheets that have a title or are disabled?  This
     450             :       // only works by sheer dumb luck.
     451           0 :       document->LoadChromeSheetSync(uri, false, &newSheet);
     452             :       // Even if it's null, we put in in there.
     453           0 :       newSheets.AppendElement(newSheet);
     454             :     } else {
     455             :       // Just use the same sheet.
     456           0 :       newSheets.AppendElement(sheet);
     457             :     }
     458             :   }
     459             : 
     460             :   // Now notify the document that multiple sheets have been added and removed.
     461           0 :   document->UpdateStyleSheets(oldSheets, newSheets);
     462           0 :   return NS_OK;
     463             : }
     464             : 
     465             : void
     466           0 : nsChromeRegistry::FlushAllCaches()
     467             : {
     468             :   nsCOMPtr<nsIObserverService> obsSvc =
     469           0 :     mozilla::services::GetObserverService();
     470           0 :   NS_ASSERTION(obsSvc, "Couldn't get observer service.");
     471             : 
     472           0 :   obsSvc->NotifyObservers((nsIChromeRegistry*) this,
     473           0 :                           NS_CHROME_FLUSH_TOPIC, nullptr);
     474           0 : }
     475             : 
     476             : // xxxbsmedberg Move me to nsIWindowMediator
     477             : NS_IMETHODIMP
     478           0 : nsChromeRegistry::ReloadChrome()
     479             : {
     480           0 :   FlushAllCaches();
     481             :   // Do a reload of all top level windows.
     482           0 :   nsresult rv = NS_OK;
     483             : 
     484             :   // Get the window mediator
     485             :   nsCOMPtr<nsIWindowMediator> windowMediator
     486           0 :     (do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
     487           0 :   if (windowMediator) {
     488           0 :     nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
     489             : 
     490           0 :     rv = windowMediator->GetEnumerator(nullptr, getter_AddRefs(windowEnumerator));
     491           0 :     if (NS_SUCCEEDED(rv)) {
     492             :       // Get each dom window
     493             :       bool more;
     494           0 :       rv = windowEnumerator->HasMoreElements(&more);
     495           0 :       if (NS_FAILED(rv)) return rv;
     496           0 :       while (more) {
     497           0 :         nsCOMPtr<nsISupports> protoWindow;
     498           0 :         rv = windowEnumerator->GetNext(getter_AddRefs(protoWindow));
     499           0 :         if (NS_SUCCEEDED(rv)) {
     500           0 :           nsCOMPtr<nsPIDOMWindowOuter> domWindow = do_QueryInterface(protoWindow);
     501           0 :           if (domWindow) {
     502           0 :             Location* location = domWindow->GetLocation();
     503           0 :             if (location) {
     504           0 :               rv = location->Reload(false);
     505           0 :               if (NS_FAILED(rv)) return rv;
     506             :             }
     507             :           }
     508             :         }
     509           0 :         rv = windowEnumerator->HasMoreElements(&more);
     510           0 :         if (NS_FAILED(rv)) return rv;
     511             :       }
     512             :     }
     513             :   }
     514           0 :   return rv;
     515             : }
     516             : 
     517             : NS_IMETHODIMP
     518          26 : nsChromeRegistry::AllowScriptsForPackage(nsIURI* aChromeURI, bool *aResult)
     519             : {
     520             :   nsresult rv;
     521          26 :   *aResult = false;
     522             : 
     523             : #ifdef DEBUG
     524             :   bool isChrome;
     525          26 :   aChromeURI->SchemeIs("chrome", &isChrome);
     526          26 :   NS_ASSERTION(isChrome, "Non-chrome URI passed to AllowScriptsForPackage!");
     527             : #endif
     528             : 
     529          52 :   nsCOMPtr<nsIURL> url (do_QueryInterface(aChromeURI));
     530          26 :   NS_ENSURE_TRUE(url, NS_NOINTERFACE);
     531             : 
     532          52 :   nsAutoCString provider, file;
     533          26 :   rv = GetProviderAndPath(url, provider, file);
     534          26 :   NS_ENSURE_SUCCESS(rv, rv);
     535             : 
     536          26 :   if (!provider.EqualsLiteral("skin"))
     537          26 :     *aResult = true;
     538             : 
     539          26 :   return NS_OK;
     540             : }
     541             : 
     542             : NS_IMETHODIMP
     543           2 : nsChromeRegistry::AllowContentToAccess(nsIURI *aURI, bool *aResult)
     544             : {
     545             :   nsresult rv;
     546             : 
     547           2 :   *aResult = false;
     548             : 
     549             : #ifdef DEBUG
     550             :   bool isChrome;
     551           2 :   aURI->SchemeIs("chrome", &isChrome);
     552           2 :   NS_ASSERTION(isChrome, "Non-chrome URI passed to AllowContentToAccess!");
     553             : #endif
     554             : 
     555           4 :   nsCOMPtr<nsIURL> url = do_QueryInterface(aURI);
     556           2 :   if (!url) {
     557           0 :     NS_ERROR("Chrome URL doesn't implement nsIURL.");
     558           0 :     return NS_ERROR_UNEXPECTED;
     559             :   }
     560             : 
     561           4 :   nsAutoCString package;
     562           2 :   rv = url->GetHostPort(package);
     563           2 :   NS_ENSURE_SUCCESS(rv, rv);
     564             : 
     565             :   uint32_t flags;
     566           2 :   rv = GetFlagsFromPackage(package, &flags);
     567             : 
     568           2 :   if (NS_SUCCEEDED(rv)) {
     569           2 :     *aResult = !!(flags & CONTENT_ACCESSIBLE);
     570             :   }
     571           2 :   return NS_OK;
     572             : }
     573             : 
     574             : NS_IMETHODIMP
     575           0 : nsChromeRegistry::CanLoadURLRemotely(nsIURI *aURI, bool *aResult)
     576             : {
     577             :   nsresult rv;
     578             : 
     579           0 :   *aResult = false;
     580             : 
     581             : #ifdef DEBUG
     582             :   bool isChrome;
     583           0 :   aURI->SchemeIs("chrome", &isChrome);
     584           0 :   NS_ASSERTION(isChrome, "Non-chrome URI passed to CanLoadURLRemotely!");
     585             : #endif
     586             : 
     587           0 :   nsCOMPtr<nsIURL> url = do_QueryInterface(aURI);
     588           0 :   if (!url) {
     589           0 :     NS_ERROR("Chrome URL doesn't implement nsIURL.");
     590           0 :     return NS_ERROR_UNEXPECTED;
     591             :   }
     592             : 
     593           0 :   nsAutoCString package;
     594           0 :   rv = url->GetHostPort(package);
     595           0 :   NS_ENSURE_SUCCESS(rv, rv);
     596             : 
     597             :   uint32_t flags;
     598           0 :   rv = GetFlagsFromPackage(package, &flags);
     599             : 
     600           0 :   if (NS_SUCCEEDED(rv)) {
     601           0 :     *aResult = !!(flags & REMOTE_ALLOWED);
     602             :   }
     603           0 :   return NS_OK;
     604             : }
     605             : 
     606             : NS_IMETHODIMP
     607           0 : nsChromeRegistry::MustLoadURLRemotely(nsIURI *aURI, bool *aResult)
     608             : {
     609             :   nsresult rv;
     610             : 
     611           0 :   *aResult = false;
     612             : 
     613             : #ifdef DEBUG
     614             :   bool isChrome;
     615           0 :   aURI->SchemeIs("chrome", &isChrome);
     616           0 :   NS_ASSERTION(isChrome, "Non-chrome URI passed to MustLoadURLRemotely!");
     617             : #endif
     618             : 
     619           0 :   nsCOMPtr<nsIURL> url = do_QueryInterface(aURI);
     620           0 :   if (!url) {
     621           0 :     NS_ERROR("Chrome URL doesn't implement nsIURL.");
     622           0 :     return NS_ERROR_UNEXPECTED;
     623             :   }
     624             : 
     625           0 :   nsAutoCString package;
     626           0 :   rv = url->GetHostPort(package);
     627           0 :   NS_ENSURE_SUCCESS(rv, rv);
     628             : 
     629             :   uint32_t flags;
     630           0 :   rv = GetFlagsFromPackage(package, &flags);
     631             : 
     632           0 :   if (NS_SUCCEEDED(rv)) {
     633           0 :     *aResult = !!(flags & REMOTE_REQUIRED);
     634             :   }
     635           0 :   return NS_OK;
     636             : }
     637             : 
     638             : bool
     639           1 : nsChromeRegistry::GetDirectionForLocale(const nsACString& aLocale)
     640             : {
     641             : #ifdef ENABLE_INTL_API
     642           1 :   int pref = mozilla::Preferences::GetInt("intl.uidirection", -1);
     643           1 :   if (pref >= 0) {
     644           0 :     return (pref > 0);
     645             :   }
     646           2 :   nsAutoCString locale(aLocale);
     647           1 :   SanitizeForBCP47(locale);
     648           1 :   return uloc_isRightToLeft(locale.get());
     649             : #else
     650             :   // first check the intl.uidirection.<locale> preference, and if that is not
     651             :   // set, check the same preference but with just the first two characters of
     652             :   // the locale. If that isn't set, default to left-to-right.
     653             :   nsAutoCString prefString = NS_LITERAL_CSTRING("intl.uidirection.") + aLocale;
     654             :   nsCOMPtr<nsIPrefBranch> prefBranch (do_GetService(NS_PREFSERVICE_CONTRACTID));
     655             :   if (!prefBranch) {
     656             :     return false;
     657             :   }
     658             : 
     659             :   nsXPIDLCString dir;
     660             :   prefBranch->GetCharPref(prefString.get(), getter_Copies(dir));
     661             :   if (dir.IsEmpty()) {
     662             :     int32_t hyphen = prefString.FindChar('-');
     663             :     if (hyphen >= 1) {
     664             :       nsAutoCString shortPref(Substring(prefString, 0, hyphen));
     665             :       prefBranch->GetCharPref(shortPref.get(), getter_Copies(dir));
     666             :     }
     667             :   }
     668             : 
     669             :   return dir.EqualsLiteral("rtl");
     670             : #endif
     671             : }
     672             : 
     673             : NS_IMETHODIMP_(bool)
     674         714 : nsChromeRegistry::WrappersEnabled(nsIURI *aURI)
     675             : {
     676        1428 :   nsCOMPtr<nsIURL> chromeURL (do_QueryInterface(aURI));
     677         714 :   if (!chromeURL)
     678           0 :     return false;
     679             : 
     680         714 :   bool isChrome = false;
     681         714 :   nsresult rv = chromeURL->SchemeIs("chrome", &isChrome);
     682         714 :   if (NS_FAILED(rv) || !isChrome)
     683           0 :     return false;
     684             : 
     685        1428 :   nsAutoCString package;
     686         714 :   rv = chromeURL->GetHostPort(package);
     687         714 :   if (NS_FAILED(rv))
     688           0 :     return false;
     689             : 
     690             :   uint32_t flags;
     691         714 :   rv = GetFlagsFromPackage(package, &flags);
     692         714 :   return NS_SUCCEEDED(rv) && (flags & XPCNATIVEWRAPPERS);
     693             : }
     694             : 
     695             : already_AddRefed<nsChromeRegistry>
     696           3 : nsChromeRegistry::GetSingleton()
     697             : {
     698           3 :   if (gChromeRegistry) {
     699           0 :     RefPtr<nsChromeRegistry> registry = gChromeRegistry;
     700           0 :     return registry.forget();
     701             :   }
     702             : 
     703           6 :   RefPtr<nsChromeRegistry> cr;
     704           3 :   if (GeckoProcessType_Content == XRE_GetProcessType())
     705           2 :     cr = new nsChromeRegistryContent();
     706             :   else
     707           1 :     cr = new nsChromeRegistryChrome();
     708             : 
     709           3 :   if (NS_FAILED(cr->Init()))
     710           0 :     return nullptr;
     711             : 
     712           3 :   return cr.forget();
     713             : }
     714             : 
     715             : void
     716           1 : nsChromeRegistry::SanitizeForBCP47(nsACString& aLocale)
     717             : {
     718             : #ifdef ENABLE_INTL_API
     719             :   // Currently, the only locale code we use that's not BCP47-conformant is
     720             :   // "ja-JP-mac" on OS X, but let's try to be more general than just
     721             :   // hard-coding that here.
     722           1 :   const int32_t LANG_TAG_CAPACITY = 128;
     723             :   char langTag[LANG_TAG_CAPACITY];
     724           2 :   nsAutoCString locale(aLocale);
     725           1 :   UErrorCode err = U_ZERO_ERROR;
     726             :   // This is a fail-safe method that will set langTag to "und" if it cannot
     727             :   // match any part of the input locale code.
     728           1 :   int32_t len = uloc_toLanguageTag(locale.get(), langTag, LANG_TAG_CAPACITY,
     729           1 :                                    false, &err);
     730           1 :   if (U_SUCCESS(err) && len > 0) {
     731           1 :     aLocale.Assign(langTag, len);
     732             :   }
     733             : #else
     734             :   // This is only really needed for Intl API purposes, AFAIK,
     735             :   // so probably won't be used in a non-ENABLE_INTL_API build.
     736             :   // But let's fix up the single anomalous code we actually ship,
     737             :   // just in case:
     738             :   if (aLocale.EqualsLiteral("ja-JP-mac")) {
     739             :     aLocale.AssignLiteral("ja-JP");
     740             :   }
     741             : #endif
     742           1 : }

Generated by: LCOV version 1.13