LCOV - code coverage report
Current view: top level - dom/xslt/xslt - txMozillaXSLTProcessor.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 7 689 1.0 %
Date: 2017-07-14 16:53:18 Functions: 1 87 1.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       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             : #include "txMozillaXSLTProcessor.h"
       7             : #include "nsContentCID.h"
       8             : #include "nsError.h"
       9             : #include "nsIChannel.h"
      10             : #include "mozilla/dom/Element.h"
      11             : #include "nsIDOMElement.h"
      12             : #include "nsIDOMText.h"
      13             : #include "nsIDocument.h"
      14             : #include "nsIDOMDocument.h"
      15             : #include "nsIDOMDocumentFragment.h"
      16             : #include "nsIDOMNodeList.h"
      17             : #include "nsIIOService.h"
      18             : #include "nsILoadGroup.h"
      19             : #include "nsIStringBundle.h"
      20             : #include "nsIURI.h"
      21             : #include "XPathResult.h"
      22             : #include "txExecutionState.h"
      23             : #include "txMozillaTextOutput.h"
      24             : #include "txMozillaXMLOutput.h"
      25             : #include "txURIUtils.h"
      26             : #include "txXMLUtils.h"
      27             : #include "txUnknownHandler.h"
      28             : #include "txXSLTProcessor.h"
      29             : #include "nsIPrincipal.h"
      30             : #include "nsThreadUtils.h"
      31             : #include "jsapi.h"
      32             : #include "txExprParser.h"
      33             : #include "nsIErrorService.h"
      34             : #include "nsIScriptSecurityManager.h"
      35             : #include "nsJSUtils.h"
      36             : #include "nsIXPConnect.h"
      37             : #include "nsVariant.h"
      38             : #include "nsTextNode.h"
      39             : #include "mozilla/dom/DocumentFragment.h"
      40             : #include "mozilla/dom/XSLTProcessorBinding.h"
      41             : 
      42             : using namespace mozilla::dom;
      43             : 
      44             : static NS_DEFINE_CID(kXMLDocumentCID, NS_XMLDOCUMENT_CID);
      45             : 
      46             : /**
      47             :  * Output Handler Factories
      48             :  */
      49           0 : class txToDocHandlerFactory : public txAOutputHandlerFactory
      50             : {
      51             : public:
      52           0 :     txToDocHandlerFactory(txExecutionState* aEs,
      53             :                           nsIDOMDocument* aSourceDocument,
      54             :                           nsITransformObserver* aObserver,
      55             :                           bool aDocumentIsData)
      56           0 :         : mEs(aEs), mSourceDocument(aSourceDocument), mObserver(aObserver),
      57           0 :           mDocumentIsData(aDocumentIsData)
      58             :     {
      59           0 :     }
      60             : 
      61             :     TX_DECL_TXAOUTPUTHANDLERFACTORY
      62             : 
      63             : private:
      64             :     txExecutionState* mEs;
      65             :     nsCOMPtr<nsIDOMDocument> mSourceDocument;
      66             :     nsCOMPtr<nsITransformObserver> mObserver;
      67             :     bool mDocumentIsData;
      68             : };
      69             : 
      70           0 : class txToFragmentHandlerFactory : public txAOutputHandlerFactory
      71             : {
      72             : public:
      73           0 :     explicit txToFragmentHandlerFactory(nsIDOMDocumentFragment* aFragment)
      74           0 :         : mFragment(aFragment)
      75             :     {
      76           0 :     }
      77             : 
      78             :     TX_DECL_TXAOUTPUTHANDLERFACTORY
      79             : 
      80             : private:
      81             :     nsCOMPtr<nsIDOMDocumentFragment> mFragment;
      82             : };
      83             : 
      84             : nsresult
      85           0 : txToDocHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
      86             :                                          txAXMLEventHandler** aHandler)
      87             : {
      88           0 :     *aHandler = nullptr;
      89           0 :     switch (aFormat->mMethod) {
      90             :         case eMethodNotSet:
      91             :         case eXMLOutput:
      92             :         {
      93           0 :             *aHandler = new txUnknownHandler(mEs);
      94           0 :             return NS_OK;
      95             :         }
      96             : 
      97             :         case eHTMLOutput:
      98             :         {
      99             :             nsAutoPtr<txMozillaXMLOutput> handler(
     100           0 :                 new txMozillaXMLOutput(aFormat, mObserver));
     101             : 
     102           0 :             nsresult rv = handler->createResultDocument(EmptyString(),
     103             :                                                         kNameSpaceID_None,
     104             :                                                         mSourceDocument,
     105           0 :                                                         mDocumentIsData);
     106           0 :             if (NS_SUCCEEDED(rv)) {
     107           0 :                 *aHandler = handler.forget();
     108             :             }
     109             : 
     110           0 :             return rv;
     111             :         }
     112             : 
     113             :         case eTextOutput:
     114             :         {
     115             :             nsAutoPtr<txMozillaTextOutput> handler(
     116           0 :                 new txMozillaTextOutput(mObserver));
     117             : 
     118           0 :             nsresult rv = handler->createResultDocument(mSourceDocument,
     119           0 :                                                         mDocumentIsData);
     120           0 :             if (NS_SUCCEEDED(rv)) {
     121           0 :                 *aHandler = handler.forget();
     122             :             }
     123             : 
     124           0 :             return rv;
     125             :         }
     126             :     }
     127             : 
     128           0 :     MOZ_CRASH("Unknown output method");
     129             : 
     130             :     return NS_ERROR_FAILURE;
     131             : }
     132             : 
     133             : nsresult
     134           0 : txToDocHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
     135             :                                          const nsAString& aName,
     136             :                                          int32_t aNsID,
     137             :                                          txAXMLEventHandler** aHandler)
     138             : {
     139           0 :     *aHandler = nullptr;
     140           0 :     switch (aFormat->mMethod) {
     141             :         case eMethodNotSet:
     142             :         {
     143           0 :             NS_ERROR("How can method not be known when root element is?");
     144           0 :             return NS_ERROR_UNEXPECTED;
     145             :         }
     146             : 
     147             :         case eXMLOutput:
     148             :         case eHTMLOutput:
     149             :         {
     150             :             nsAutoPtr<txMozillaXMLOutput> handler(
     151           0 :                 new txMozillaXMLOutput(aFormat, mObserver));
     152             : 
     153           0 :             nsresult rv = handler->createResultDocument(aName, aNsID,
     154             :                                                         mSourceDocument,
     155           0 :                                                         mDocumentIsData);
     156           0 :             if (NS_SUCCEEDED(rv)) {
     157           0 :                 *aHandler = handler.forget();
     158             :             }
     159             : 
     160           0 :             return rv;
     161             :         }
     162             : 
     163             :         case eTextOutput:
     164             :         {
     165             :             nsAutoPtr<txMozillaTextOutput> handler(
     166           0 :                 new txMozillaTextOutput(mObserver));
     167             : 
     168           0 :             nsresult rv = handler->createResultDocument(mSourceDocument,
     169           0 :                                                         mDocumentIsData);
     170           0 :             if (NS_SUCCEEDED(rv)) {
     171           0 :                 *aHandler = handler.forget();
     172             :             }
     173             : 
     174           0 :             return rv;
     175             :         }
     176             :     }
     177             : 
     178           0 :     MOZ_CRASH("Unknown output method");
     179             : 
     180             :     return NS_ERROR_FAILURE;
     181             : }
     182             : 
     183             : nsresult
     184           0 : txToFragmentHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
     185             :                                               txAXMLEventHandler** aHandler)
     186             : {
     187           0 :     *aHandler = nullptr;
     188           0 :     switch (aFormat->mMethod) {
     189             :         case eMethodNotSet:
     190             :         {
     191           0 :             txOutputFormat format;
     192           0 :             format.merge(*aFormat);
     193           0 :             nsCOMPtr<nsIDOMDocument> domdoc;
     194           0 :             mFragment->GetOwnerDocument(getter_AddRefs(domdoc));
     195           0 :             NS_ASSERTION(domdoc, "unable to get ownerdocument");
     196           0 :             nsCOMPtr<nsIDocument> doc = do_QueryInterface(domdoc);
     197             : 
     198           0 :             if (doc && doc->IsHTMLDocument()) {
     199           0 :                 format.mMethod = eHTMLOutput;
     200             :             } else {
     201           0 :                 format.mMethod = eXMLOutput;
     202             :             }
     203             : 
     204           0 :             *aHandler = new txMozillaXMLOutput(&format, mFragment, false);
     205           0 :             break;
     206             :         }
     207             : 
     208             :         case eXMLOutput:
     209             :         case eHTMLOutput:
     210             :         {
     211           0 :             *aHandler = new txMozillaXMLOutput(aFormat, mFragment, false);
     212           0 :             break;
     213             :         }
     214             : 
     215             :         case eTextOutput:
     216             :         {
     217           0 :             *aHandler = new txMozillaTextOutput(mFragment);
     218           0 :             break;
     219             :         }
     220             :     }
     221           0 :     NS_ENSURE_TRUE(*aHandler, NS_ERROR_OUT_OF_MEMORY);
     222           0 :     return NS_OK;
     223             : }
     224             : 
     225             : nsresult
     226           0 : txToFragmentHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
     227             :                                               const nsAString& aName,
     228             :                                               int32_t aNsID,
     229             :                                               txAXMLEventHandler** aHandler)
     230             : {
     231           0 :     *aHandler = nullptr;
     232           0 :     NS_ASSERTION(aFormat->mMethod != eMethodNotSet,
     233             :                  "How can method not be known when root element is?");
     234           0 :     NS_ENSURE_TRUE(aFormat->mMethod != eMethodNotSet, NS_ERROR_UNEXPECTED);
     235           0 :     return createHandlerWith(aFormat, aHandler);
     236             : }
     237             : 
     238           0 : class txVariable : public txIGlobalParameter
     239             : {
     240             : public:
     241           0 :     explicit txVariable(nsIVariant* aValue) : mValue(aValue)
     242             :     {
     243           0 :         NS_ASSERTION(aValue, "missing value");
     244           0 :     }
     245           0 :     explicit txVariable(txAExprResult* aValue) : mTxValue(aValue)
     246             :     {
     247           0 :         NS_ASSERTION(aValue, "missing value");
     248           0 :     }
     249           0 :     nsresult getValue(txAExprResult** aValue)
     250             :     {
     251           0 :         NS_ASSERTION(mValue || mTxValue, "variablevalue is null");
     252             : 
     253           0 :         if (!mTxValue) {
     254           0 :             nsresult rv = Convert(mValue, getter_AddRefs(mTxValue));
     255           0 :             NS_ENSURE_SUCCESS(rv, rv);
     256             :         }
     257             : 
     258           0 :         *aValue = mTxValue;
     259           0 :         NS_ADDREF(*aValue);
     260             : 
     261           0 :         return NS_OK;
     262             :     }
     263           0 :     nsresult getValue(nsIVariant** aValue)
     264             :     {
     265           0 :         *aValue = mValue;
     266           0 :         NS_ADDREF(*aValue);
     267           0 :         return NS_OK;
     268             :     }
     269             :     nsIVariant* getValue()
     270             :     {
     271             :         return mValue;
     272             :     }
     273           0 :     void setValue(nsIVariant* aValue)
     274             :     {
     275           0 :         NS_ASSERTION(aValue, "setting variablevalue to null");
     276           0 :         mValue = aValue;
     277           0 :         mTxValue = nullptr;
     278           0 :     }
     279           0 :     void setValue(txAExprResult* aValue)
     280             :     {
     281           0 :         NS_ASSERTION(aValue, "setting variablevalue to null");
     282           0 :         mValue = nullptr;
     283           0 :         mTxValue = aValue;
     284           0 :     }
     285             : 
     286             :     friend void ImplCycleCollectionUnlink(txVariable& aVariable);
     287             :     friend void ImplCycleCollectionTraverse(
     288             :         nsCycleCollectionTraversalCallback& aCallback, txVariable& aVariable,
     289             :         const char* aName, uint32_t aFlags);
     290             : 
     291             : private:
     292             :     static nsresult Convert(nsIVariant *aValue, txAExprResult** aResult);
     293             : 
     294             :     nsCOMPtr<nsIVariant> mValue;
     295             :     RefPtr<txAExprResult> mTxValue;
     296             : };
     297             : 
     298             : inline void
     299           0 : ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
     300             :                             txVariable& aVariable, const char* aName,
     301             :                             uint32_t aFlags)
     302             : {
     303           0 :     ImplCycleCollectionTraverse(aCallback, aVariable.mValue, aName, aFlags);
     304           0 : }
     305             : 
     306             : inline void
     307           0 : ImplCycleCollectionUnlink(txOwningExpandedNameMap<txIGlobalParameter>& aMap)
     308             : {
     309           0 :     aMap.clear();
     310           0 : }
     311             : 
     312             : inline void
     313           0 : ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
     314             :                             txOwningExpandedNameMap<txIGlobalParameter>& aMap,
     315             :                             const char* aName,
     316             :                             uint32_t aFlags = 0)
     317             : {
     318           0 :     aFlags |= CycleCollectionEdgeNameArrayFlag;
     319           0 :     txOwningExpandedNameMap<txIGlobalParameter>::iterator iter(aMap);
     320           0 :     while (iter.next()) {
     321             :         ImplCycleCollectionTraverse(aCallback,
     322           0 :                                     *static_cast<txVariable*>(iter.value()),
     323           0 :                                     aName, aFlags);
     324             :     }
     325           0 : }
     326             : 
     327             : /**
     328             :  * txMozillaXSLTProcessor
     329             :  */
     330             : 
     331           0 : NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(txMozillaXSLTProcessor,
     332             :                                       mOwner, mEmbeddedStylesheetRoot,
     333             :                                       mSource, mVariables)
     334             : 
     335           0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(txMozillaXSLTProcessor)
     336           0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(txMozillaXSLTProcessor)
     337             : 
     338           0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(txMozillaXSLTProcessor)
     339           0 :     NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
     340           0 :     NS_INTERFACE_MAP_ENTRY(nsIXSLTProcessor)
     341           0 :     NS_INTERFACE_MAP_ENTRY(nsIXSLTProcessorPrivate)
     342           0 :     NS_INTERFACE_MAP_ENTRY(nsIDocumentTransformer)
     343           0 :     NS_INTERFACE_MAP_ENTRY(nsIMutationObserver)
     344           0 :     NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXSLTProcessor)
     345           0 : NS_INTERFACE_MAP_END
     346             : 
     347           0 : txMozillaXSLTProcessor::txMozillaXSLTProcessor()
     348             :   : mOwner(nullptr),
     349             :     mStylesheetDocument(nullptr),
     350             :     mTransformResult(NS_OK),
     351             :     mCompileResult(NS_OK),
     352           0 :     mFlags(0)
     353             : {
     354           0 : }
     355             : 
     356           0 : txMozillaXSLTProcessor::txMozillaXSLTProcessor(nsISupports* aOwner)
     357             :   : mOwner(aOwner),
     358             :     mStylesheetDocument(nullptr),
     359             :     mTransformResult(NS_OK),
     360             :     mCompileResult(NS_OK),
     361           0 :     mFlags(0)
     362             : {
     363           0 : }
     364             : 
     365           0 : txMozillaXSLTProcessor::~txMozillaXSLTProcessor()
     366             : {
     367           0 :     if (mStylesheetDocument) {
     368           0 :         mStylesheetDocument->RemoveMutationObserver(this);
     369             :     }
     370           0 : }
     371             : 
     372             : NS_IMETHODIMP
     373           0 : txMozillaXSLTProcessor::SetTransformObserver(nsITransformObserver* aObserver)
     374             : {
     375           0 :     mObserver = aObserver;
     376           0 :     return NS_OK;
     377             : }
     378             : 
     379             : nsresult
     380           0 : txMozillaXSLTProcessor::SetSourceContentModel(nsIDOMNode* aSourceDOM)
     381             : {
     382           0 :     mSource = aSourceDOM;
     383             : 
     384           0 :     if (NS_FAILED(mTransformResult)) {
     385           0 :         notifyError();
     386           0 :         return NS_OK;
     387             :     }
     388             : 
     389           0 :     if (mStylesheet) {
     390           0 :         return DoTransform();
     391             :     }
     392             : 
     393           0 :     return NS_OK;
     394             : }
     395             : 
     396             : NS_IMETHODIMP
     397           0 : txMozillaXSLTProcessor::AddXSLTParamNamespace(const nsString& aPrefix,
     398             :                                               const nsString& aNamespace)
     399             : {
     400           0 :     nsCOMPtr<nsIAtom> pre = NS_Atomize(aPrefix);
     401           0 :     return mParamNamespaceMap.mapNamespace(pre, aNamespace);
     402             : }
     403             : 
     404             : 
     405           0 : class txXSLTParamContext : public txIParseContext,
     406             :                            public txIEvalContext
     407             : {
     408             : public:
     409           0 :     txXSLTParamContext(txNamespaceMap *aResolver, const txXPathNode& aContext,
     410             :                        txResultRecycler* aRecycler)
     411           0 :         : mResolver(aResolver),
     412             :           mContext(aContext),
     413           0 :           mRecycler(aRecycler)
     414             :     {
     415           0 :     }
     416             : 
     417             :     // txIParseContext
     418           0 :     nsresult resolveNamespacePrefix(nsIAtom* aPrefix, int32_t& aID)
     419             :     {
     420           0 :         aID = mResolver->lookupNamespace(aPrefix);
     421           0 :         return aID == kNameSpaceID_Unknown ? NS_ERROR_DOM_NAMESPACE_ERR :
     422           0 :                                              NS_OK;
     423             :     }
     424           0 :     nsresult resolveFunctionCall(nsIAtom* aName, int32_t aID,
     425             :                                  FunctionCall** aFunction)
     426             :     {
     427           0 :         return NS_ERROR_XPATH_UNKNOWN_FUNCTION;
     428             :     }
     429           0 :     bool caseInsensitiveNameTests()
     430             :     {
     431           0 :         return false;
     432             :     }
     433           0 :     void SetErrorOffset(uint32_t aOffset)
     434             :     {
     435           0 :     }
     436             : 
     437             :     // txIEvalContext
     438           0 :     nsresult getVariable(int32_t aNamespace, nsIAtom* aLName,
     439             :                          txAExprResult*& aResult)
     440             :     {
     441           0 :         aResult = nullptr;
     442           0 :         return NS_ERROR_INVALID_ARG;
     443             :     }
     444           0 :     nsresult isStripSpaceAllowed(const txXPathNode& aNode, bool& aAllowed)
     445             :     {
     446           0 :         aAllowed = false;
     447             : 
     448           0 :         return NS_OK;
     449             :     }
     450           0 :     void* getPrivateContext()
     451             :     {
     452           0 :         return nullptr;
     453             :     }
     454           0 :     txResultRecycler* recycler()
     455             :     {
     456           0 :         return mRecycler;
     457             :     }
     458           0 :     void receiveError(const nsAString& aMsg, nsresult aRes)
     459             :     {
     460           0 :     }
     461           0 :     const txXPathNode& getContextNode()
     462             :     {
     463           0 :       return mContext;
     464             :     }
     465           0 :     uint32_t size()
     466             :     {
     467           0 :       return 1;
     468             :     }
     469           0 :     uint32_t position()
     470             :     {
     471           0 :       return 1;
     472             :     }
     473             : 
     474             : private:
     475             :     txNamespaceMap *mResolver;
     476             :     const txXPathNode& mContext;
     477             :     txResultRecycler* mRecycler;
     478             : };
     479             : 
     480             : 
     481             : NS_IMETHODIMP
     482           0 : txMozillaXSLTProcessor::AddXSLTParam(const nsString& aName,
     483             :                                      const nsString& aNamespace,
     484             :                                      const nsString& aSelect,
     485             :                                      const nsString& aValue,
     486             :                                      nsIDOMNode* aContext)
     487             : {
     488           0 :     nsresult rv = NS_OK;
     489             : 
     490           0 :     if (aSelect.IsVoid() == aValue.IsVoid()) {
     491             :         // Ignore if neither or both are specified
     492           0 :         return NS_ERROR_FAILURE;
     493             :     }
     494             : 
     495           0 :     RefPtr<txAExprResult> value;
     496           0 :     if (!aSelect.IsVoid()) {
     497             : 
     498             :         // Set up context
     499             :         nsAutoPtr<txXPathNode> contextNode(
     500           0 :           txXPathNativeNode::createXPathNode(aContext));
     501           0 :         NS_ENSURE_TRUE(contextNode, NS_ERROR_OUT_OF_MEMORY);
     502             : 
     503           0 :         if (!mRecycler) {
     504           0 :             mRecycler = new txResultRecycler;
     505             :         }
     506             : 
     507           0 :         txXSLTParamContext paramContext(&mParamNamespaceMap, *contextNode,
     508           0 :                                         mRecycler);
     509             : 
     510             :         // Parse
     511           0 :         nsAutoPtr<Expr> expr;
     512           0 :         rv = txExprParser::createExpr(aSelect, &paramContext,
     513           0 :                                       getter_Transfers(expr));
     514           0 :         NS_ENSURE_SUCCESS(rv, rv);
     515             : 
     516             :         // Evaluate
     517           0 :         rv = expr->evaluate(&paramContext, getter_AddRefs(value));
     518           0 :         NS_ENSURE_SUCCESS(rv, rv);
     519             :     }
     520             :     else {
     521           0 :         value = new StringResult(aValue, nullptr);
     522             :     }
     523             : 
     524           0 :     nsCOMPtr<nsIAtom> name = NS_Atomize(aName);
     525           0 :     int32_t nsId = kNameSpaceID_Unknown;
     526             :     rv = nsContentUtils::NameSpaceManager()->
     527           0 :         RegisterNameSpace(aNamespace, nsId);
     528           0 :     NS_ENSURE_SUCCESS(rv, rv);
     529             : 
     530           0 :     txExpandedName varName(nsId, name);
     531           0 :     txVariable* var = static_cast<txVariable*>(mVariables.get(varName));
     532           0 :     if (var) {
     533           0 :         var->setValue(value);
     534             : 
     535           0 :         return NS_OK;
     536             :     }
     537             : 
     538           0 :     var = new txVariable(value);
     539           0 :     NS_ENSURE_TRUE(var, NS_ERROR_OUT_OF_MEMORY);
     540             : 
     541           0 :     return mVariables.add(varName, var);
     542             : }
     543             : 
     544             : class nsTransformBlockerEvent : public mozilla::Runnable {
     545             : public:
     546             :   RefPtr<txMozillaXSLTProcessor> mProcessor;
     547             : 
     548           0 :   explicit nsTransformBlockerEvent(txMozillaXSLTProcessor* processor)
     549           0 :     : mozilla::Runnable("nsTransformBlockerEvent")
     550           0 :     , mProcessor(processor)
     551           0 :   {}
     552             : 
     553           0 :   ~nsTransformBlockerEvent()
     554           0 :   {
     555             :     nsCOMPtr<nsIDocument> document =
     556           0 :         do_QueryInterface(mProcessor->GetSourceContentModel());
     557           0 :     document->UnblockOnload(true);
     558           0 :   }
     559             : 
     560           0 :   NS_IMETHOD Run() override
     561             :   {
     562           0 :     mProcessor->TransformToDoc(nullptr, false);
     563           0 :     return NS_OK;
     564             :   }
     565             : };
     566             : 
     567             : nsresult
     568           0 : txMozillaXSLTProcessor::DoTransform()
     569             : {
     570           0 :     NS_ENSURE_TRUE(mSource, NS_ERROR_UNEXPECTED);
     571           0 :     NS_ENSURE_TRUE(mStylesheet, NS_ERROR_UNEXPECTED);
     572           0 :     NS_ASSERTION(mObserver, "no observer");
     573           0 :     NS_ASSERTION(NS_IsMainThread(), "should only be on main thread");
     574             : 
     575             :     nsresult rv;
     576           0 :     nsCOMPtr<nsIDocument> document = do_QueryInterface(mSource, &rv);
     577           0 :     NS_ENSURE_SUCCESS(rv, rv);
     578             : 
     579           0 :     nsCOMPtr<nsIRunnable> event = new nsTransformBlockerEvent(this);
     580           0 :     document->BlockOnload();
     581           0 :     rv = NS_DispatchToCurrentThread(event);
     582           0 :     if (NS_FAILED(rv)) {
     583             :         // XXX Maybe we should just display the source document in this case?
     584             :         //     Also, set up context information, see bug 204655.
     585           0 :         reportError(rv, nullptr, nullptr);
     586             :     }
     587             : 
     588           0 :     return rv;
     589             : }
     590             : 
     591             : NS_IMETHODIMP
     592           0 : txMozillaXSLTProcessor::ImportStylesheet(nsIDOMNode *aStyle)
     593             : {
     594           0 :     NS_ENSURE_TRUE(aStyle, NS_ERROR_NULL_POINTER);
     595             : 
     596             :     // We don't support importing multiple stylesheets yet.
     597           0 :     NS_ENSURE_TRUE(!mStylesheetDocument && !mStylesheet,
     598             :                    NS_ERROR_NOT_IMPLEMENTED);
     599             : 
     600           0 :     nsCOMPtr<nsINode> node = do_QueryInterface(aStyle);
     601           0 :     if (!node || !nsContentUtils::SubjectPrincipalOrSystemIfNativeCaller()->Subsumes(node->NodePrincipal())) {
     602           0 :         return NS_ERROR_DOM_SECURITY_ERR;
     603             :     }
     604             : 
     605           0 :     nsCOMPtr<nsINode> styleNode = do_QueryInterface(aStyle);
     606           0 :     NS_ENSURE_TRUE(styleNode &&
     607             :                    (styleNode->IsElement() ||
     608             :                     styleNode->IsNodeOfType(nsINode::eDOCUMENT)),
     609             :                    NS_ERROR_INVALID_ARG);
     610             : 
     611           0 :     nsresult rv = TX_CompileStylesheet(styleNode, this,
     612           0 :                                        getter_AddRefs(mStylesheet));
     613             :     // XXX set up exception context, bug 204658
     614           0 :     NS_ENSURE_SUCCESS(rv, rv);
     615             : 
     616           0 :     if (styleNode->IsElement()) {
     617           0 :         mStylesheetDocument = styleNode->OwnerDoc();
     618           0 :         NS_ENSURE_TRUE(mStylesheetDocument, NS_ERROR_UNEXPECTED);
     619             : 
     620           0 :         mEmbeddedStylesheetRoot = static_cast<nsIContent*>(styleNode.get());
     621             :     }
     622             :     else {
     623           0 :         mStylesheetDocument = static_cast<nsIDocument*>(styleNode.get());
     624             :     }
     625             : 
     626           0 :     mStylesheetDocument->AddMutationObserver(this);
     627             : 
     628           0 :     return NS_OK;
     629             : }
     630             : 
     631             : NS_IMETHODIMP
     632           0 : txMozillaXSLTProcessor::TransformToDocument(nsIDOMNode *aSource,
     633             :                                             nsIDOMDocument **aResult)
     634             : {
     635           0 :     NS_ENSURE_ARG(aSource);
     636           0 :     NS_ENSURE_ARG_POINTER(aResult);
     637           0 :     NS_ENSURE_SUCCESS(mCompileResult, mCompileResult);
     638             : 
     639           0 :     if (!nsContentUtils::CanCallerAccess(aSource)) {
     640           0 :         return NS_ERROR_DOM_SECURITY_ERR;
     641             :     }
     642             : 
     643           0 :     nsresult rv = ensureStylesheet();
     644           0 :     NS_ENSURE_SUCCESS(rv, rv);
     645             : 
     646           0 :     mSource = aSource;
     647             : 
     648           0 :     return TransformToDoc(aResult, true);
     649             : }
     650             : 
     651             : nsresult
     652           0 : txMozillaXSLTProcessor::TransformToDoc(nsIDOMDocument **aResult,
     653             :                                        bool aCreateDataDocument)
     654             : {
     655           0 :     nsAutoPtr<txXPathNode> sourceNode(txXPathNativeNode::createXPathNode(mSource));
     656           0 :     if (!sourceNode) {
     657           0 :         return NS_ERROR_OUT_OF_MEMORY;
     658             :     }
     659             : 
     660           0 :     nsCOMPtr<nsIDOMDocument> sourceDOMDocument;
     661           0 :     mSource->GetOwnerDocument(getter_AddRefs(sourceDOMDocument));
     662           0 :     if (!sourceDOMDocument) {
     663           0 :         sourceDOMDocument = do_QueryInterface(mSource);
     664             :     }
     665             : 
     666           0 :     txExecutionState es(mStylesheet, IsLoadDisabled());
     667             : 
     668             :     // XXX Need to add error observers
     669             : 
     670             :     // If aResult is non-null, we're a data document
     671             :     txToDocHandlerFactory handlerFactory(&es, sourceDOMDocument, mObserver,
     672           0 :                                          aCreateDataDocument);
     673           0 :     es.mOutputHandlerFactory = &handlerFactory;
     674             : 
     675           0 :     nsresult rv = es.init(*sourceNode, &mVariables);
     676             : 
     677             :     // Process root of XML source document
     678           0 :     if (NS_SUCCEEDED(rv)) {
     679           0 :         rv = txXSLTProcessor::execute(es);
     680             :     }
     681             : 
     682           0 :     nsresult endRv = es.end(rv);
     683           0 :     if (NS_SUCCEEDED(rv)) {
     684           0 :       rv = endRv;
     685             :     }
     686             : 
     687           0 :     if (NS_SUCCEEDED(rv)) {
     688           0 :         if (aResult) {
     689             :             txAOutputXMLEventHandler* handler =
     690           0 :                 static_cast<txAOutputXMLEventHandler*>(es.mOutputHandler);
     691           0 :             handler->getOutputDocument(aResult);
     692           0 :             nsCOMPtr<nsIDocument> doc = do_QueryInterface(*aResult);
     693           0 :             MOZ_ASSERT(doc->GetReadyStateEnum() ==
     694             :                        nsIDocument::READYSTATE_INTERACTIVE, "Bad readyState");
     695           0 :             doc->SetReadyStateInternal(nsIDocument::READYSTATE_COMPLETE);
     696             :         }
     697             :     }
     698           0 :     else if (mObserver) {
     699             :         // XXX set up context information, bug 204655
     700           0 :         reportError(rv, nullptr, nullptr);
     701             :     }
     702             : 
     703           0 :     return rv;
     704             : }
     705             : 
     706             : NS_IMETHODIMP
     707           0 : txMozillaXSLTProcessor::TransformToFragment(nsIDOMNode *aSource,
     708             :                                             nsIDOMDocument *aOutput,
     709             :                                             nsIDOMDocumentFragment **aResult)
     710             : {
     711           0 :     NS_ENSURE_ARG(aSource);
     712           0 :     NS_ENSURE_ARG(aOutput);
     713           0 :     NS_ENSURE_ARG_POINTER(aResult);
     714           0 :     NS_ENSURE_SUCCESS(mCompileResult, mCompileResult);
     715             : 
     716           0 :     nsCOMPtr<nsINode> node = do_QueryInterface(aSource);
     717           0 :     nsCOMPtr<nsIDocument> doc = do_QueryInterface(aOutput);
     718           0 :     NS_ENSURE_TRUE(node && doc, NS_ERROR_DOM_SECURITY_ERR);
     719           0 :     nsIPrincipal* subject = nsContentUtils::SubjectPrincipalOrSystemIfNativeCaller();
     720           0 :     if (!subject->Subsumes(node->NodePrincipal()) ||
     721           0 :         !subject->Subsumes(doc->NodePrincipal()))
     722             :     {
     723           0 :         return NS_ERROR_DOM_SECURITY_ERR;
     724             :     }
     725             : 
     726           0 :     nsresult rv = ensureStylesheet();
     727           0 :     NS_ENSURE_SUCCESS(rv, rv);
     728             : 
     729           0 :     nsAutoPtr<txXPathNode> sourceNode(txXPathNativeNode::createXPathNode(aSource));
     730           0 :     if (!sourceNode) {
     731           0 :         return NS_ERROR_OUT_OF_MEMORY;
     732             :     }
     733             : 
     734           0 :     txExecutionState es(mStylesheet, IsLoadDisabled());
     735             : 
     736             :     // XXX Need to add error observers
     737             : 
     738           0 :     rv = aOutput->CreateDocumentFragment(aResult);
     739           0 :     NS_ENSURE_SUCCESS(rv, rv);
     740           0 :     txToFragmentHandlerFactory handlerFactory(*aResult);
     741           0 :     es.mOutputHandlerFactory = &handlerFactory;
     742             : 
     743           0 :     rv = es.init(*sourceNode, &mVariables);
     744             : 
     745             :     // Process root of XML source document
     746           0 :     if (NS_SUCCEEDED(rv)) {
     747           0 :         rv = txXSLTProcessor::execute(es);
     748             :     }
     749             :     // XXX setup exception context, bug 204658
     750           0 :     nsresult endRv = es.end(rv);
     751           0 :     if (NS_SUCCEEDED(rv)) {
     752           0 :       rv = endRv;
     753             :     }
     754             : 
     755           0 :     return rv;
     756             : }
     757             : 
     758             : NS_IMETHODIMP
     759           0 : txMozillaXSLTProcessor::SetParameter(const nsAString & aNamespaceURI,
     760             :                                      const nsAString & aLocalName,
     761             :                                      nsIVariant *aValue)
     762             : {
     763           0 :     NS_ENSURE_ARG(aValue);
     764             : 
     765           0 :     nsCOMPtr<nsIVariant> value = aValue;
     766             : 
     767             :     uint16_t dataType;
     768           0 :     value->GetDataType(&dataType);
     769           0 :     switch (dataType) {
     770             :         // Number
     771             :         case nsIDataType::VTYPE_INT8:
     772             :         case nsIDataType::VTYPE_INT16:
     773             :         case nsIDataType::VTYPE_INT32:
     774             :         case nsIDataType::VTYPE_INT64:
     775             :         case nsIDataType::VTYPE_UINT8:
     776             :         case nsIDataType::VTYPE_UINT16:
     777             :         case nsIDataType::VTYPE_UINT32:
     778             :         case nsIDataType::VTYPE_UINT64:
     779             :         case nsIDataType::VTYPE_FLOAT:
     780             :         case nsIDataType::VTYPE_DOUBLE:
     781             : 
     782             :         // Boolean
     783             :         case nsIDataType::VTYPE_BOOL:
     784             : 
     785             :         // String
     786             :         case nsIDataType::VTYPE_CHAR:
     787             :         case nsIDataType::VTYPE_WCHAR:
     788             :         case nsIDataType::VTYPE_DOMSTRING:
     789             :         case nsIDataType::VTYPE_CHAR_STR:
     790             :         case nsIDataType::VTYPE_WCHAR_STR:
     791             :         case nsIDataType::VTYPE_STRING_SIZE_IS:
     792             :         case nsIDataType::VTYPE_WSTRING_SIZE_IS:
     793             :         case nsIDataType::VTYPE_UTF8STRING:
     794             :         case nsIDataType::VTYPE_CSTRING:
     795             :         case nsIDataType::VTYPE_ASTRING:
     796             :         {
     797           0 :             break;
     798             :         }
     799             : 
     800             :         // Nodeset
     801             :         case nsIDataType::VTYPE_INTERFACE:
     802             :         case nsIDataType::VTYPE_INTERFACE_IS:
     803             :         {
     804           0 :             nsCOMPtr<nsISupports> supports;
     805           0 :             nsresult rv = value->GetAsISupports(getter_AddRefs(supports));
     806           0 :             NS_ENSURE_SUCCESS(rv, rv);
     807             : 
     808           0 :             nsCOMPtr<nsIDOMNode> node = do_QueryInterface(supports);
     809           0 :             if (node) {
     810           0 :                 if (!nsContentUtils::CanCallerAccess(node)) {
     811           0 :                     return NS_ERROR_DOM_SECURITY_ERR;
     812             :                 }
     813             : 
     814           0 :                 break;
     815             :             }
     816             : 
     817           0 :             nsCOMPtr<nsIXPathResult> xpathResult = do_QueryInterface(supports);
     818           0 :             if (xpathResult) {
     819           0 :                 RefPtr<txAExprResult> result;
     820           0 :                 nsresult rv = xpathResult->GetExprResult(getter_AddRefs(result));
     821           0 :                 NS_ENSURE_SUCCESS(rv, rv);
     822             : 
     823           0 :                 if (result->getResultType() == txAExprResult::NODESET) {
     824             :                     txNodeSet *nodeSet =
     825             :                         static_cast<txNodeSet*>
     826           0 :                                    (static_cast<txAExprResult*>(result));
     827             : 
     828           0 :                     nsCOMPtr<nsIDOMNode> node;
     829           0 :                     int32_t i, count = nodeSet->size();
     830           0 :                     for (i = 0; i < count; ++i) {
     831           0 :                         rv = txXPathNativeNode::getNode(nodeSet->get(i),
     832           0 :                                                         getter_AddRefs(node));
     833           0 :                         NS_ENSURE_SUCCESS(rv, rv);
     834             : 
     835           0 :                         if (!nsContentUtils::CanCallerAccess(node)) {
     836           0 :                             return NS_ERROR_DOM_SECURITY_ERR;
     837             :                         }
     838             :                     }
     839             :                 }
     840             : 
     841             :                 // Clone the XPathResult so that mutations don't affect this
     842             :                 // variable.
     843           0 :                 nsCOMPtr<nsIXPathResult> clone;
     844           0 :                 rv = xpathResult->Clone(getter_AddRefs(clone));
     845           0 :                 NS_ENSURE_SUCCESS(rv, rv);
     846             : 
     847           0 :                 RefPtr<nsVariant> variant = new nsVariant();
     848             : 
     849           0 :                 rv = variant->SetAsISupports(clone);
     850           0 :                 NS_ENSURE_SUCCESS(rv, rv);
     851             : 
     852           0 :                 value = variant;
     853             : 
     854           0 :                 break;
     855             :             }
     856             : 
     857           0 :             nsCOMPtr<nsIDOMNodeList> nodeList = do_QueryInterface(supports);
     858           0 :             if (nodeList) {
     859             :                 uint32_t length;
     860           0 :                 nodeList->GetLength(&length);
     861             : 
     862           0 :                 nsCOMPtr<nsIDOMNode> node;
     863             :                 uint32_t i;
     864           0 :                 for (i = 0; i < length; ++i) {
     865           0 :                     nodeList->Item(i, getter_AddRefs(node));
     866             : 
     867           0 :                     if (!nsContentUtils::CanCallerAccess(node)) {
     868           0 :                         return NS_ERROR_DOM_SECURITY_ERR;
     869             :                     }
     870             :                 }
     871             : 
     872           0 :                 break;
     873             :             }
     874             : 
     875             :             // Random JS Objects will be converted to a string.
     876             :             nsCOMPtr<nsIXPConnectJSObjectHolder> holder =
     877           0 :                 do_QueryInterface(supports);
     878           0 :             if (holder) {
     879           0 :                 break;
     880             :             }
     881             : 
     882             :             // We don't know how to handle this type of param.
     883           0 :             return NS_ERROR_ILLEGAL_VALUE;
     884             :         }
     885             : 
     886             :         case nsIDataType::VTYPE_ARRAY:
     887             :         {
     888             :             uint16_t type;
     889             :             nsIID iid;
     890             :             uint32_t count;
     891             :             void* array;
     892           0 :             nsresult rv = value->GetAsArray(&type, &iid, &count, &array);
     893           0 :             NS_ENSURE_SUCCESS(rv, rv);
     894             : 
     895           0 :             if (type != nsIDataType::VTYPE_INTERFACE &&
     896           0 :                 type != nsIDataType::VTYPE_INTERFACE_IS) {
     897           0 :                 free(array);
     898             : 
     899             :                 // We only support arrays of DOM nodes.
     900           0 :                 return NS_ERROR_ILLEGAL_VALUE;
     901             :             }
     902             : 
     903           0 :             nsISupports** values = static_cast<nsISupports**>(array);
     904             : 
     905             :             uint32_t i;
     906           0 :             for (i = 0; i < count; ++i) {
     907           0 :                 nsISupports *supports = values[i];
     908           0 :                 nsCOMPtr<nsIDOMNode> node = do_QueryInterface(supports);
     909             : 
     910           0 :                 if (node) {
     911           0 :                     rv = nsContentUtils::CanCallerAccess(node) ? NS_OK :
     912             :                          NS_ERROR_DOM_SECURITY_ERR;
     913             :                 }
     914             :                 else {
     915             :                     // We only support arrays of DOM nodes.
     916           0 :                     rv = NS_ERROR_ILLEGAL_VALUE;
     917             :                 }
     918             : 
     919           0 :                 if (NS_FAILED(rv)) {
     920           0 :                     while (i < count) {
     921           0 :                         NS_IF_RELEASE(values[i]);
     922           0 :                         ++i;
     923             :                     }
     924           0 :                     free(array);
     925             : 
     926           0 :                     return rv;
     927             :                 }
     928             : 
     929           0 :                 NS_RELEASE(supports);
     930             :             }
     931             : 
     932           0 :             free(array);
     933             : 
     934           0 :             break;
     935             :         }
     936             : 
     937             :         default:
     938             :         {
     939           0 :             return NS_ERROR_FAILURE;
     940             :         }
     941             :     }
     942             : 
     943           0 :     int32_t nsId = kNameSpaceID_Unknown;
     944             :     nsresult rv = nsContentUtils::NameSpaceManager()->
     945           0 :         RegisterNameSpace(aNamespaceURI, nsId);
     946           0 :     NS_ENSURE_SUCCESS(rv, rv);
     947           0 :     nsCOMPtr<nsIAtom> localName = NS_Atomize(aLocalName);
     948           0 :     txExpandedName varName(nsId, localName);
     949             : 
     950           0 :     txVariable* var = static_cast<txVariable*>(mVariables.get(varName));
     951           0 :     if (var) {
     952           0 :         var->setValue(value);
     953           0 :         return NS_OK;
     954             :     }
     955             : 
     956           0 :     var = new txVariable(value);
     957           0 :     return mVariables.add(varName, var);
     958             : }
     959             : 
     960             : NS_IMETHODIMP
     961           0 : txMozillaXSLTProcessor::GetParameter(const nsAString& aNamespaceURI,
     962             :                                      const nsAString& aLocalName,
     963             :                                      nsIVariant **aResult)
     964             : {
     965           0 :     int32_t nsId = kNameSpaceID_Unknown;
     966             :     nsresult rv = nsContentUtils::NameSpaceManager()->
     967           0 :         RegisterNameSpace(aNamespaceURI, nsId);
     968           0 :     NS_ENSURE_SUCCESS(rv, rv);
     969           0 :     nsCOMPtr<nsIAtom> localName = NS_Atomize(aLocalName);
     970           0 :     txExpandedName varName(nsId, localName);
     971             : 
     972           0 :     txVariable* var = static_cast<txVariable*>(mVariables.get(varName));
     973           0 :     if (var) {
     974           0 :         return var->getValue(aResult);
     975             :     }
     976           0 :     return NS_OK;
     977             : }
     978             : 
     979             : NS_IMETHODIMP
     980           0 : txMozillaXSLTProcessor::RemoveParameter(const nsAString& aNamespaceURI,
     981             :                                         const nsAString& aLocalName)
     982             : {
     983           0 :     int32_t nsId = kNameSpaceID_Unknown;
     984             :     nsresult rv = nsContentUtils::NameSpaceManager()->
     985           0 :         RegisterNameSpace(aNamespaceURI, nsId);
     986           0 :     NS_ENSURE_SUCCESS(rv, rv);
     987           0 :     nsCOMPtr<nsIAtom> localName = NS_Atomize(aLocalName);
     988           0 :     txExpandedName varName(nsId, localName);
     989             : 
     990           0 :     mVariables.remove(varName);
     991           0 :     return NS_OK;
     992             : }
     993             : 
     994             : NS_IMETHODIMP
     995           0 : txMozillaXSLTProcessor::ClearParameters()
     996             : {
     997           0 :     mVariables.clear();
     998             : 
     999           0 :     return NS_OK;
    1000             : }
    1001             : 
    1002             : NS_IMETHODIMP
    1003           0 : txMozillaXSLTProcessor::Reset()
    1004             : {
    1005           0 :     if (mStylesheetDocument) {
    1006           0 :         mStylesheetDocument->RemoveMutationObserver(this);
    1007             :     }
    1008           0 :     mStylesheet = nullptr;
    1009           0 :     mStylesheetDocument = nullptr;
    1010           0 :     mEmbeddedStylesheetRoot = nullptr;
    1011           0 :     mCompileResult = NS_OK;
    1012           0 :     mVariables.clear();
    1013             : 
    1014           0 :     return NS_OK;
    1015             : }
    1016             : 
    1017             : void
    1018           0 : txMozillaXSLTProcessor::SetFlags(uint32_t aFlags, SystemCallerGuarantee)
    1019             : {
    1020           0 :     mFlags = aFlags;
    1021           0 : }
    1022             : 
    1023             : uint32_t
    1024           0 : txMozillaXSLTProcessor::Flags(SystemCallerGuarantee)
    1025             : {
    1026           0 :     return mFlags;
    1027             : }
    1028             : 
    1029             : NS_IMETHODIMP
    1030           0 : txMozillaXSLTProcessor::LoadStyleSheet(nsIURI* aUri,
    1031             :                                        nsIDocument* aLoaderDocument)
    1032             : {
    1033           0 :     mozilla::net::ReferrerPolicy refpol = mozilla::net::RP_Unset;
    1034           0 :     if (mStylesheetDocument) {
    1035           0 :         refpol = mStylesheetDocument->GetReferrerPolicy();
    1036             :     }
    1037             : 
    1038           0 :     nsresult rv = TX_LoadSheet(aUri, this, aLoaderDocument, refpol);
    1039           0 :     if (NS_FAILED(rv) && mObserver) {
    1040             :         // This is most likely a network or security error, just
    1041             :         // use the uri as context.
    1042           0 :         nsAutoCString spec;
    1043           0 :         aUri->GetSpec(spec);
    1044           0 :         CopyUTF8toUTF16(spec, mSourceText);
    1045           0 :         nsresult status = NS_ERROR_GET_MODULE(rv) == NS_ERROR_MODULE_XSLT ? rv :
    1046           0 :                           NS_ERROR_XSLT_NETWORK_ERROR;
    1047           0 :         reportError(status, nullptr, nullptr);
    1048             :     }
    1049           0 :     return rv;
    1050             : }
    1051             : 
    1052             : nsresult
    1053           0 : txMozillaXSLTProcessor::setStylesheet(txStylesheet* aStylesheet)
    1054             : {
    1055           0 :     mStylesheet = aStylesheet;
    1056           0 :     if (mSource) {
    1057           0 :         return DoTransform();
    1058             :     }
    1059           0 :     return NS_OK;
    1060             : }
    1061             : 
    1062             : void
    1063           0 : txMozillaXSLTProcessor::reportError(nsresult aResult,
    1064             :                                     const char16_t *aErrorText,
    1065             :                                     const char16_t *aSourceText)
    1066             : {
    1067           0 :     if (!mObserver) {
    1068           0 :         return;
    1069             :     }
    1070             : 
    1071           0 :     mTransformResult = aResult;
    1072             : 
    1073           0 :     if (aErrorText) {
    1074           0 :         mErrorText.Assign(aErrorText);
    1075             :     }
    1076             :     else {
    1077             :         nsCOMPtr<nsIStringBundleService> sbs =
    1078           0 :             mozilla::services::GetStringBundleService();
    1079           0 :         if (sbs) {
    1080           0 :             nsXPIDLString errorText;
    1081           0 :             sbs->FormatStatusMessage(aResult, EmptyString().get(),
    1082           0 :                                      getter_Copies(errorText));
    1083             : 
    1084           0 :             nsXPIDLString errorMessage;
    1085           0 :             nsCOMPtr<nsIStringBundle> bundle;
    1086           0 :             sbs->CreateBundle(XSLT_MSGS_URL, getter_AddRefs(bundle));
    1087             : 
    1088           0 :             if (bundle) {
    1089           0 :                 const char16_t* error[] = { errorText.get() };
    1090           0 :                 if (mStylesheet) {
    1091           0 :                     bundle->FormatStringFromName(u"TransformError",
    1092             :                                                  error, 1,
    1093           0 :                                                  getter_Copies(errorMessage));
    1094             :                 }
    1095             :                 else {
    1096           0 :                     bundle->FormatStringFromName(u"LoadingError",
    1097             :                                                  error, 1,
    1098           0 :                                                  getter_Copies(errorMessage));
    1099             :                 }
    1100             :             }
    1101           0 :             mErrorText.Assign(errorMessage);
    1102             :         }
    1103             :     }
    1104             : 
    1105           0 :     if (aSourceText) {
    1106           0 :         mSourceText.Assign(aSourceText);
    1107             :     }
    1108             : 
    1109           0 :     if (mSource) {
    1110           0 :         notifyError();
    1111             :     }
    1112             : }
    1113             : 
    1114             : void
    1115           0 : txMozillaXSLTProcessor::notifyError()
    1116             : {
    1117           0 :     nsCOMPtr<nsIDocument> document = do_CreateInstance(kXMLDocumentCID);
    1118           0 :     if (!document) {
    1119           0 :         return;
    1120             :     }
    1121             : 
    1122           0 :     URIUtils::ResetWithSource(document, mSource);
    1123             : 
    1124           0 :     MOZ_ASSERT(document->GetReadyStateEnum() ==
    1125             :                  nsIDocument::READYSTATE_UNINITIALIZED,
    1126             :                "Bad readyState.");
    1127           0 :     document->SetReadyStateInternal(nsIDocument::READYSTATE_LOADING);
    1128             : 
    1129           0 :     NS_NAMED_LITERAL_STRING(ns, "http://www.mozilla.org/newlayout/xml/parsererror.xml");
    1130             : 
    1131           0 :     IgnoredErrorResult rv;
    1132           0 :     ElementCreationOptionsOrString options;
    1133           0 :     options.SetAsString();
    1134             : 
    1135             :     nsCOMPtr<Element> element =
    1136           0 :         document->CreateElementNS(ns, NS_LITERAL_STRING("parsererror"),
    1137           0 :                                   options, rv);
    1138           0 :     if (rv.Failed()) {
    1139           0 :         return;
    1140             :     }
    1141             : 
    1142           0 :     document->AppendChild(*element, rv);
    1143           0 :     if (rv.Failed()) {
    1144           0 :         return;
    1145             :     }
    1146             : 
    1147           0 :     RefPtr<nsTextNode> text = document->CreateTextNode(mErrorText);
    1148             : 
    1149           0 :     element->AppendChild(*text, rv);
    1150           0 :     if (rv.Failed()) {
    1151           0 :         return;
    1152             :     }
    1153             : 
    1154           0 :     if (!mSourceText.IsEmpty()) {
    1155           0 :         ElementCreationOptionsOrString options;
    1156           0 :         options.SetAsString();
    1157             : 
    1158             :         nsCOMPtr<Element> sourceElement =
    1159           0 :             document->CreateElementNS(ns, NS_LITERAL_STRING("sourcetext"),
    1160           0 :                                       options, rv);
    1161           0 :         if (rv.Failed()) {
    1162           0 :             return;
    1163             :         }
    1164             : 
    1165           0 :         element->AppendChild(*sourceElement, rv);
    1166           0 :         if (rv.Failed()) {
    1167           0 :             return;
    1168             :         }
    1169             : 
    1170           0 :         text = document->CreateTextNode(mSourceText);
    1171             : 
    1172           0 :         sourceElement->AppendChild(*text, rv);
    1173           0 :         if (rv.Failed()) {
    1174           0 :             return;
    1175             :         }
    1176             :     }
    1177             : 
    1178           0 :     MOZ_ASSERT(document->GetReadyStateEnum() ==
    1179             :                  nsIDocument::READYSTATE_LOADING,
    1180             :                "Bad readyState.");
    1181           0 :     document->SetReadyStateInternal(nsIDocument::READYSTATE_INTERACTIVE);
    1182             : 
    1183           0 :     mObserver->OnTransformDone(mTransformResult, document);
    1184             : }
    1185             : 
    1186             : nsresult
    1187           0 : txMozillaXSLTProcessor::ensureStylesheet()
    1188             : {
    1189           0 :     if (mStylesheet) {
    1190           0 :         return NS_OK;
    1191             :     }
    1192             : 
    1193           0 :     NS_ENSURE_TRUE(mStylesheetDocument, NS_ERROR_NOT_INITIALIZED);
    1194             : 
    1195           0 :     nsINode* style = mEmbeddedStylesheetRoot;
    1196           0 :     if (!style) {
    1197           0 :         style = mStylesheetDocument;
    1198             :     }
    1199             : 
    1200           0 :     return TX_CompileStylesheet(style, this, getter_AddRefs(mStylesheet));
    1201             : }
    1202             : 
    1203             : void
    1204           0 : txMozillaXSLTProcessor::NodeWillBeDestroyed(const nsINode* aNode)
    1205             : {
    1206           0 :     nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
    1207           0 :     if (NS_FAILED(mCompileResult)) {
    1208           0 :         return;
    1209             :     }
    1210             : 
    1211           0 :     mCompileResult = ensureStylesheet();
    1212           0 :     mStylesheetDocument = nullptr;
    1213           0 :     mEmbeddedStylesheetRoot = nullptr;
    1214             : }
    1215             : 
    1216             : void
    1217           0 : txMozillaXSLTProcessor::CharacterDataChanged(nsIDocument* aDocument,
    1218             :                                              nsIContent *aContent,
    1219             :                                              CharacterDataChangeInfo* aInfo)
    1220             : {
    1221           0 :     mStylesheet = nullptr;
    1222           0 : }
    1223             : 
    1224             : void
    1225           0 : txMozillaXSLTProcessor::AttributeChanged(nsIDocument* aDocument,
    1226             :                                          Element* aElement,
    1227             :                                          int32_t aNameSpaceID,
    1228             :                                          nsIAtom* aAttribute,
    1229             :                                          int32_t aModType,
    1230             :                                          const nsAttrValue* aOldValue)
    1231             : {
    1232           0 :     mStylesheet = nullptr;
    1233           0 : }
    1234             : 
    1235             : void
    1236           0 : txMozillaXSLTProcessor::ContentAppended(nsIDocument* aDocument,
    1237             :                                         nsIContent* aContainer,
    1238             :                                         nsIContent* aFirstNewContent,
    1239             :                                         int32_t /* unused */)
    1240             : {
    1241           0 :     mStylesheet = nullptr;
    1242           0 : }
    1243             : 
    1244             : void
    1245           0 : txMozillaXSLTProcessor::ContentInserted(nsIDocument* aDocument,
    1246             :                                         nsIContent* aContainer,
    1247             :                                         nsIContent* aChild,
    1248             :                                         int32_t /* unused */)
    1249             : {
    1250           0 :     mStylesheet = nullptr;
    1251           0 : }
    1252             : 
    1253             : void
    1254           0 : txMozillaXSLTProcessor::ContentRemoved(nsIDocument* aDocument,
    1255             :                                        nsIContent* aContainer,
    1256             :                                        nsIContent* aChild,
    1257             :                                        int32_t aIndexInContainer,
    1258             :                                        nsIContent* aPreviousSibling)
    1259             : {
    1260           0 :     mStylesheet = nullptr;
    1261           0 : }
    1262             : 
    1263             : /* virtual */ JSObject*
    1264           0 : txMozillaXSLTProcessor::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
    1265             : {
    1266           0 :     return XSLTProcessorBinding::Wrap(aCx, this, aGivenProto);
    1267             : }
    1268             : 
    1269             : 
    1270             : /* static */ already_AddRefed<txMozillaXSLTProcessor>
    1271           0 : txMozillaXSLTProcessor::Constructor(const GlobalObject& aGlobal,
    1272             :                                     mozilla::ErrorResult& aRv)
    1273             : {
    1274             :     RefPtr<txMozillaXSLTProcessor> processor =
    1275           0 :         new txMozillaXSLTProcessor(aGlobal.GetAsSupports());
    1276           0 :     return processor.forget();
    1277             : }
    1278             : 
    1279             : void
    1280           0 : txMozillaXSLTProcessor::ImportStylesheet(nsINode& stylesheet,
    1281             :                                          mozilla::ErrorResult& aRv)
    1282             : {
    1283           0 :     aRv = ImportStylesheet(stylesheet.AsDOMNode());
    1284           0 : }
    1285             : 
    1286             : already_AddRefed<DocumentFragment>
    1287           0 : txMozillaXSLTProcessor::TransformToFragment(nsINode& source,
    1288             :                                             nsIDocument& docVal,
    1289             :                                             mozilla::ErrorResult& aRv)
    1290             : {
    1291           0 :     nsCOMPtr<nsIDOMDocumentFragment> fragment;
    1292           0 :     nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(&docVal);
    1293           0 :     if (!domDoc) {
    1294           0 :         aRv.Throw(NS_ERROR_FAILURE);
    1295           0 :         return nullptr;
    1296             :     }
    1297           0 :     aRv = TransformToFragment(source.AsDOMNode(), domDoc, getter_AddRefs(fragment));
    1298           0 :     return fragment.forget().downcast<DocumentFragment>();
    1299             : }
    1300             : 
    1301             : already_AddRefed<nsIDocument>
    1302           0 : txMozillaXSLTProcessor::TransformToDocument(nsINode& source,
    1303             :                                             mozilla::ErrorResult& aRv)
    1304             : {
    1305           0 :     nsCOMPtr<nsIDOMDocument> document;
    1306           0 :     aRv = TransformToDocument(source.AsDOMNode(), getter_AddRefs(document));
    1307           0 :     nsCOMPtr<nsIDocument> domDoc = do_QueryInterface(document);
    1308           0 :     return domDoc.forget();
    1309             : }
    1310             : 
    1311             : void
    1312           0 : txMozillaXSLTProcessor::SetParameter(JSContext* aCx,
    1313             :                                      const nsAString& aNamespaceURI,
    1314             :                                      const nsAString& aLocalName,
    1315             :                                      JS::Handle<JS::Value> aValue,
    1316             :                                      mozilla::ErrorResult& aRv)
    1317             : {
    1318           0 :     nsCOMPtr<nsIVariant> val;
    1319           0 :     aRv = nsContentUtils::XPConnect()->JSToVariant(aCx, aValue,
    1320           0 :                                                    getter_AddRefs(val));
    1321           0 :     if (aRv.Failed()) {
    1322           0 :         return;
    1323             :     }
    1324           0 :     aRv = SetParameter(aNamespaceURI, aLocalName, val);
    1325             : }
    1326             : 
    1327             : nsIVariant*
    1328           0 : txMozillaXSLTProcessor::GetParameter(const nsAString& aNamespaceURI,
    1329             :                                      const nsAString& aLocalName,
    1330             :                                      mozilla::ErrorResult& aRv)
    1331             : {
    1332           0 :     nsCOMPtr<nsIVariant> val;
    1333           0 :     aRv = GetParameter(aNamespaceURI, aLocalName, getter_AddRefs(val));
    1334           0 :     return val;
    1335             : }
    1336             : 
    1337             : /* static*/
    1338             : nsresult
    1339           3 : txMozillaXSLTProcessor::Startup()
    1340             : {
    1341           3 :     if (!txXSLTProcessor::init()) {
    1342           0 :         return NS_ERROR_OUT_OF_MEMORY;
    1343             :     }
    1344             : 
    1345             :     nsCOMPtr<nsIErrorService> errorService =
    1346           6 :         do_GetService(NS_ERRORSERVICE_CONTRACTID);
    1347           3 :     if (errorService) {
    1348           3 :         errorService->RegisterErrorStringBundle(NS_ERROR_MODULE_XSLT,
    1349           3 :                                                 XSLT_MSGS_URL);
    1350             :     }
    1351             : 
    1352           3 :     return NS_OK;
    1353             : }
    1354             : 
    1355             : /* static*/
    1356             : void
    1357           0 : txMozillaXSLTProcessor::Shutdown()
    1358             : {
    1359           0 :     txXSLTProcessor::shutdown();
    1360             : 
    1361             :     nsCOMPtr<nsIErrorService> errorService =
    1362           0 :         do_GetService(NS_ERRORSERVICE_CONTRACTID);
    1363           0 :     if (errorService) {
    1364           0 :         errorService->UnregisterErrorStringBundle(NS_ERROR_MODULE_XSLT);
    1365             :     }
    1366           0 : }
    1367             : 
    1368             : /* static*/
    1369             : nsresult
    1370           0 : txVariable::Convert(nsIVariant *aValue, txAExprResult** aResult)
    1371             : {
    1372           0 :     *aResult = nullptr;
    1373             : 
    1374             :     uint16_t dataType;
    1375           0 :     aValue->GetDataType(&dataType);
    1376           0 :     switch (dataType) {
    1377             :         // Number
    1378             :         case nsIDataType::VTYPE_INT8:
    1379             :         case nsIDataType::VTYPE_INT16:
    1380             :         case nsIDataType::VTYPE_INT32:
    1381             :         case nsIDataType::VTYPE_INT64:
    1382             :         case nsIDataType::VTYPE_UINT8:
    1383             :         case nsIDataType::VTYPE_UINT16:
    1384             :         case nsIDataType::VTYPE_UINT32:
    1385             :         case nsIDataType::VTYPE_UINT64:
    1386             :         case nsIDataType::VTYPE_FLOAT:
    1387             :         case nsIDataType::VTYPE_DOUBLE:
    1388             :         {
    1389             :             double value;
    1390           0 :             nsresult rv = aValue->GetAsDouble(&value);
    1391           0 :             NS_ENSURE_SUCCESS(rv, rv);
    1392             : 
    1393           0 :             *aResult = new NumberResult(value, nullptr);
    1394           0 :             NS_ADDREF(*aResult);
    1395             : 
    1396           0 :             return NS_OK;
    1397             :         }
    1398             : 
    1399             :         // Boolean
    1400             :         case nsIDataType::VTYPE_BOOL:
    1401             :         {
    1402             :             bool value;
    1403           0 :             nsresult rv = aValue->GetAsBool(&value);
    1404           0 :             NS_ENSURE_SUCCESS(rv, rv);
    1405             : 
    1406           0 :             *aResult = new BooleanResult(value);
    1407           0 :             NS_ADDREF(*aResult);
    1408             : 
    1409           0 :             return NS_OK;
    1410             :         }
    1411             : 
    1412             :         // String
    1413             :         case nsIDataType::VTYPE_CHAR:
    1414             :         case nsIDataType::VTYPE_WCHAR:
    1415             :         case nsIDataType::VTYPE_DOMSTRING:
    1416             :         case nsIDataType::VTYPE_CHAR_STR:
    1417             :         case nsIDataType::VTYPE_WCHAR_STR:
    1418             :         case nsIDataType::VTYPE_STRING_SIZE_IS:
    1419             :         case nsIDataType::VTYPE_WSTRING_SIZE_IS:
    1420             :         case nsIDataType::VTYPE_UTF8STRING:
    1421             :         case nsIDataType::VTYPE_CSTRING:
    1422             :         case nsIDataType::VTYPE_ASTRING:
    1423             :         {
    1424           0 :             nsAutoString value;
    1425           0 :             nsresult rv = aValue->GetAsAString(value);
    1426           0 :             NS_ENSURE_SUCCESS(rv, rv);
    1427             : 
    1428           0 :             *aResult = new StringResult(value, nullptr);
    1429           0 :             NS_ADDREF(*aResult);
    1430             : 
    1431           0 :             return NS_OK;
    1432             :         }
    1433             : 
    1434             :         // Nodeset
    1435             :         case nsIDataType::VTYPE_INTERFACE:
    1436             :         case nsIDataType::VTYPE_INTERFACE_IS:
    1437             :         {
    1438           0 :             nsCOMPtr<nsISupports> supports;
    1439           0 :             nsresult rv = aValue->GetAsISupports(getter_AddRefs(supports));
    1440           0 :             NS_ENSURE_SUCCESS(rv, rv);
    1441             : 
    1442           0 :             nsCOMPtr<nsIDOMNode> node = do_QueryInterface(supports);
    1443           0 :             if (node) {
    1444           0 :                 nsAutoPtr<txXPathNode> xpathNode(txXPathNativeNode::createXPathNode(node));
    1445           0 :                 if (!xpathNode) {
    1446           0 :                     return NS_ERROR_FAILURE;
    1447             :                 }
    1448             : 
    1449           0 :                 *aResult = new txNodeSet(*xpathNode, nullptr);
    1450           0 :                 if (!*aResult) {
    1451           0 :                     return NS_ERROR_OUT_OF_MEMORY;
    1452             :                 }
    1453             : 
    1454           0 :                 NS_ADDREF(*aResult);
    1455             : 
    1456           0 :                 return NS_OK;
    1457             :             }
    1458             : 
    1459           0 :             nsCOMPtr<nsIXPathResult> xpathResult = do_QueryInterface(supports);
    1460           0 :             if (xpathResult) {
    1461           0 :                 return xpathResult->GetExprResult(aResult);
    1462             :             }
    1463             : 
    1464           0 :             nsCOMPtr<nsIDOMNodeList> nodeList = do_QueryInterface(supports);
    1465           0 :             if (nodeList) {
    1466           0 :                 RefPtr<txNodeSet> nodeSet = new txNodeSet(nullptr);
    1467           0 :                 if (!nodeSet) {
    1468           0 :                     return NS_ERROR_OUT_OF_MEMORY;
    1469             :                 }
    1470             : 
    1471             :                 uint32_t length;
    1472           0 :                 nodeList->GetLength(&length);
    1473             : 
    1474           0 :                 nsCOMPtr<nsIDOMNode> node;
    1475             :                 uint32_t i;
    1476           0 :                 for (i = 0; i < length; ++i) {
    1477           0 :                     nodeList->Item(i, getter_AddRefs(node));
    1478             : 
    1479             :                     nsAutoPtr<txXPathNode> xpathNode(
    1480           0 :                         txXPathNativeNode::createXPathNode(node));
    1481           0 :                     if (!xpathNode) {
    1482           0 :                         return NS_ERROR_FAILURE;
    1483             :                     }
    1484             : 
    1485           0 :                     nodeSet->add(*xpathNode);
    1486             :                 }
    1487             : 
    1488           0 :                 NS_ADDREF(*aResult = nodeSet);
    1489             : 
    1490           0 :                 return NS_OK;
    1491             :             }
    1492             : 
    1493             :             // Convert random JS Objects to a string.
    1494             :             nsCOMPtr<nsIXPConnectJSObjectHolder> holder =
    1495           0 :                 do_QueryInterface(supports);
    1496           0 :             if (holder) {
    1497           0 :                 JSContext* cx = nsContentUtils::GetCurrentJSContext();
    1498           0 :                 NS_ENSURE_TRUE(cx, NS_ERROR_NOT_AVAILABLE);
    1499             : 
    1500           0 :                 JS::Rooted<JSObject*> jsobj(cx, holder->GetJSObject());
    1501           0 :                 NS_ENSURE_STATE(jsobj);
    1502             : 
    1503           0 :                 JS::Rooted<JS::Value> v(cx, JS::ObjectValue(*jsobj));
    1504           0 :                 JS::Rooted<JSString*> str(cx, JS::ToString(cx, v));
    1505           0 :                 NS_ENSURE_TRUE(str, NS_ERROR_FAILURE);
    1506             : 
    1507           0 :                 nsAutoJSString value;
    1508           0 :                 NS_ENSURE_TRUE(value.init(cx, str), NS_ERROR_FAILURE);
    1509             : 
    1510           0 :                 *aResult = new StringResult(value, nullptr);
    1511           0 :                 NS_ADDREF(*aResult);
    1512             : 
    1513           0 :                 return NS_OK;
    1514             :             }
    1515             : 
    1516           0 :             break;
    1517             :         }
    1518             : 
    1519             :         case nsIDataType::VTYPE_ARRAY:
    1520             :         {
    1521             :             uint16_t type;
    1522             :             nsIID iid;
    1523             :             uint32_t count;
    1524             :             void* array;
    1525           0 :             nsresult rv = aValue->GetAsArray(&type, &iid, &count, &array);
    1526           0 :             NS_ENSURE_SUCCESS(rv, rv);
    1527             : 
    1528           0 :             NS_ASSERTION(type == nsIDataType::VTYPE_INTERFACE ||
    1529             :                          type == nsIDataType::VTYPE_INTERFACE_IS,
    1530             :                          "Huh, we checked this in SetParameter?");
    1531             : 
    1532           0 :             nsISupports** values = static_cast<nsISupports**>(array);
    1533             : 
    1534           0 :             RefPtr<txNodeSet> nodeSet = new txNodeSet(nullptr);
    1535           0 :             if (!nodeSet) {
    1536           0 :                 NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(count, values);
    1537             : 
    1538           0 :                 return NS_ERROR_OUT_OF_MEMORY;
    1539             :             }
    1540             : 
    1541             :             uint32_t i;
    1542           0 :             for (i = 0; i < count; ++i) {
    1543           0 :                 nsISupports *supports = values[i];
    1544           0 :                 nsCOMPtr<nsIDOMNode> node = do_QueryInterface(supports);
    1545           0 :                 NS_ASSERTION(node, "Huh, we checked this in SetParameter?");
    1546             : 
    1547             :                 nsAutoPtr<txXPathNode> xpathNode(
    1548           0 :                     txXPathNativeNode::createXPathNode(node));
    1549           0 :                 if (!xpathNode) {
    1550           0 :                     while (i < count) {
    1551           0 :                         NS_RELEASE(values[i]);
    1552           0 :                         ++i;
    1553             :                     }
    1554           0 :                     free(array);
    1555             : 
    1556           0 :                     return NS_ERROR_FAILURE;
    1557             :                 }
    1558             : 
    1559           0 :                 nodeSet->add(*xpathNode);
    1560             : 
    1561           0 :                 NS_RELEASE(supports);
    1562             :             }
    1563             : 
    1564           0 :             free(array);
    1565             : 
    1566           0 :             NS_ADDREF(*aResult = nodeSet);
    1567             : 
    1568           0 :             return NS_OK;
    1569             :         }
    1570             :     }
    1571             : 
    1572           0 :     return NS_ERROR_ILLEGAL_VALUE;
    1573             : }

Generated by: LCOV version 1.13