LCOV - code coverage report
Current view: top level - dom/base - nsNameSpaceManager.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 89 133 66.9 %
Date: 2017-07-14 16:53:18 Functions: 12 14 85.7 %
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=8 sts=2 et sw=2 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             : /*
       8             :  * A class for managing namespace IDs and mapping back and forth
       9             :  * between namespace IDs and namespace URIs.
      10             :  */
      11             : 
      12             : #include "nsNameSpaceManager.h"
      13             : 
      14             : #include "nscore.h"
      15             : #include "mozilla/dom/NodeInfo.h"
      16             : #include "nsCOMArray.h"
      17             : #include "nsContentCreatorFunctions.h"
      18             : #include "nsContentUtils.h"
      19             : #include "nsGkAtoms.h"
      20             : #include "nsIDocument.h"
      21             : #include "nsString.h"
      22             : #include "mozilla/dom/NodeInfo.h"
      23             : #include "mozilla/ClearOnShutdown.h"
      24             : #include "mozilla/dom/XBLChildrenElement.h"
      25             : #include "mozilla/dom/Element.h"
      26             : #include "mozilla/Preferences.h"
      27             : 
      28             : using namespace mozilla;
      29             : using namespace mozilla::dom;
      30             : 
      31             : static const char* kPrefSVGDisabled = "svg.disabled";
      32             : static const char* kPrefMathMLDisabled = "mathml.disabled";
      33             : static const char* kObservedPrefs[] = {
      34             :   kPrefMathMLDisabled,
      35             :   kPrefSVGDisabled,
      36             :   nullptr
      37           3 : };
      38           3 : StaticRefPtr<nsNameSpaceManager> nsNameSpaceManager::sInstance;
      39             : 
      40             : /* static */ nsNameSpaceManager*
      41         136 : nsNameSpaceManager::GetInstance() {
      42         136 :   if (!sInstance) {
      43           3 :     sInstance = new nsNameSpaceManager();
      44           3 :     if (sInstance->Init()) {
      45           3 :       ClearOnShutdown(&sInstance);
      46             :     } else {
      47           0 :       delete sInstance;
      48           0 :       sInstance = nullptr;
      49             :     }
      50             :   }
      51             : 
      52         136 :   return sInstance;
      53             : }
      54             : 
      55           3 : bool nsNameSpaceManager::Init()
      56             : {
      57             :   nsresult rv;
      58             : #define REGISTER_NAMESPACE(uri, id) \
      59             :   rv = AddNameSpace(dont_AddRef(uri), id); \
      60             :   NS_ENSURE_SUCCESS(rv, false)
      61             : 
      62             : #define REGISTER_DISABLED_NAMESPACE(uri, id) \
      63             :   rv = AddDisabledNameSpace(dont_AddRef(uri), id); \
      64             :   NS_ENSURE_SUCCESS(rv, false)
      65             : 
      66           3 :   mozilla::Preferences::AddStrongObservers(this, kObservedPrefs);
      67           3 :   mMathMLDisabled = mozilla::Preferences::GetBool(kPrefMathMLDisabled);
      68           3 :   mSVGDisabled = mozilla::Preferences::GetBool(kPrefSVGDisabled);
      69             : 
      70             : 
      71             :   // Need to be ordered according to ID.
      72           3 :   MOZ_ASSERT(mURIArray.IsEmpty());
      73           3 :   REGISTER_NAMESPACE(nsGkAtoms::empty, kNameSpaceID_None);
      74           3 :   REGISTER_NAMESPACE(nsGkAtoms::nsuri_xmlns, kNameSpaceID_XMLNS);
      75           3 :   REGISTER_NAMESPACE(nsGkAtoms::nsuri_xml, kNameSpaceID_XML);
      76           3 :   REGISTER_NAMESPACE(nsGkAtoms::nsuri_xhtml, kNameSpaceID_XHTML);
      77           3 :   REGISTER_NAMESPACE(nsGkAtoms::nsuri_xlink, kNameSpaceID_XLink);
      78           3 :   REGISTER_NAMESPACE(nsGkAtoms::nsuri_xslt, kNameSpaceID_XSLT);
      79           3 :   REGISTER_NAMESPACE(nsGkAtoms::nsuri_xbl, kNameSpaceID_XBL);
      80           3 :   REGISTER_NAMESPACE(nsGkAtoms::nsuri_mathml, kNameSpaceID_MathML);
      81           3 :   REGISTER_NAMESPACE(nsGkAtoms::nsuri_rdf, kNameSpaceID_RDF);
      82           3 :   REGISTER_NAMESPACE(nsGkAtoms::nsuri_xul, kNameSpaceID_XUL);
      83           3 :   REGISTER_NAMESPACE(nsGkAtoms::nsuri_svg, kNameSpaceID_SVG);
      84           3 :   REGISTER_DISABLED_NAMESPACE(nsGkAtoms::nsuri_mathml, kNameSpaceID_disabled_MathML);
      85           3 :   REGISTER_DISABLED_NAMESPACE(nsGkAtoms::nsuri_svg, kNameSpaceID_disabled_SVG);
      86             : 
      87             : #undef REGISTER_NAMESPACE
      88             : #undef REGISTER_DISABLED_NAMESPACE
      89             : 
      90           3 :   return true;
      91             : }
      92             : 
      93             : nsresult
      94         625 : nsNameSpaceManager::RegisterNameSpace(const nsAString& aURI,
      95             :                                       int32_t& aNameSpaceID)
      96             : {
      97         625 :   if (aURI.IsEmpty()) {
      98           0 :     aNameSpaceID = kNameSpaceID_None; // xmlns="", see bug 75700 for details
      99             : 
     100           0 :     return NS_OK;
     101             :   }
     102             : 
     103        1250 :   nsCOMPtr<nsIAtom> atom = NS_Atomize(aURI);
     104         625 :   nsresult rv = NS_OK;
     105         625 :   if (!mURIToIDTable.Get(atom, &aNameSpaceID)) {
     106          17 :     aNameSpaceID = mURIArray.Length();
     107             : 
     108          17 :     rv = AddNameSpace(atom.forget(), aNameSpaceID);
     109          17 :     if (NS_FAILED(rv)) {
     110           0 :       aNameSpaceID = kNameSpaceID_Unknown;
     111             :     }
     112             :   }
     113             : 
     114         625 :   NS_POSTCONDITION(aNameSpaceID >= -1, "Bogus namespace ID");
     115             : 
     116         625 :   return rv;
     117             : }
     118             : 
     119             : nsresult
     120           1 : nsNameSpaceManager::GetNameSpaceURI(int32_t aNameSpaceID, nsAString& aURI)
     121             : {
     122           1 :   NS_PRECONDITION(aNameSpaceID >= 0, "Bogus namespace ID");
     123             : 
     124             :   // We have historically treated GetNameSpaceURI calls for kNameSpaceID_None
     125             :   // as erroneous.
     126           1 :   if (aNameSpaceID <= 0 || aNameSpaceID >= int32_t(mURIArray.Length())) {
     127           0 :     aURI.Truncate();
     128             : 
     129           0 :     return NS_ERROR_ILLEGAL_VALUE;
     130             :   }
     131             : 
     132           1 :   mURIArray.ElementAt(aNameSpaceID)->ToString(aURI);
     133             : 
     134           1 :   return NS_OK;
     135             : }
     136             : 
     137             : int32_t
     138           1 : nsNameSpaceManager::GetNameSpaceID(const nsAString& aURI,
     139             :                                    bool aInChromeDoc)
     140             : {
     141           1 :   if (aURI.IsEmpty()) {
     142           0 :     return kNameSpaceID_None; // xmlns="", see bug 75700 for details
     143             :   }
     144             : 
     145           2 :   nsCOMPtr<nsIAtom> atom = NS_Atomize(aURI);
     146           1 :   return GetNameSpaceID(atom, aInChromeDoc);
     147             : }
     148             : 
     149             : int32_t
     150           1 : nsNameSpaceManager::GetNameSpaceID(nsIAtom* aURI,
     151             :                                    bool aInChromeDoc)
     152             : {
     153           1 :   if (aURI == nsGkAtoms::_empty) {
     154           0 :     return kNameSpaceID_None; // xmlns="", see bug 75700 for details
     155             :   }
     156             : 
     157             :   int32_t nameSpaceID;
     158           2 :   if (!aInChromeDoc
     159           0 :       && (mMathMLDisabled || mSVGDisabled)
     160           0 :       && mDisabledURIToIDTable.Get(aURI, &nameSpaceID)
     161           1 :       && ((mMathMLDisabled && kNameSpaceID_disabled_MathML == nameSpaceID) ||
     162           0 :       (mSVGDisabled && kNameSpaceID_disabled_SVG == nameSpaceID))) {
     163           0 :     NS_POSTCONDITION(nameSpaceID >= 0, "Bogus namespace ID");
     164           0 :     return nameSpaceID;
     165             :   }
     166           1 :   if (mURIToIDTable.Get(aURI, &nameSpaceID)) {
     167           1 :     NS_POSTCONDITION(nameSpaceID >= 0, "Bogus namespace ID");
     168           1 :     return nameSpaceID;
     169             :   }
     170             : 
     171           0 :   return kNameSpaceID_Unknown;
     172             : }
     173             : 
     174             : nsresult
     175         558 : NS_NewElement(Element** aResult,
     176             :               already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
     177             :               FromParser aFromParser,
     178             :               const nsAString* aIs)
     179             : {
     180        1116 :   RefPtr<mozilla::dom::NodeInfo> ni = aNodeInfo;
     181         558 :   int32_t ns = ni->NamespaceID();
     182         558 :   if (ns == kNameSpaceID_XHTML) {
     183          47 :     return NS_NewHTMLElement(aResult, ni.forget(), aFromParser, aIs);
     184             :   }
     185             : #ifdef MOZ_XUL
     186         511 :   if (ns == kNameSpaceID_XUL) {
     187          56 :     return NS_NewXULElement(aResult, ni.forget());
     188             :   }
     189             : #endif
     190         455 :   if (ns == kNameSpaceID_MathML) {
     191             :     // If the mathml.disabled pref. is true, convert all MathML nodes into
     192             :     // disabled MathML nodes by swapping the namespace.
     193           0 :     nsNameSpaceManager* nsmgr = nsNameSpaceManager::GetInstance();
     194           0 :     if ((nsmgr && !nsmgr->mMathMLDisabled) ||
     195           0 :         nsContentUtils::IsSystemPrincipal(ni->GetDocument()->NodePrincipal())) {
     196           0 :       return NS_NewMathMLElement(aResult, ni.forget());
     197             :     }
     198             : 
     199             :     RefPtr<mozilla::dom::NodeInfo> genericXMLNI =
     200             :       ni->NodeInfoManager()->
     201           0 :       GetNodeInfo(ni->NameAtom(), ni->GetPrefixAtom(),
     202           0 :         kNameSpaceID_disabled_MathML, ni->NodeType(), ni->GetExtraName());
     203           0 :     return NS_NewXMLElement(aResult, genericXMLNI.forget());
     204             :   }
     205         455 :   if (ns == kNameSpaceID_SVG) {
     206             :     // If the svg.disabled pref. is true, convert all SVG nodes into
     207             :     // disabled SVG nodes by swapping the namespace.
     208         133 :     nsNameSpaceManager* nsmgr = nsNameSpaceManager::GetInstance();
     209         266 :     nsCOMPtr<nsILoadInfo> loadInfo;
     210         133 :     bool SVGEnabled = false;
     211             : 
     212         133 :     if (nsmgr && !nsmgr->mSVGDisabled) {
     213         133 :       SVGEnabled = true;
     214             :     } else {
     215           0 :       nsCOMPtr<nsIChannel> channel = ni->GetDocument()->GetChannel();
     216             :       // We don't have a channel for SVGs constructed inside a SVG script
     217           0 :       if (channel) {
     218           0 :         loadInfo  = channel->GetLoadInfo();
     219             :       }
     220             :     }
     221         133 :     if (SVGEnabled ||
     222         266 :         nsContentUtils::IsSystemPrincipal(ni->GetDocument()->NodePrincipal()) ||
     223           0 :         (loadInfo &&
     224           0 :          (loadInfo->GetExternalContentPolicyType() == nsIContentPolicy::TYPE_IMAGE ||
     225           0 :          loadInfo->GetExternalContentPolicyType() == nsIContentPolicy::TYPE_OTHER) &&
     226           0 :          (nsContentUtils::IsSystemPrincipal(loadInfo->LoadingPrincipal()) ||
     227           0 :           nsContentUtils::IsSystemPrincipal(loadInfo->TriggeringPrincipal())
     228             :          )
     229             :         )
     230             :        ) {
     231         133 :       return NS_NewSVGElement(aResult, ni.forget(), aFromParser);
     232             :     }
     233             :     RefPtr<mozilla::dom::NodeInfo> genericXMLNI =
     234             :       ni->NodeInfoManager()->
     235           0 :       GetNodeInfo(ni->NameAtom(), ni->GetPrefixAtom(),
     236           0 :         kNameSpaceID_disabled_SVG, ni->NodeType(), ni->GetExtraName());
     237           0 :     return NS_NewXMLElement(aResult, genericXMLNI.forget());
     238             :   }
     239         322 :   if (ns == kNameSpaceID_XBL && ni->Equals(nsGkAtoms::children)) {
     240         142 :     NS_ADDREF(*aResult = new XBLChildrenElement(ni.forget()));
     241          71 :     return NS_OK;
     242             :   }
     243             : 
     244         251 :   return NS_NewXMLElement(aResult, ni.forget());
     245             : }
     246             : 
     247             : bool
     248           0 : nsNameSpaceManager::HasElementCreator(int32_t aNameSpaceID)
     249             : {
     250           0 :   return aNameSpaceID == kNameSpaceID_XHTML ||
     251             : #ifdef MOZ_XUL
     252           0 :          aNameSpaceID == kNameSpaceID_XUL ||
     253             : #endif
     254           0 :          aNameSpaceID == kNameSpaceID_MathML ||
     255             :          aNameSpaceID == kNameSpaceID_SVG ||
     256           0 :          false;
     257             : }
     258             : 
     259          50 : nsresult nsNameSpaceManager::AddNameSpace(already_AddRefed<nsIAtom> aURI,
     260             :                                           const int32_t aNameSpaceID)
     261             : {
     262         100 :   nsCOMPtr<nsIAtom> uri = aURI;
     263          50 :   if (aNameSpaceID < 0) {
     264             :     // We've wrapped...  Can't do anything else here; just bail.
     265           0 :     return NS_ERROR_OUT_OF_MEMORY;
     266             :   }
     267             : 
     268          50 :   MOZ_ASSERT(aNameSpaceID == (int32_t) mURIArray.Length());
     269          50 :   mURIArray.AppendElement(uri.forget());
     270          50 :   mURIToIDTable.Put(mURIArray.LastElement(), aNameSpaceID);
     271             : 
     272          50 :   return NS_OK;
     273             : }
     274             : 
     275             : nsresult
     276           6 : nsNameSpaceManager::AddDisabledNameSpace(already_AddRefed<nsIAtom> aURI,
     277             :                                          const int32_t aNameSpaceID)
     278             : {
     279          12 :   nsCOMPtr<nsIAtom> uri = aURI;
     280           6 :   if (aNameSpaceID < 0) {
     281             :     // We've wrapped...  Can't do anything else here; just bail.
     282           0 :     return NS_ERROR_OUT_OF_MEMORY;
     283             :   }
     284             : 
     285           6 :   MOZ_ASSERT(aNameSpaceID == (int32_t) mURIArray.Length());
     286           6 :   mURIArray.AppendElement(uri.forget());
     287           6 :   mDisabledURIToIDTable.Put(mURIArray.LastElement(), aNameSpaceID);
     288             : 
     289           6 :   return NS_OK;
     290             : }
     291             : 
     292             : // nsISupports
     293          51 : NS_IMPL_ISUPPORTS(nsNameSpaceManager,
     294             :                   nsIObserver)
     295             : 
     296             : // nsIObserver
     297             : NS_IMETHODIMP
     298           0 : nsNameSpaceManager::Observe(nsISupports* aObject, const char* aTopic,
     299             :                             const char16_t* aMessage)
     300             : {
     301           0 :   mMathMLDisabled = mozilla::Preferences::GetBool(kPrefMathMLDisabled);
     302           0 :   mSVGDisabled = mozilla::Preferences::GetBool(kPrefSVGDisabled);
     303           0 :   return NS_OK;
     304             : }

Generated by: LCOV version 1.13