LCOV - code coverage report
Current view: top level - browser/components/about - AboutRedirector.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 29 72 40.3 %
Date: 2017-07-14 16:53:18 Functions: 6 7 85.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : // See also: docshell/base/nsAboutRedirector.cpp
       7             : 
       8             : #include "AboutRedirector.h"
       9             : #include "nsNetUtil.h"
      10             : #include "nsIAboutNewTabService.h"
      11             : #include "nsIChannel.h"
      12             : #include "nsIURI.h"
      13             : #include "nsIScriptSecurityManager.h"
      14             : #include "nsIProtocolHandler.h"
      15             : #include "mozilla/ArrayUtils.h"
      16             : #include "mozilla/Preferences.h"
      17             : #include "nsServiceManagerUtils.h"
      18             : 
      19             : namespace mozilla {
      20             : namespace browser {
      21             : 
      22         309 : NS_IMPL_ISUPPORTS(AboutRedirector, nsIAboutModule)
      23             : 
      24             : bool AboutRedirector::sUseOldPreferences = false;
      25             : bool AboutRedirector::sActivityStreamEnabled = false;
      26             : 
      27             : struct RedirEntry {
      28             :   const char* id;
      29             :   const char* url;
      30             :   uint32_t flags;
      31             : };
      32             : 
      33             : /*
      34             :   Entries which do not have URI_SAFE_FOR_UNTRUSTED_CONTENT will run with chrome
      35             :   privileges. This is potentially dangerous. Please use
      36             :   URI_SAFE_FOR_UNTRUSTED_CONTENT in the third argument to each map item below
      37             :   unless your about: page really needs chrome privileges. Security review is
      38             :   required before adding new map entries without
      39             :   URI_SAFE_FOR_UNTRUSTED_CONTENT.
      40             : */
      41             : static const RedirEntry kRedirMap[] = {
      42             :   { "blocked", "chrome://browser/content/blockedSite.xhtml",
      43             :     nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
      44             :     nsIAboutModule::URI_CAN_LOAD_IN_CHILD |
      45             :     nsIAboutModule::ALLOW_SCRIPT |
      46             :     nsIAboutModule::HIDE_FROM_ABOUTABOUT },
      47             :   { "certerror", "chrome://browser/content/aboutNetError.xhtml",
      48             :     nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
      49             :     nsIAboutModule::URI_CAN_LOAD_IN_CHILD |
      50             :     nsIAboutModule::ALLOW_SCRIPT |
      51             :     nsIAboutModule::HIDE_FROM_ABOUTABOUT },
      52             :   { "socialerror", "chrome://browser/content/aboutSocialError.xhtml",
      53             :     nsIAboutModule::ALLOW_SCRIPT |
      54             :     nsIAboutModule::HIDE_FROM_ABOUTABOUT },
      55             :   { "providerdirectory", "chrome://browser/content/aboutProviderDirectory.xhtml",
      56             :     nsIAboutModule::ALLOW_SCRIPT |
      57             :     nsIAboutModule::HIDE_FROM_ABOUTABOUT },
      58             :   { "tabcrashed", "chrome://browser/content/aboutTabCrashed.xhtml",
      59             :     nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
      60             :     nsIAboutModule::ALLOW_SCRIPT |
      61             :     nsIAboutModule::HIDE_FROM_ABOUTABOUT },
      62             :   { "feeds", "chrome://browser/content/feeds/subscribe.xhtml",
      63             :     nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
      64             :     nsIAboutModule::ALLOW_SCRIPT |
      65             :     nsIAboutModule::HIDE_FROM_ABOUTABOUT },
      66             :   { "privatebrowsing", "chrome://browser/content/aboutPrivateBrowsing.xhtml",
      67             :     nsIAboutModule::URI_MUST_LOAD_IN_CHILD |
      68             :     nsIAboutModule::ALLOW_SCRIPT },
      69             :   { "rights",
      70             :     "chrome://global/content/aboutRights.xhtml",
      71             :     nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
      72             :     nsIAboutModule::MAKE_LINKABLE |
      73             :     nsIAboutModule::ALLOW_SCRIPT },
      74             :   { "robots", "chrome://browser/content/aboutRobots.xhtml",
      75             :     nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
      76             :     nsIAboutModule::ALLOW_SCRIPT },
      77             :   { "searchreset", "chrome://browser/content/search/searchReset.xhtml",
      78             :     nsIAboutModule::ALLOW_SCRIPT |
      79             :     nsIAboutModule::HIDE_FROM_ABOUTABOUT },
      80             :   { "sessionrestore", "chrome://browser/content/aboutSessionRestore.xhtml",
      81             :     nsIAboutModule::ALLOW_SCRIPT },
      82             :   { "welcomeback", "chrome://browser/content/aboutWelcomeBack.xhtml",
      83             :     nsIAboutModule::ALLOW_SCRIPT },
      84             :   // Linkable because of indexeddb use (bug 1228118)
      85             :   { "home", "chrome://browser/content/abouthome/aboutHome.xhtml",
      86             :     nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
      87             :     nsIAboutModule::URI_MUST_LOAD_IN_CHILD |
      88             :     nsIAboutModule::ALLOW_SCRIPT |
      89             :     nsIAboutModule::MAKE_LINKABLE |
      90             :     nsIAboutModule::ENABLE_INDEXED_DB },
      91             :   // the newtab's actual URL will be determined when the channel is created
      92             :   { "newtab", "about:blank",
      93             :     nsIAboutModule::ALLOW_SCRIPT },
      94             :   { "preferences", "chrome://browser/content/preferences/in-content/preferences.xul",
      95             :     nsIAboutModule::ALLOW_SCRIPT },
      96             :   { "downloads", "chrome://browser/content/downloads/contentAreaDownloadsView.xul",
      97             :     nsIAboutModule::ALLOW_SCRIPT },
      98             : #ifdef MOZ_SERVICES_HEALTHREPORT
      99             :   { "healthreport", "chrome://browser/content/abouthealthreport/abouthealth.xhtml",
     100             :     nsIAboutModule::ALLOW_SCRIPT },
     101             : #endif
     102             :   { "accounts", "chrome://browser/content/aboutaccounts/aboutaccounts.xhtml",
     103             :     nsIAboutModule::ALLOW_SCRIPT },
     104             :   { "reader", "chrome://global/content/reader/aboutReader.html",
     105             :     nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
     106             :     nsIAboutModule::ALLOW_SCRIPT |
     107             :     nsIAboutModule::URI_MUST_LOAD_IN_CHILD |
     108             :     nsIAboutModule::HIDE_FROM_ABOUTABOUT },
     109             : };
     110             : 
     111             : static nsAutoCString
     112          31 : GetAboutModuleName(nsIURI *aURI)
     113             : {
     114          31 :   nsAutoCString path;
     115          31 :   aURI->GetPath(path);
     116             : 
     117          31 :   int32_t f = path.FindChar('#');
     118          31 :   if (f >= 0)
     119           0 :     path.SetLength(f);
     120             : 
     121          31 :   f = path.FindChar('?');
     122          31 :   if (f >= 0)
     123           0 :     path.SetLength(f);
     124             : 
     125          31 :   ToLowerCase(path);
     126          31 :   return path;
     127             : }
     128             : 
     129             : NS_IMETHODIMP
     130           0 : AboutRedirector::NewChannel(nsIURI* aURI,
     131             :                             nsILoadInfo* aLoadInfo,
     132             :                             nsIChannel** result)
     133             : {
     134           0 :   NS_ENSURE_ARG_POINTER(aURI);
     135           0 :   NS_ENSURE_ARG_POINTER(aLoadInfo);
     136             : 
     137           0 :   NS_ASSERTION(result, "must not be null");
     138             : 
     139           0 :   nsAutoCString path = GetAboutModuleName(aURI);
     140             : 
     141             :   nsresult rv;
     142           0 :   nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
     143           0 :   NS_ENSURE_SUCCESS(rv, rv);
     144             : 
     145             :   static bool sPrefCacheInited = false;
     146           0 :   if (!sPrefCacheInited) {
     147             :     Preferences::AddBoolVarCache(&sUseOldPreferences,
     148           0 :                                  "browser.preferences.useOldOrganization");
     149           0 :     sPrefCacheInited = true;
     150             :   }
     151             : 
     152           0 :   for (auto & redir : kRedirMap) {
     153           0 :     if (!strcmp(path.get(), redir.id)) {
     154           0 :       nsAutoCString url;
     155             : 
     156           0 :       if (path.EqualsLiteral("newtab")) {
     157             :         // let the aboutNewTabService decide where to redirect
     158             :         nsCOMPtr<nsIAboutNewTabService> aboutNewTabService =
     159           0 :           do_GetService("@mozilla.org/browser/aboutnewtab-service;1", &rv);
     160           0 :         NS_ENSURE_SUCCESS(rv, rv);
     161           0 :         rv = aboutNewTabService->GetDefaultURL(url);
     162           0 :         NS_ENSURE_SUCCESS(rv, rv);
     163           0 :       } else if (path.EqualsLiteral("preferences") && !sUseOldPreferences) {
     164           0 :         url.AssignASCII("chrome://browser/content/preferences/in-content-new/preferences.xul");
     165             :       }
     166             :       // fall back to the specified url in the map
     167           0 :       if (url.IsEmpty()) {
     168           0 :         url.AssignASCII(redir.url);
     169             :       }
     170             : 
     171           0 :       nsCOMPtr<nsIChannel> tempChannel;
     172           0 :       nsCOMPtr<nsIURI> tempURI;
     173           0 :       rv = NS_NewURI(getter_AddRefs(tempURI), url);
     174           0 :       NS_ENSURE_SUCCESS(rv, rv);
     175             : 
     176             :       // If tempURI links to an external URI (i.e. something other than
     177             :       // chrome:// or resource://) then set the result principal URI on the
     178             :       // load info which forces the channel prncipal to reflect the displayed
     179             :       // URL rather then being the systemPrincipal.
     180           0 :       bool isUIResource = false;
     181           0 :       rv = NS_URIChainHasFlags(tempURI, nsIProtocolHandler::URI_IS_UI_RESOURCE,
     182             :                                &isUIResource);
     183           0 :       NS_ENSURE_SUCCESS(rv, rv);
     184             : 
     185           0 :       rv = NS_NewChannelInternal(getter_AddRefs(tempChannel),
     186             :                                  tempURI,
     187             :                                  aLoadInfo);
     188           0 :       NS_ENSURE_SUCCESS(rv, rv);
     189             : 
     190           0 :       if (!isUIResource) {
     191           0 :         aLoadInfo->SetResultPrincipalURI(tempURI);
     192             :       }
     193           0 :       tempChannel->SetOriginalURI(aURI);
     194             : 
     195           0 :       NS_ADDREF(*result = tempChannel);
     196           0 :       return rv;
     197             :     }
     198             :   }
     199             : 
     200           0 :   return NS_ERROR_ILLEGAL_VALUE;
     201             : }
     202             : 
     203             : NS_IMETHODIMP
     204          31 : AboutRedirector::GetURIFlags(nsIURI *aURI, uint32_t *result)
     205             : {
     206          31 :   NS_ENSURE_ARG_POINTER(aURI);
     207             : 
     208          62 :   nsAutoCString name = GetAboutModuleName(aURI);
     209             : 
     210             :   static bool sASEnabledCacheInited = false;
     211          31 :   if (!sASEnabledCacheInited) {
     212             :     Preferences::AddBoolVarCache(&sActivityStreamEnabled,
     213           3 :                                  "browser.newtabpage.activity-stream.enabled");
     214           3 :     sASEnabledCacheInited = true;
     215             :   }
     216             : 
     217         431 :   for (auto & redir : kRedirMap) {
     218         431 :     if (name.Equals(redir.id)) {
     219             : 
     220             :       // Once ActivityStream is fully rolled out and we've removed Tiles,
     221             :       // this special case can go away and the flag can just become part
     222             :       // of the normal about:newtab entry in kRedirMap.
     223          31 :       if (name.EqualsLiteral("newtab")) {
     224          28 :         if (sActivityStreamEnabled) {
     225           0 :           *result = redir.flags | nsIAboutModule::URI_MUST_LOAD_IN_CHILD;
     226           0 :           return NS_OK;
     227             :         }
     228             :       }
     229             : 
     230          31 :       *result = redir.flags;
     231          31 :       return NS_OK;
     232             :     }
     233             :   }
     234             : 
     235           0 :   return NS_ERROR_ILLEGAL_VALUE;
     236             : }
     237             : 
     238             : nsresult
     239           3 : AboutRedirector::Create(nsISupports *aOuter, REFNSIID aIID, void **result)
     240             : {
     241           3 :   AboutRedirector* about = new AboutRedirector();
     242           3 :   if (about == nullptr)
     243           0 :     return NS_ERROR_OUT_OF_MEMORY;
     244           3 :   NS_ADDREF(about);
     245           3 :   nsresult rv = about->QueryInterface(aIID, result);
     246           3 :   NS_RELEASE(about);
     247           3 :   return rv;
     248             : }
     249             : 
     250             : } // namespace browser
     251             : } // namespace mozilla

Generated by: LCOV version 1.13