LCOV - code coverage report
Current view: top level - dom/xslt/xslt - txMozillaStylesheetCompiler.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 311 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 43 0.0 %
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 "nsCOMArray.h"
       7             : #include "nsIAuthPrompt.h"
       8             : #include "nsIDOMNode.h"
       9             : #include "nsIDOMDocument.h"
      10             : #include "nsIDocument.h"
      11             : #include "nsIExpatSink.h"
      12             : #include "nsIChannelEventSink.h"
      13             : #include "nsIInterfaceRequestor.h"
      14             : #include "nsILoadGroup.h"
      15             : #include "nsIParser.h"
      16             : #include "nsCharsetSource.h"
      17             : #include "nsIRequestObserver.h"
      18             : #include "nsIScriptSecurityManager.h"
      19             : #include "nsContentPolicyUtils.h"
      20             : #include "nsIStreamConverterService.h"
      21             : #include "nsSyncLoadService.h"
      22             : #include "nsIURI.h"
      23             : #include "nsIPrincipal.h"
      24             : #include "nsIWindowWatcher.h"
      25             : #include "nsIXMLContentSink.h"
      26             : #include "nsMimeTypes.h"
      27             : #include "nsNetUtil.h"
      28             : #include "nsParserCIID.h"
      29             : #include "nsGkAtoms.h"
      30             : #include "txLog.h"
      31             : #include "txMozillaXSLTProcessor.h"
      32             : #include "txStylesheetCompiler.h"
      33             : #include "txXMLUtils.h"
      34             : #include "nsAttrName.h"
      35             : #include "nsIScriptError.h"
      36             : #include "nsIURL.h"
      37             : #include "nsError.h"
      38             : #include "mozilla/Attributes.h"
      39             : #include "mozilla/dom/Element.h"
      40             : #include "mozilla/Encoding.h"
      41             : #include "mozilla/UniquePtr.h"
      42             : 
      43             : using namespace mozilla;
      44             : using mozilla::net::ReferrerPolicy;
      45             : 
      46             : static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
      47             : 
      48             : static void
      49           0 : getSpec(nsIChannel* aChannel, nsAString& aSpec)
      50             : {
      51           0 :     if (!aChannel) {
      52           0 :         return;
      53             :     }
      54             : 
      55           0 :     nsCOMPtr<nsIURI> uri;
      56           0 :     aChannel->GetOriginalURI(getter_AddRefs(uri));
      57           0 :     if (!uri) {
      58           0 :         return;
      59             :     }
      60             : 
      61           0 :     nsAutoCString spec;
      62           0 :     uri->GetSpec(spec);
      63           0 :     AppendUTF8toUTF16(spec, aSpec);
      64             : }
      65             : 
      66             : class txStylesheetSink final : public nsIXMLContentSink,
      67             :                                public nsIExpatSink,
      68             :                                public nsIStreamListener,
      69             :                                public nsIInterfaceRequestor
      70             : {
      71             : public:
      72             :     txStylesheetSink(txStylesheetCompiler* aCompiler, nsIParser* aParser);
      73             : 
      74             :     NS_DECL_ISUPPORTS
      75             :     NS_DECL_NSIEXPATSINK
      76             :     NS_DECL_NSISTREAMLISTENER
      77             :     NS_DECL_NSIREQUESTOBSERVER
      78             :     NS_DECL_NSIINTERFACEREQUESTOR
      79             : 
      80             :     // nsIContentSink
      81           0 :     NS_IMETHOD WillParse(void) override { return NS_OK; }
      82             :     NS_IMETHOD DidBuildModel(bool aTerminated) override;
      83           0 :     NS_IMETHOD WillInterrupt(void) override { return NS_OK; }
      84           0 :     NS_IMETHOD WillResume(void) override { return NS_OK; }
      85           0 :     NS_IMETHOD SetParser(nsParserBase* aParser) override { return NS_OK; }
      86           0 :     virtual void FlushPendingNotifications(mozilla::FlushType aType) override { }
      87           0 :     virtual void SetDocumentCharset(NotNull<const Encoding*> aEncoding)
      88           0 :       override { }
      89           0 :     virtual nsISupports *GetTarget() override { return nullptr; }
      90             : 
      91             : private:
      92             :     RefPtr<txStylesheetCompiler> mCompiler;
      93             :     nsCOMPtr<nsIStreamListener>    mListener;
      94             :     nsCOMPtr<nsIParser>            mParser;
      95             :     bool mCheckedForXML;
      96             : 
      97             : protected:
      98           0 :     ~txStylesheetSink() {}
      99             : 
     100             :     // This exists solely to suppress a warning from nsDerivedSafe
     101             :     txStylesheetSink();
     102             : };
     103             : 
     104           0 : txStylesheetSink::txStylesheetSink(txStylesheetCompiler* aCompiler,
     105           0 :                                    nsIParser* aParser)
     106             :     : mCompiler(aCompiler)
     107             :     , mParser(aParser)
     108           0 :     , mCheckedForXML(false)
     109             : {
     110           0 :     mListener = do_QueryInterface(aParser);
     111           0 : }
     112             : 
     113           0 : NS_IMPL_ISUPPORTS(txStylesheetSink,
     114             :                   nsIXMLContentSink,
     115             :                   nsIContentSink,
     116             :                   nsIExpatSink,
     117             :                   nsIStreamListener,
     118             :                   nsIRequestObserver,
     119             :                   nsIInterfaceRequestor)
     120             : 
     121             : NS_IMETHODIMP
     122           0 : txStylesheetSink::HandleStartElement(const char16_t *aName,
     123             :                                      const char16_t **aAtts,
     124             :                                      uint32_t aAttsCount,
     125             :                                      uint32_t aLineNumber)
     126             : {
     127           0 :     NS_PRECONDITION(aAttsCount % 2 == 0, "incorrect aAttsCount");
     128             : 
     129             :     nsresult rv =
     130           0 :         mCompiler->startElement(aName, aAtts, aAttsCount / 2);
     131           0 :     if (NS_FAILED(rv)) {
     132           0 :         mCompiler->cancel(rv);
     133             : 
     134           0 :         return rv;
     135             :     }
     136             : 
     137           0 :     return NS_OK;
     138             : }
     139             : 
     140             : NS_IMETHODIMP
     141           0 : txStylesheetSink::HandleEndElement(const char16_t *aName)
     142             : {
     143           0 :     nsresult rv = mCompiler->endElement();
     144           0 :     if (NS_FAILED(rv)) {
     145           0 :         mCompiler->cancel(rv);
     146             : 
     147           0 :         return rv;
     148             :     }
     149             : 
     150           0 :     return NS_OK;
     151             : }
     152             : 
     153             : NS_IMETHODIMP
     154           0 : txStylesheetSink::HandleComment(const char16_t *aName)
     155             : {
     156           0 :     return NS_OK;
     157             : }
     158             : 
     159             : NS_IMETHODIMP
     160           0 : txStylesheetSink::HandleCDataSection(const char16_t *aData,
     161             :                                      uint32_t aLength)
     162             : {
     163           0 :     return HandleCharacterData(aData, aLength);
     164             : }
     165             : 
     166             : NS_IMETHODIMP
     167           0 : txStylesheetSink::HandleDoctypeDecl(const nsAString & aSubset,
     168             :                                     const nsAString & aName,
     169             :                                     const nsAString & aSystemId,
     170             :                                     const nsAString & aPublicId,
     171             :                                     nsISupports *aCatalogData)
     172             : {
     173           0 :     return NS_OK;
     174             : }
     175             : 
     176             : NS_IMETHODIMP
     177           0 : txStylesheetSink::HandleCharacterData(const char16_t *aData,
     178             :                                       uint32_t aLength)
     179             : {
     180           0 :     nsresult rv = mCompiler->characters(Substring(aData, aData + aLength));
     181           0 :     if (NS_FAILED(rv)) {
     182           0 :         mCompiler->cancel(rv);
     183           0 :         return rv;
     184             :     }
     185             : 
     186           0 :     return NS_OK;
     187             : }
     188             : 
     189             : NS_IMETHODIMP
     190           0 : txStylesheetSink::HandleProcessingInstruction(const char16_t *aTarget,
     191             :                                               const char16_t *aData)
     192             : {
     193           0 :     return NS_OK;
     194             : }
     195             : 
     196             : NS_IMETHODIMP
     197           0 : txStylesheetSink::HandleXMLDeclaration(const char16_t *aVersion,
     198             :                                        const char16_t *aEncoding,
     199             :                                        int32_t aStandalone)
     200             : {
     201           0 :     return NS_OK;
     202             : }
     203             : 
     204             : NS_IMETHODIMP
     205           0 : txStylesheetSink::ReportError(const char16_t *aErrorText,
     206             :                               const char16_t *aSourceText,
     207             :                               nsIScriptError *aError,
     208             :                               bool *_retval)
     209             : {
     210           0 :     NS_PRECONDITION(aError && aSourceText && aErrorText, "Check arguments!!!");
     211             : 
     212             :     // The expat driver should report the error.
     213           0 :     *_retval = true;
     214             : 
     215           0 :     mCompiler->cancel(NS_ERROR_FAILURE, aErrorText, aSourceText);
     216             : 
     217           0 :     return NS_OK;
     218             : }
     219             : 
     220             : NS_IMETHODIMP
     221           0 : txStylesheetSink::DidBuildModel(bool aTerminated)
     222             : {
     223           0 :     return mCompiler->doneLoading();
     224             : }
     225             : 
     226             : NS_IMETHODIMP
     227           0 : txStylesheetSink::OnDataAvailable(nsIRequest *aRequest, nsISupports *aContext,
     228             :                                   nsIInputStream *aInputStream,
     229             :                                   uint64_t aOffset, uint32_t aCount)
     230             : {
     231           0 :     if (!mCheckedForXML) {
     232           0 :         nsCOMPtr<nsIDTD> dtd;
     233           0 :         mParser->GetDTD(getter_AddRefs(dtd));
     234           0 :         if (dtd) {
     235           0 :             mCheckedForXML = true;
     236           0 :             if (!(dtd->GetType() & NS_IPARSER_FLAG_XML)) {
     237           0 :                 nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
     238           0 :                 nsAutoString spec;
     239           0 :                 getSpec(channel, spec);
     240           0 :                 mCompiler->cancel(NS_ERROR_XSLT_WRONG_MIME_TYPE, nullptr,
     241           0 :                                   spec.get());
     242             : 
     243           0 :                 return NS_ERROR_XSLT_WRONG_MIME_TYPE;
     244             :             }
     245             :         }
     246             :     }
     247             : 
     248           0 :     return mListener->OnDataAvailable(aRequest, mParser, aInputStream,
     249           0 :                                       aOffset, aCount);
     250             : }
     251             : 
     252             : NS_IMETHODIMP
     253           0 : txStylesheetSink::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
     254             : {
     255           0 :     int32_t charsetSource = kCharsetFromDocTypeDefault;
     256             : 
     257           0 :     nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
     258             : 
     259             :     // check channel's charset...
     260           0 :     const Encoding* encoding = nullptr;
     261           0 :     nsAutoCString charsetVal;
     262           0 :     if (NS_SUCCEEDED(channel->GetContentCharset(charsetVal))) {
     263           0 :         encoding = Encoding::ForLabel(charsetVal);
     264           0 :         if (encoding) {
     265           0 :             charsetSource = kCharsetFromChannel;
     266             :         }
     267             :     }
     268             : 
     269           0 :     if (!encoding) {
     270           0 :         encoding = UTF_8_ENCODING;
     271             :     }
     272             : 
     273           0 :     mParser->SetDocumentCharset(WrapNotNull(encoding), charsetSource);
     274             : 
     275           0 :     nsAutoCString contentType;
     276           0 :     channel->GetContentType(contentType);
     277             : 
     278             :     // Time to sniff! Note: this should go away once file channels do
     279             :     // sniffing themselves.
     280           0 :     nsCOMPtr<nsIURI> uri;
     281           0 :     channel->GetURI(getter_AddRefs(uri));
     282             :     bool sniff;
     283           0 :     if (NS_SUCCEEDED(uri->SchemeIs("file", &sniff)) && sniff &&
     284           0 :         contentType.Equals(UNKNOWN_CONTENT_TYPE)) {
     285             :         nsresult rv;
     286             :         nsCOMPtr<nsIStreamConverterService> serv =
     287           0 :             do_GetService("@mozilla.org/streamConverters;1", &rv);
     288           0 :         if (NS_SUCCEEDED(rv)) {
     289           0 :             nsCOMPtr<nsIStreamListener> converter;
     290           0 :             rv = serv->AsyncConvertData(UNKNOWN_CONTENT_TYPE,
     291             :                                         "*/*",
     292             :                                         mListener,
     293             :                                         mParser,
     294           0 :                                         getter_AddRefs(converter));
     295           0 :             if (NS_SUCCEEDED(rv)) {
     296           0 :                 mListener = converter;
     297             :             }
     298             :         }
     299             :     }
     300             : 
     301           0 :     return mListener->OnStartRequest(aRequest, mParser);
     302             : }
     303             : 
     304             : NS_IMETHODIMP
     305           0 : txStylesheetSink::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext,
     306             :                                 nsresult aStatusCode)
     307             : {
     308           0 :     bool success = true;
     309             : 
     310           0 :     nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aRequest);
     311           0 :     if (httpChannel) {
     312           0 :         Unused << httpChannel->GetRequestSucceeded(&success);
     313             :     }
     314             : 
     315           0 :     nsresult result = aStatusCode;
     316           0 :     if (!success) {
     317             :         // XXX We sometimes want to use aStatusCode here, but the parser resets
     318             :         //     it to NS_ERROR_NOINTERFACE because we don't implement
     319             :         //     nsIHTMLContentSink.
     320           0 :         result = NS_ERROR_XSLT_NETWORK_ERROR;
     321             :     }
     322           0 :     else if (!mCheckedForXML) {
     323           0 :         nsCOMPtr<nsIDTD> dtd;
     324           0 :         mParser->GetDTD(getter_AddRefs(dtd));
     325           0 :         if (dtd && !(dtd->GetType() & NS_IPARSER_FLAG_XML)) {
     326           0 :             result = NS_ERROR_XSLT_WRONG_MIME_TYPE;
     327             :         }
     328             :     }
     329             : 
     330           0 :     if (NS_FAILED(result)) {
     331           0 :         nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
     332           0 :         nsAutoString spec;
     333           0 :         getSpec(channel, spec);
     334           0 :         mCompiler->cancel(result, nullptr, spec.get());
     335             :     }
     336             : 
     337           0 :     nsresult rv = mListener->OnStopRequest(aRequest, mParser, aStatusCode);
     338           0 :     mListener = nullptr;
     339           0 :     mParser = nullptr;
     340           0 :     return rv;
     341             : }
     342             : 
     343             : NS_IMETHODIMP
     344           0 : txStylesheetSink::GetInterface(const nsIID& aIID, void** aResult)
     345             : {
     346           0 :     if (aIID.Equals(NS_GET_IID(nsIAuthPrompt))) {
     347           0 :         NS_ENSURE_ARG(aResult);
     348           0 :         *aResult = nullptr;
     349             : 
     350             :         nsresult rv;
     351             :         nsCOMPtr<nsIWindowWatcher> wwatcher =
     352           0 :             do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
     353           0 :         NS_ENSURE_SUCCESS(rv, rv);
     354             : 
     355           0 :         nsCOMPtr<nsIAuthPrompt> prompt;
     356           0 :         rv = wwatcher->GetNewAuthPrompter(nullptr, getter_AddRefs(prompt));
     357           0 :         NS_ENSURE_SUCCESS(rv, rv);
     358             : 
     359           0 :         prompt.forget(aResult);
     360             : 
     361           0 :         return NS_OK;
     362             :     }
     363             : 
     364           0 :     return NS_ERROR_NO_INTERFACE;
     365             : }
     366             : 
     367             : class txCompileObserver final : public txACompileObserver
     368             : {
     369             : public:
     370             :     txCompileObserver(txMozillaXSLTProcessor* aProcessor,
     371             :                       nsIDocument* aLoaderDocument);
     372             : 
     373             :     TX_DECL_ACOMPILEOBSERVER
     374           0 :     NS_INLINE_DECL_REFCOUNTING(txCompileObserver)
     375             : 
     376             :     nsresult startLoad(nsIURI* aUri, txStylesheetCompiler* aCompiler,
     377             :                        nsIPrincipal* aSourcePrincipal,
     378             :                        ReferrerPolicy aReferrerPolicy);
     379             : 
     380             : private:
     381             :     RefPtr<txMozillaXSLTProcessor> mProcessor;
     382             :     nsCOMPtr<nsIDocument> mLoaderDocument;
     383             : 
     384             :     // This exists solely to suppress a warning from nsDerivedSafe
     385             :     txCompileObserver();
     386             : 
     387             :     // Private destructor, to discourage deletion outside of Release():
     388           0 :     ~txCompileObserver()
     389           0 :     {
     390           0 :     }
     391             : };
     392             : 
     393           0 : txCompileObserver::txCompileObserver(txMozillaXSLTProcessor* aProcessor,
     394           0 :                                      nsIDocument* aLoaderDocument)
     395             :     : mProcessor(aProcessor),
     396           0 :       mLoaderDocument(aLoaderDocument)
     397             : {
     398           0 : }
     399             : 
     400             : nsresult
     401           0 : txCompileObserver::loadURI(const nsAString& aUri,
     402             :                            const nsAString& aReferrerUri,
     403             :                            ReferrerPolicy aReferrerPolicy,
     404             :                            txStylesheetCompiler* aCompiler)
     405             : {
     406           0 :     if (mProcessor->IsLoadDisabled()) {
     407           0 :         return NS_ERROR_XSLT_LOAD_BLOCKED_ERROR;
     408             :     }
     409             : 
     410           0 :     nsCOMPtr<nsIURI> uri;
     411           0 :     nsresult rv = NS_NewURI(getter_AddRefs(uri), aUri);
     412           0 :     NS_ENSURE_SUCCESS(rv, rv);
     413             : 
     414           0 :     nsCOMPtr<nsIURI> referrerUri;
     415           0 :     rv = NS_NewURI(getter_AddRefs(referrerUri), aReferrerUri);
     416           0 :     NS_ENSURE_SUCCESS(rv, rv);
     417             : 
     418           0 :     OriginAttributes attrs;
     419             :     nsCOMPtr<nsIPrincipal> referrerPrincipal =
     420           0 :       BasePrincipal::CreateCodebasePrincipal(referrerUri, attrs);
     421           0 :     NS_ENSURE_TRUE(referrerPrincipal, NS_ERROR_FAILURE);
     422             : 
     423           0 :     return startLoad(uri, aCompiler, referrerPrincipal, aReferrerPolicy);
     424             : }
     425             : 
     426             : void
     427           0 : txCompileObserver::onDoneCompiling(txStylesheetCompiler* aCompiler,
     428             :                                    nsresult aResult,
     429             :                                    const char16_t *aErrorText,
     430             :                                    const char16_t *aParam)
     431             : {
     432           0 :     if (NS_SUCCEEDED(aResult)) {
     433           0 :         mProcessor->setStylesheet(aCompiler->getStylesheet());
     434             :     }
     435             :     else {
     436           0 :         mProcessor->reportError(aResult, aErrorText, aParam);
     437             :     }
     438           0 : }
     439             : 
     440             : nsresult
     441           0 : txCompileObserver::startLoad(nsIURI* aUri, txStylesheetCompiler* aCompiler,
     442             :                              nsIPrincipal* aReferrerPrincipal,
     443             :                              ReferrerPolicy aReferrerPolicy)
     444             : {
     445           0 :     nsCOMPtr<nsILoadGroup> loadGroup = mLoaderDocument->GetDocumentLoadGroup();
     446           0 :     if (!loadGroup) {
     447           0 :         return NS_ERROR_FAILURE;
     448             :     }
     449             : 
     450           0 :     nsCOMPtr<nsIChannel> channel;
     451           0 :     nsresult rv = NS_NewChannelWithTriggeringPrincipal(
     452           0 :                     getter_AddRefs(channel),
     453             :                     aUri,
     454             :                     mLoaderDocument,
     455             :                     aReferrerPrincipal, // triggeringPrincipal
     456             :                     nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS,
     457             :                     nsIContentPolicy::TYPE_XSLT,
     458           0 :                     loadGroup);
     459             : 
     460           0 :     NS_ENSURE_SUCCESS(rv, rv);
     461             : 
     462           0 :     channel->SetContentType(NS_LITERAL_CSTRING("text/xml"));
     463             : 
     464           0 :     nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
     465           0 :     if (httpChannel) {
     466           0 :         DebugOnly<nsresult> rv;
     467           0 :         rv = httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
     468           0 :                                            NS_LITERAL_CSTRING("*/*"),
     469           0 :                                            false);
     470           0 :         MOZ_ASSERT(NS_SUCCEEDED(rv));
     471             : 
     472           0 :         nsCOMPtr<nsIURI> referrerURI;
     473           0 :         aReferrerPrincipal->GetURI(getter_AddRefs(referrerURI));
     474           0 :         if (referrerURI) {
     475           0 :             rv = httpChannel->SetReferrerWithPolicy(referrerURI, aReferrerPolicy);
     476           0 :             MOZ_ASSERT(NS_SUCCEEDED(rv));
     477             :         }
     478             :     }
     479             : 
     480           0 :     nsCOMPtr<nsIParser> parser = do_CreateInstance(kCParserCID, &rv);
     481           0 :     NS_ENSURE_SUCCESS(rv, rv);
     482             : 
     483           0 :     RefPtr<txStylesheetSink> sink = new txStylesheetSink(aCompiler, parser);
     484           0 :     NS_ENSURE_TRUE(sink, NS_ERROR_OUT_OF_MEMORY);
     485             : 
     486           0 :     channel->SetNotificationCallbacks(sink);
     487             : 
     488           0 :     parser->SetCommand(kLoadAsData);
     489           0 :     parser->SetContentSink(sink);
     490           0 :     parser->Parse(aUri);
     491             : 
     492           0 :     return channel->AsyncOpen2(sink);
     493             : }
     494             : 
     495             : nsresult
     496           0 : TX_LoadSheet(nsIURI* aUri, txMozillaXSLTProcessor* aProcessor,
     497             :              nsIDocument* aLoaderDocument, ReferrerPolicy aReferrerPolicy)
     498             : {
     499           0 :     nsIPrincipal* principal = aLoaderDocument->NodePrincipal();
     500             : 
     501           0 :     nsAutoCString spec;
     502           0 :     aUri->GetSpec(spec);
     503           0 :     MOZ_LOG(txLog::xslt, LogLevel::Info, ("TX_LoadSheet: %s\n", spec.get()));
     504             : 
     505             :     RefPtr<txCompileObserver> observer =
     506           0 :         new txCompileObserver(aProcessor, aLoaderDocument);
     507           0 :     NS_ENSURE_TRUE(observer, NS_ERROR_OUT_OF_MEMORY);
     508             : 
     509             :     RefPtr<txStylesheetCompiler> compiler =
     510           0 :         new txStylesheetCompiler(NS_ConvertUTF8toUTF16(spec), aReferrerPolicy,
     511           0 :                                  observer);
     512           0 :     NS_ENSURE_TRUE(compiler, NS_ERROR_OUT_OF_MEMORY);
     513             : 
     514           0 :     return observer->startLoad(aUri, compiler, principal, aReferrerPolicy);
     515             : }
     516             : 
     517             : /**
     518             :  * handling DOM->txStylesheet
     519             :  * Observer needs to do synchronous loads.
     520             :  */
     521             : static nsresult
     522           0 : handleNode(nsINode* aNode, txStylesheetCompiler* aCompiler)
     523             : {
     524           0 :     nsresult rv = NS_OK;
     525             : 
     526           0 :     if (aNode->IsElement()) {
     527           0 :         dom::Element* element = aNode->AsElement();
     528             : 
     529           0 :         uint32_t attsCount = element->GetAttrCount();
     530           0 :         UniquePtr<txStylesheetAttr[]> atts;
     531           0 :         if (attsCount > 0) {
     532           0 :             atts = MakeUnique<txStylesheetAttr[]>(attsCount);
     533             :             uint32_t counter;
     534           0 :             for (counter = 0; counter < attsCount; ++counter) {
     535           0 :                 txStylesheetAttr& att = atts[counter];
     536           0 :                 const nsAttrName* name = element->GetAttrNameAt(counter);
     537           0 :                 att.mNamespaceID = name->NamespaceID();
     538           0 :                 att.mLocalName = name->LocalName();
     539           0 :                 att.mPrefix = name->GetPrefix();
     540           0 :                 element->GetAttr(att.mNamespaceID, att.mLocalName, att.mValue);
     541             :             }
     542             :         }
     543             : 
     544           0 :         mozilla::dom::NodeInfo *ni = element->NodeInfo();
     545             : 
     546           0 :         rv = aCompiler->startElement(ni->NamespaceID(),
     547             :                                      ni->NameAtom(),
     548             :                                      ni->GetPrefixAtom(), atts.get(),
     549           0 :                                      attsCount);
     550           0 :         NS_ENSURE_SUCCESS(rv, rv);
     551             : 
     552             :         // explicitly destroy the attrs here since we no longer need it
     553           0 :         atts = nullptr;
     554             : 
     555           0 :         for (nsIContent* child = element->GetFirstChild();
     556           0 :              child;
     557           0 :              child = child->GetNextSibling()) {
     558             : 
     559           0 :             rv = handleNode(child, aCompiler);
     560           0 :             NS_ENSURE_SUCCESS(rv, rv);
     561             :         }
     562             : 
     563           0 :         rv = aCompiler->endElement();
     564           0 :         NS_ENSURE_SUCCESS(rv, rv);
     565             :     }
     566           0 :     else if (aNode->IsNodeOfType(nsINode::eTEXT)) {
     567           0 :         nsAutoString chars;
     568           0 :         static_cast<nsIContent*>(aNode)->AppendTextTo(chars);
     569           0 :         rv = aCompiler->characters(chars);
     570           0 :         NS_ENSURE_SUCCESS(rv, rv);
     571             :     }
     572           0 :     else if (aNode->IsNodeOfType(nsINode::eDOCUMENT)) {
     573           0 :         for (nsIContent* child = aNode->GetFirstChild();
     574           0 :              child;
     575           0 :              child = child->GetNextSibling()) {
     576             : 
     577           0 :             rv = handleNode(child, aCompiler);
     578           0 :             NS_ENSURE_SUCCESS(rv, rv);
     579             :         }
     580             :     }
     581             : 
     582           0 :     return NS_OK;
     583             : }
     584             : 
     585             : class txSyncCompileObserver final : public txACompileObserver
     586             : {
     587             : public:
     588             :     explicit txSyncCompileObserver(txMozillaXSLTProcessor* aProcessor);
     589             : 
     590             :     TX_DECL_ACOMPILEOBSERVER
     591           0 :     NS_INLINE_DECL_REFCOUNTING(txSyncCompileObserver)
     592             : 
     593             : private:
     594             :     // Private destructor, to discourage deletion outside of Release():
     595           0 :     ~txSyncCompileObserver()
     596           0 :     {
     597           0 :     }
     598             : 
     599             :     RefPtr<txMozillaXSLTProcessor> mProcessor;
     600             : };
     601             : 
     602           0 : txSyncCompileObserver::txSyncCompileObserver(txMozillaXSLTProcessor* aProcessor)
     603           0 :   : mProcessor(aProcessor)
     604             : {
     605           0 : }
     606             : 
     607             : nsresult
     608           0 : txSyncCompileObserver::loadURI(const nsAString& aUri,
     609             :                                const nsAString& aReferrerUri,
     610             :                                ReferrerPolicy aReferrerPolicy,
     611             :                                txStylesheetCompiler* aCompiler)
     612             : {
     613           0 :     if (mProcessor->IsLoadDisabled()) {
     614           0 :         return NS_ERROR_XSLT_LOAD_BLOCKED_ERROR;
     615             :     }
     616             : 
     617           0 :     nsCOMPtr<nsIURI> uri;
     618           0 :     nsresult rv = NS_NewURI(getter_AddRefs(uri), aUri);
     619           0 :     NS_ENSURE_SUCCESS(rv, rv);
     620             : 
     621           0 :     nsCOMPtr<nsIURI> referrerUri;
     622           0 :     rv = NS_NewURI(getter_AddRefs(referrerUri), aReferrerUri);
     623           0 :     NS_ENSURE_SUCCESS(rv, rv);
     624             : 
     625             :     nsCOMPtr<nsIPrincipal> referrerPrincipal =
     626           0 :       BasePrincipal::CreateCodebasePrincipal(referrerUri, OriginAttributes());
     627           0 :     NS_ENSURE_TRUE(referrerPrincipal, NS_ERROR_FAILURE);
     628             : 
     629             :     // This is probably called by js, a loadGroup for the channel doesn't
     630             :     // make sense.
     631           0 :     nsCOMPtr<nsINode> source;
     632           0 :     if (mProcessor) {
     633             :       source =
     634           0 :         do_QueryInterface(mProcessor->GetSourceContentModel());
     635             :     }
     636           0 :     nsAutoSyncOperation sync(source ? source->OwnerDoc() : nullptr);
     637           0 :     nsCOMPtr<nsIDOMDocument> document;
     638             : 
     639           0 :     rv = nsSyncLoadService::LoadDocument(uri, nsIContentPolicy::TYPE_XSLT,
     640             :                                          referrerPrincipal,
     641             :                                          nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS,
     642             :                                          nullptr, false,
     643             :                                          aReferrerPolicy,
     644           0 :                                          getter_AddRefs(document));
     645           0 :     NS_ENSURE_SUCCESS(rv, rv);
     646             : 
     647           0 :     nsCOMPtr<nsIDocument> doc = do_QueryInterface(document);
     648           0 :     rv = handleNode(doc, aCompiler);
     649           0 :     if (NS_FAILED(rv)) {
     650           0 :         nsAutoCString spec;
     651           0 :         uri->GetSpec(spec);
     652           0 :         aCompiler->cancel(rv, nullptr, NS_ConvertUTF8toUTF16(spec).get());
     653           0 :         return rv;
     654             :     }
     655             : 
     656           0 :     rv = aCompiler->doneLoading();
     657           0 :     return rv;
     658             : }
     659             : 
     660           0 : void txSyncCompileObserver::onDoneCompiling(txStylesheetCompiler* aCompiler,
     661             :                                             nsresult aResult,
     662             :                                             const char16_t *aErrorText,
     663             :                                             const char16_t *aParam)
     664             : {
     665           0 : }
     666             : 
     667             : nsresult
     668           0 : TX_CompileStylesheet(nsINode* aNode, txMozillaXSLTProcessor* aProcessor,
     669             :                      txStylesheet** aStylesheet)
     670             : {
     671             :     // If we move GetBaseURI to nsINode this can be simplified.
     672           0 :     nsCOMPtr<nsIDocument> doc = aNode->OwnerDoc();
     673             : 
     674           0 :     nsCOMPtr<nsIURI> uri;
     675           0 :     if (aNode->IsNodeOfType(nsINode::eCONTENT)) {
     676           0 :       uri = static_cast<nsIContent*>(aNode)->GetBaseURI();
     677             :     }
     678             :     else {
     679           0 :       NS_ASSERTION(aNode->IsNodeOfType(nsINode::eDOCUMENT), "not a doc");
     680           0 :       uri = static_cast<nsIDocument*>(aNode)->GetBaseURI();
     681             :     }
     682           0 :     NS_ENSURE_TRUE(uri, NS_ERROR_FAILURE);
     683             : 
     684           0 :     nsAutoCString spec;
     685           0 :     uri->GetSpec(spec);
     686           0 :     NS_ConvertUTF8toUTF16 baseURI(spec);
     687             : 
     688           0 :     nsIURI* docUri = doc->GetDocumentURI();
     689           0 :     NS_ENSURE_TRUE(docUri, NS_ERROR_FAILURE);
     690             : 
     691             :     // We need to remove the ref, a URI with a ref would mean that we have an
     692             :     // embedded stylesheet.
     693           0 :     docUri->CloneIgnoringRef(getter_AddRefs(uri));
     694           0 :     NS_ENSURE_TRUE(uri, NS_ERROR_FAILURE);
     695             : 
     696           0 :     uri->GetSpec(spec);
     697           0 :     NS_ConvertUTF8toUTF16 stylesheetURI(spec);
     698             : 
     699             :     RefPtr<txSyncCompileObserver> obs =
     700           0 :         new txSyncCompileObserver(aProcessor);
     701           0 :     NS_ENSURE_TRUE(obs, NS_ERROR_OUT_OF_MEMORY);
     702             : 
     703             :     RefPtr<txStylesheetCompiler> compiler =
     704           0 :         new txStylesheetCompiler(stylesheetURI, doc->GetReferrerPolicy(), obs);
     705           0 :     NS_ENSURE_TRUE(compiler, NS_ERROR_OUT_OF_MEMORY);
     706             : 
     707           0 :     compiler->setBaseURI(baseURI);
     708             : 
     709           0 :     nsresult rv = handleNode(aNode, compiler);
     710           0 :     if (NS_FAILED(rv)) {
     711           0 :         compiler->cancel(rv);
     712           0 :         return rv;
     713             :     }
     714             : 
     715           0 :     rv = compiler->doneLoading();
     716           0 :     NS_ENSURE_SUCCESS(rv, rv);
     717             : 
     718           0 :     *aStylesheet = compiler->getStylesheet();
     719           0 :     NS_ADDREF(*aStylesheet);
     720             : 
     721           0 :     return NS_OK;
     722             : }

Generated by: LCOV version 1.13