LCOV - code coverage report
Current view: directory - content/xslt/src/xslt - txMozillaStylesheetCompiler.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 314 0 0.0 %
Date: 2012-06-02 Functions: 43 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is TransforMiiX XSLT processor code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 2002
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Peter Van der Beken <peterv@propagandism.org>
      24                 :  *   Ryan Jones <sciguyryan@gmail.com>
      25                 :  *
      26                 :  * Alternatively, the contents of this file may be used under the terms of
      27                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      28                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      30                 :  * of those above. If you wish to allow use of your version of this file only
      31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      32                 :  * use your version of this file under the terms of the MPL, indicate your
      33                 :  * decision by deleting the provisions above and replace them with the notice
      34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      35                 :  * the provisions above, a recipient may use your version of this file under
      36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      37                 :  *
      38                 :  * ***** END LICENSE BLOCK ***** */
      39                 : 
      40                 : #include "nsCOMArray.h"
      41                 : #include "nsIAuthPrompt.h"
      42                 : #include "nsCharsetAlias.h"
      43                 : #include "nsIDOMNode.h"
      44                 : #include "nsIDOMDocument.h"
      45                 : #include "nsIDocument.h"
      46                 : #include "nsIExpatSink.h"
      47                 : #include "nsIChannelEventSink.h"
      48                 : #include "nsIInterfaceRequestor.h"
      49                 : #include "nsILoadGroup.h"
      50                 : #include "nsINameSpaceManager.h"
      51                 : #include "nsINodeInfo.h"
      52                 : #include "nsIParser.h"
      53                 : #include "nsIRequestObserver.h"
      54                 : #include "nsIScriptSecurityManager.h"
      55                 : #include "nsContentPolicyUtils.h"
      56                 : #include "nsIStreamConverterService.h"
      57                 : #include "nsSyncLoadService.h"
      58                 : #include "nsIURI.h"
      59                 : #include "nsIPrincipal.h"
      60                 : #include "nsIWindowWatcher.h"
      61                 : #include "nsIXMLContentSink.h"
      62                 : #include "nsMimeTypes.h"
      63                 : #include "nsNetUtil.h"
      64                 : #include "nsParserCIID.h"
      65                 : #include "nsGkAtoms.h"
      66                 : #include "txLog.h"
      67                 : #include "txMozillaXSLTProcessor.h"
      68                 : #include "txStylesheetCompiler.h"
      69                 : #include "txXMLUtils.h"
      70                 : #include "nsAttrName.h"
      71                 : #include "nsIScriptError.h"
      72                 : #include "nsIURL.h"
      73                 : #include "nsCrossSiteListenerProxy.h"
      74                 : #include "nsDOMError.h"
      75                 : #include "mozilla/dom/Element.h"
      76                 : 
      77                 : using namespace mozilla;
      78                 : 
      79                 : static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
      80                 : 
      81                 : static void
      82               0 : getSpec(nsIChannel* aChannel, nsAString& aSpec)
      83                 : {
      84               0 :     if (!aChannel) {
      85               0 :         return;
      86                 :     }
      87                 : 
      88               0 :     nsCOMPtr<nsIURI> uri;
      89               0 :     aChannel->GetOriginalURI(getter_AddRefs(uri));
      90               0 :     if (!uri) {
      91                 :         return;
      92                 :     }
      93                 : 
      94               0 :     nsCAutoString spec;
      95               0 :     uri->GetSpec(spec);
      96               0 :     AppendUTF8toUTF16(spec, aSpec);
      97                 : }
      98                 : 
      99                 : class txStylesheetSink : public nsIXMLContentSink,
     100                 :                          public nsIExpatSink,
     101                 :                          public nsIStreamListener,
     102                 :                          public nsIInterfaceRequestor
     103               0 : {
     104                 : public:
     105                 :     txStylesheetSink(txStylesheetCompiler* aCompiler, nsIParser* aParser);
     106                 : 
     107                 :     NS_DECL_ISUPPORTS
     108                 :     NS_DECL_NSIEXPATSINK
     109                 :     NS_DECL_NSISTREAMLISTENER
     110                 :     NS_DECL_NSIREQUESTOBSERVER
     111                 :     NS_DECL_NSIINTERFACEREQUESTOR
     112                 : 
     113                 :     // nsIContentSink
     114               0 :     NS_IMETHOD WillParse(void) { return NS_OK; }
     115                 :     NS_IMETHOD DidBuildModel(bool aTerminated);
     116               0 :     NS_IMETHOD WillInterrupt(void) { return NS_OK; }
     117               0 :     NS_IMETHOD WillResume(void) { return NS_OK; }
     118               0 :     NS_IMETHOD SetParser(nsParserBase* aParser) { return NS_OK; }
     119               0 :     virtual void FlushPendingNotifications(mozFlushType aType) { }
     120               0 :     NS_IMETHOD SetDocumentCharset(nsACString& aCharset) { return NS_OK; }
     121               0 :     virtual nsISupports *GetTarget() { return nsnull; }
     122                 : 
     123                 : private:
     124                 :     nsRefPtr<txStylesheetCompiler> mCompiler;
     125                 :     nsCOMPtr<nsIStreamListener> mListener;
     126                 :     bool mCheckedForXML;
     127                 : 
     128                 : protected:
     129                 :     // This exists solely to suppress a warning from nsDerivedSafe
     130                 :     txStylesheetSink();
     131                 : };
     132                 : 
     133               0 : txStylesheetSink::txStylesheetSink(txStylesheetCompiler* aCompiler,
     134                 :                                    nsIParser* aParser)
     135                 :     : mCompiler(aCompiler),
     136               0 :       mCheckedForXML(false)
     137                 : {
     138               0 :     mListener = do_QueryInterface(aParser);
     139               0 : }
     140                 : 
     141               0 : NS_IMPL_ISUPPORTS6(txStylesheetSink,
     142                 :                    nsIXMLContentSink,
     143                 :                    nsIContentSink,
     144                 :                    nsIExpatSink,
     145                 :                    nsIStreamListener,
     146                 :                    nsIRequestObserver,
     147                 :                    nsIInterfaceRequestor)
     148                 : 
     149                 : NS_IMETHODIMP
     150               0 : txStylesheetSink::HandleStartElement(const PRUnichar *aName,
     151                 :                                      const PRUnichar **aAtts,
     152                 :                                      PRUint32 aAttsCount,
     153                 :                                      PRInt32 aIndex,
     154                 :                                      PRUint32 aLineNumber)
     155                 : {
     156               0 :     NS_PRECONDITION(aAttsCount % 2 == 0, "incorrect aAttsCount");
     157                 : 
     158                 :     nsresult rv =
     159               0 :         mCompiler->startElement(aName, aAtts, aAttsCount / 2, aIndex);
     160               0 :     if (NS_FAILED(rv)) {
     161               0 :         mCompiler->cancel(rv);
     162                 : 
     163               0 :         return rv;
     164                 :     }
     165                 :     
     166               0 :     return NS_OK;
     167                 : }
     168                 : 
     169                 : NS_IMETHODIMP
     170               0 : txStylesheetSink::HandleEndElement(const PRUnichar *aName)
     171                 : {
     172               0 :     nsresult rv = mCompiler->endElement();
     173               0 :     if (NS_FAILED(rv)) {
     174               0 :         mCompiler->cancel(rv);
     175                 : 
     176               0 :         return rv;
     177                 :     }
     178                 : 
     179               0 :     return NS_OK;
     180                 : }
     181                 : 
     182                 : NS_IMETHODIMP
     183               0 : txStylesheetSink::HandleComment(const PRUnichar *aName)
     184                 : {
     185               0 :     return NS_OK;
     186                 : }
     187                 : 
     188                 : NS_IMETHODIMP
     189               0 : txStylesheetSink::HandleCDataSection(const PRUnichar *aData,
     190                 :                                      PRUint32 aLength)
     191                 : {
     192               0 :     return HandleCharacterData(aData, aLength);
     193                 : }
     194                 : 
     195                 : NS_IMETHODIMP
     196               0 : txStylesheetSink::HandleDoctypeDecl(const nsAString & aSubset,
     197                 :                                     const nsAString & aName,
     198                 :                                     const nsAString & aSystemId,
     199                 :                                     const nsAString & aPublicId,
     200                 :                                     nsISupports *aCatalogData)
     201                 : {
     202               0 :     return NS_OK;
     203                 : }
     204                 : 
     205                 : NS_IMETHODIMP
     206               0 : txStylesheetSink::HandleCharacterData(const PRUnichar *aData,
     207                 :                                       PRUint32 aLength)
     208                 : {
     209               0 :     nsresult rv = mCompiler->characters(Substring(aData, aData + aLength));
     210               0 :     if (NS_FAILED(rv)) {
     211               0 :         mCompiler->cancel(rv);
     212               0 :         return rv;
     213                 :     }
     214                 : 
     215               0 :     return NS_OK;
     216                 : }
     217                 : 
     218                 : NS_IMETHODIMP
     219               0 : txStylesheetSink::HandleProcessingInstruction(const PRUnichar *aTarget,
     220                 :                                               const PRUnichar *aData)
     221                 : {
     222               0 :     return NS_OK;
     223                 : }
     224                 : 
     225                 : NS_IMETHODIMP
     226               0 : txStylesheetSink::HandleXMLDeclaration(const PRUnichar *aVersion,
     227                 :                                        const PRUnichar *aEncoding,
     228                 :                                        PRInt32 aStandalone)
     229                 : {
     230               0 :     return NS_OK;
     231                 : }
     232                 : 
     233                 : NS_IMETHODIMP
     234               0 : txStylesheetSink::ReportError(const PRUnichar *aErrorText,
     235                 :                               const PRUnichar *aSourceText,
     236                 :                               nsIScriptError *aError,
     237                 :                               bool *_retval)
     238                 : {
     239               0 :     NS_PRECONDITION(aError && aSourceText && aErrorText, "Check arguments!!!");
     240                 : 
     241                 :     // The expat driver should report the error.
     242               0 :     *_retval = true;
     243                 : 
     244               0 :     mCompiler->cancel(NS_ERROR_FAILURE, aErrorText, aSourceText);
     245                 : 
     246               0 :     return NS_OK;
     247                 : }
     248                 : 
     249                 : NS_IMETHODIMP 
     250               0 : txStylesheetSink::DidBuildModel(bool aTerminated)
     251                 : {  
     252               0 :     return mCompiler->doneLoading();
     253                 : }
     254                 : 
     255                 : NS_IMETHODIMP
     256               0 : txStylesheetSink::OnDataAvailable(nsIRequest *aRequest, nsISupports *aContext,
     257                 :                                   nsIInputStream *aInputStream,
     258                 :                                   PRUint32 aOffset, PRUint32 aCount)
     259                 : {
     260               0 :     if (!mCheckedForXML) {
     261               0 :         nsCOMPtr<nsIParser> parser = do_QueryInterface(aContext);
     262               0 :         nsCOMPtr<nsIDTD> dtd;
     263               0 :         parser->GetDTD(getter_AddRefs(dtd));
     264               0 :         if (dtd) {
     265               0 :             mCheckedForXML = true;
     266               0 :             if (!(dtd->GetType() & NS_IPARSER_FLAG_XML)) {
     267               0 :                 nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
     268               0 :                 nsAutoString spec;
     269               0 :                 getSpec(channel, spec);
     270                 :                 mCompiler->cancel(NS_ERROR_XSLT_WRONG_MIME_TYPE, nsnull,
     271               0 :                                   spec.get());
     272                 : 
     273               0 :                 return NS_ERROR_XSLT_WRONG_MIME_TYPE;
     274                 :             }
     275                 :         }
     276                 :     }
     277                 : 
     278               0 :     return mListener->OnDataAvailable(aRequest, aContext, aInputStream,
     279               0 :                                       aOffset, aCount);
     280                 : }
     281                 : 
     282                 : NS_IMETHODIMP
     283               0 : txStylesheetSink::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
     284                 : {
     285               0 :     PRInt32 charsetSource = kCharsetFromDocTypeDefault;
     286                 : 
     287               0 :     nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
     288                 : 
     289                 :     // check channel's charset...
     290               0 :     nsCAutoString charsetVal;
     291               0 :     nsCAutoString charset;
     292               0 :     if (NS_SUCCEEDED(channel->GetContentCharset(charsetVal))) {
     293               0 :         if (NS_SUCCEEDED(nsCharsetAlias::GetPreferred(charsetVal, charset))) {
     294               0 :             charsetSource = kCharsetFromChannel;
     295                 :         }
     296                 :     }
     297                 : 
     298               0 :     if (charset.IsEmpty()) {
     299               0 :       charset.AssignLiteral("UTF-8");
     300                 :     }
     301                 : 
     302               0 :     nsCOMPtr<nsIParser> parser = do_QueryInterface(aContext);
     303               0 :     parser->SetDocumentCharset(charset, charsetSource);
     304                 : 
     305               0 :     nsCAutoString contentType;
     306               0 :     channel->GetContentType(contentType);
     307                 : 
     308                 :     // Time to sniff! Note: this should go away once file channels do
     309                 :     // sniffing themselves.
     310               0 :     nsCOMPtr<nsIURI> uri;
     311               0 :     channel->GetURI(getter_AddRefs(uri));
     312                 :     bool sniff;
     313               0 :     if (NS_SUCCEEDED(uri->SchemeIs("file", &sniff)) && sniff &&
     314               0 :         contentType.Equals(UNKNOWN_CONTENT_TYPE)) {
     315                 :         nsresult rv;
     316                 :         nsCOMPtr<nsIStreamConverterService> serv =
     317               0 :             do_GetService("@mozilla.org/streamConverters;1", &rv);
     318               0 :         if (NS_SUCCEEDED(rv)) {
     319               0 :             nsCOMPtr<nsIStreamListener> converter;
     320               0 :             rv = serv->AsyncConvertData(UNKNOWN_CONTENT_TYPE,
     321                 :                                         "*/*",
     322                 :                                         mListener,
     323                 :                                         aContext,
     324               0 :                                         getter_AddRefs(converter));
     325               0 :             if (NS_SUCCEEDED(rv)) {
     326               0 :                 mListener = converter;
     327                 :             }
     328                 :         }
     329                 :     }
     330                 : 
     331               0 :     return mListener->OnStartRequest(aRequest, aContext);
     332                 : }
     333                 : 
     334                 : NS_IMETHODIMP
     335               0 : txStylesheetSink::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext,
     336                 :                                 nsresult aStatusCode)
     337                 : {
     338               0 :     bool success = true;
     339                 : 
     340               0 :     nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aRequest);
     341               0 :     if (httpChannel) {
     342               0 :         httpChannel->GetRequestSucceeded(&success);
     343                 :     }
     344                 : 
     345               0 :     nsresult result = aStatusCode;
     346               0 :     if (!success) {
     347                 :         // XXX We sometimes want to use aStatusCode here, but the parser resets
     348                 :         //     it to NS_ERROR_NOINTERFACE because we don't implement
     349                 :         //     nsIHTMLContentSink.
     350               0 :         result = NS_ERROR_XSLT_NETWORK_ERROR;
     351                 :     }
     352               0 :     else if (!mCheckedForXML) {
     353               0 :         nsCOMPtr<nsIParser> parser = do_QueryInterface(aContext);
     354               0 :         nsCOMPtr<nsIDTD> dtd;
     355               0 :         parser->GetDTD(getter_AddRefs(dtd));
     356               0 :         if (dtd && !(dtd->GetType() & NS_IPARSER_FLAG_XML)) {
     357               0 :             result = NS_ERROR_XSLT_WRONG_MIME_TYPE;
     358                 :         }
     359                 :     }
     360                 : 
     361               0 :     if (NS_FAILED(result)) {
     362               0 :         nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
     363               0 :         nsAutoString spec;
     364               0 :         getSpec(channel, spec);
     365               0 :         mCompiler->cancel(result, nsnull, spec.get());
     366                 :     }
     367                 : 
     368               0 :     nsresult rv = mListener->OnStopRequest(aRequest, aContext, aStatusCode);
     369               0 :     mListener = nsnull;
     370               0 :     return rv;
     371                 : }
     372                 : 
     373                 : NS_IMETHODIMP
     374               0 : txStylesheetSink::GetInterface(const nsIID& aIID, void** aResult)
     375                 : {
     376               0 :     if (aIID.Equals(NS_GET_IID(nsIAuthPrompt))) {
     377               0 :         NS_ENSURE_ARG(aResult);
     378               0 :         *aResult = nsnull;
     379                 : 
     380                 :         nsresult rv;
     381                 :         nsCOMPtr<nsIWindowWatcher> wwatcher =
     382               0 :             do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
     383               0 :         NS_ENSURE_SUCCESS(rv, rv);
     384                 : 
     385               0 :         nsCOMPtr<nsIAuthPrompt> prompt;
     386               0 :         rv = wwatcher->GetNewAuthPrompter(nsnull, getter_AddRefs(prompt));
     387               0 :         NS_ENSURE_SUCCESS(rv, rv);
     388                 : 
     389               0 :         nsIAuthPrompt* rawPtr = nsnull;
     390               0 :         prompt.swap(rawPtr);
     391               0 :         *aResult = rawPtr;
     392                 : 
     393               0 :         return NS_OK;
     394                 :     }
     395                 : 
     396               0 :     return NS_ERROR_NO_INTERFACE;
     397                 : }
     398                 : 
     399                 : class txCompileObserver : public txACompileObserver
     400               0 : {
     401                 : public:
     402                 :     txCompileObserver(txMozillaXSLTProcessor* aProcessor,
     403                 :                       nsILoadGroup* aLoadGroup);
     404                 : 
     405                 :     TX_DECL_ACOMPILEOBSERVER
     406               0 :     NS_INLINE_DECL_REFCOUNTING(txCompileObserver)
     407                 : 
     408                 :     nsresult startLoad(nsIURI* aUri, txStylesheetCompiler* aCompiler,
     409                 :                        nsIPrincipal* aSourcePrincipal);
     410                 : 
     411                 : private:
     412                 :     nsRefPtr<txMozillaXSLTProcessor> mProcessor;
     413                 :     nsCOMPtr<nsILoadGroup> mLoadGroup;
     414                 :     nsCOMPtr<nsIPrincipal> mCallerPrincipal;
     415                 : 
     416                 : protected:
     417                 :     // This exists solely to suppress a warning from nsDerivedSafe
     418                 :     txCompileObserver();
     419                 : };
     420                 : 
     421               0 : txCompileObserver::txCompileObserver(txMozillaXSLTProcessor* aProcessor,
     422                 :                                      nsILoadGroup* aLoadGroup)
     423                 :     : mProcessor(aProcessor),
     424               0 :       mLoadGroup(aLoadGroup)
     425                 : {
     426               0 : }
     427                 : 
     428                 : nsresult
     429               0 : txCompileObserver::loadURI(const nsAString& aUri,
     430                 :                            const nsAString& aReferrerUri,
     431                 :                            txStylesheetCompiler* aCompiler)
     432                 : {
     433               0 :     if (mProcessor->IsLoadDisabled()) {
     434               0 :         return NS_ERROR_XSLT_LOAD_BLOCKED_ERROR;
     435                 :     }
     436                 : 
     437               0 :     nsCOMPtr<nsIURI> uri;
     438               0 :     nsresult rv = NS_NewURI(getter_AddRefs(uri), aUri);
     439               0 :     NS_ENSURE_SUCCESS(rv, rv);
     440                 : 
     441               0 :     nsCOMPtr<nsIURI> referrerUri;
     442               0 :     rv = NS_NewURI(getter_AddRefs(referrerUri), aReferrerUri);
     443               0 :     NS_ENSURE_SUCCESS(rv, rv);
     444                 : 
     445               0 :     nsCOMPtr<nsIPrincipal> referrerPrincipal;
     446               0 :     rv = nsContentUtils::GetSecurityManager()->
     447               0 :       GetCodebasePrincipal(referrerUri, getter_AddRefs(referrerPrincipal));
     448               0 :     NS_ENSURE_SUCCESS(rv, rv);
     449                 : 
     450                 :     // Content Policy
     451               0 :     PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
     452                 :     rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_STYLESHEET,
     453                 :                                    uri,
     454                 :                                    referrerPrincipal,
     455                 :                                    nsnull,
     456               0 :                                    NS_LITERAL_CSTRING("application/xml"),
     457                 :                                    nsnull,
     458               0 :                                    &shouldLoad);
     459               0 :     NS_ENSURE_SUCCESS(rv, rv);
     460               0 :     if (NS_CP_REJECTED(shouldLoad)) {
     461               0 :         return NS_ERROR_DOM_BAD_URI;
     462                 :     }
     463                 : 
     464               0 :     return startLoad(uri, aCompiler, referrerPrincipal);
     465                 : }
     466                 : 
     467                 : void
     468               0 : txCompileObserver::onDoneCompiling(txStylesheetCompiler* aCompiler,
     469                 :                                    nsresult aResult,
     470                 :                                    const PRUnichar *aErrorText,
     471                 :                                    const PRUnichar *aParam)
     472                 : {
     473               0 :     if (NS_SUCCEEDED(aResult)) {
     474               0 :         mProcessor->setStylesheet(aCompiler->getStylesheet());
     475                 :     }
     476                 :     else {
     477               0 :         mProcessor->reportError(aResult, aErrorText, aParam);
     478                 :     }
     479               0 : }
     480                 : 
     481                 : nsresult
     482               0 : txCompileObserver::startLoad(nsIURI* aUri, txStylesheetCompiler* aCompiler,
     483                 :                              nsIPrincipal* aReferrerPrincipal)
     484                 : {
     485               0 :     nsCOMPtr<nsIChannel> channel;
     486               0 :     nsresult rv = NS_NewChannel(getter_AddRefs(channel), aUri);
     487               0 :     NS_ENSURE_SUCCESS(rv, rv);
     488                 : 
     489               0 :     channel->SetLoadGroup(mLoadGroup);
     490                 : 
     491               0 :     channel->SetContentType(NS_LITERAL_CSTRING("text/xml"));
     492                 : 
     493               0 :     nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
     494               0 :     if (httpChannel) {
     495               0 :         httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
     496               0 :                                       NS_LITERAL_CSTRING("*/*"),
     497               0 :                                       false);
     498                 : 
     499               0 :         nsCOMPtr<nsIURI> referrerURI;
     500               0 :         aReferrerPrincipal->GetURI(getter_AddRefs(referrerURI));
     501               0 :         if (referrerURI) {
     502               0 :             httpChannel->SetReferrer(referrerURI);
     503                 :         }
     504                 :     }
     505                 : 
     506               0 :     nsCOMPtr<nsIParser> parser = do_CreateInstance(kCParserCID, &rv);
     507               0 :     NS_ENSURE_SUCCESS(rv, rv);
     508                 : 
     509               0 :     nsRefPtr<txStylesheetSink> sink = new txStylesheetSink(aCompiler, parser);
     510               0 :     NS_ENSURE_TRUE(sink, NS_ERROR_OUT_OF_MEMORY);
     511                 : 
     512               0 :     channel->SetNotificationCallbacks(sink);
     513                 : 
     514               0 :     parser->SetCommand(kLoadAsData);
     515               0 :     parser->SetContentSink(sink);
     516               0 :     parser->Parse(aUri);
     517                 : 
     518                 :     // Always install in case of redirects
     519                 :     nsCOMPtr<nsIStreamListener> listener =
     520                 :         new nsCORSListenerProxy(sink, aReferrerPrincipal, channel,
     521               0 :                                 false, &rv);
     522               0 :     NS_ENSURE_TRUE(listener, NS_ERROR_OUT_OF_MEMORY);
     523               0 :     NS_ENSURE_SUCCESS(rv, rv);
     524                 : 
     525               0 :     return channel->AsyncOpen(listener, parser);
     526                 : }
     527                 : 
     528                 : nsresult
     529               0 : TX_LoadSheet(nsIURI* aUri, txMozillaXSLTProcessor* aProcessor,
     530                 :              nsILoadGroup* aLoadGroup, nsIPrincipal* aCallerPrincipal)
     531                 : {
     532               0 :     nsCAutoString spec;
     533               0 :     aUri->GetSpec(spec);
     534               0 :     PR_LOG(txLog::xslt, PR_LOG_ALWAYS, ("TX_LoadSheet: %s\n", spec.get()));
     535                 : 
     536                 :     // Content Policy
     537               0 :     PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
     538                 :     nsresult rv =
     539                 :         NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_STYLESHEET,
     540                 :                                   aUri,
     541                 :                                   aCallerPrincipal,
     542               0 :                                   aProcessor->GetSourceContentModel(),
     543               0 :                                   NS_LITERAL_CSTRING("application/xml"),
     544                 :                                   nsnull,
     545               0 :                                   &shouldLoad);
     546               0 :     NS_ENSURE_SUCCESS(rv, rv);
     547               0 :     if (NS_CP_REJECTED(shouldLoad)) {
     548               0 :         return NS_ERROR_DOM_BAD_URI;
     549                 :     }
     550                 : 
     551                 :     nsRefPtr<txCompileObserver> observer =
     552               0 :         new txCompileObserver(aProcessor, aLoadGroup);
     553               0 :     NS_ENSURE_TRUE(observer, NS_ERROR_OUT_OF_MEMORY);
     554                 : 
     555                 :     nsRefPtr<txStylesheetCompiler> compiler =
     556               0 :         new txStylesheetCompiler(NS_ConvertUTF8toUTF16(spec), observer);
     557               0 :     NS_ENSURE_TRUE(compiler, NS_ERROR_OUT_OF_MEMORY);
     558                 : 
     559               0 :     return observer->startLoad(aUri, compiler, aCallerPrincipal);
     560                 : }
     561                 : 
     562                 : /**
     563                 :  * handling DOM->txStylesheet
     564                 :  * Observer needs to do synchronous loads.
     565                 :  */
     566                 : static nsresult
     567               0 : handleNode(nsINode* aNode, txStylesheetCompiler* aCompiler)
     568                 : {
     569               0 :     nsresult rv = NS_OK;
     570                 :     
     571               0 :     if (aNode->IsElement()) {
     572               0 :         dom::Element* element = aNode->AsElement();
     573                 : 
     574               0 :         PRUint32 attsCount = element->GetAttrCount();
     575               0 :         nsAutoArrayPtr<txStylesheetAttr> atts;
     576               0 :         if (attsCount > 0) {
     577               0 :             atts = new txStylesheetAttr[attsCount];
     578               0 :             NS_ENSURE_TRUE(atts, NS_ERROR_OUT_OF_MEMORY);
     579                 : 
     580                 :             PRUint32 counter;
     581               0 :             for (counter = 0; counter < attsCount; ++counter) {
     582               0 :                 txStylesheetAttr& att = atts[counter];
     583               0 :                 const nsAttrName* name = element->GetAttrNameAt(counter);
     584               0 :                 att.mNamespaceID = name->NamespaceID();
     585               0 :                 att.mLocalName = name->LocalName();
     586               0 :                 att.mPrefix = name->GetPrefix();
     587               0 :                 element->GetAttr(att.mNamespaceID, att.mLocalName, att.mValue);
     588                 :             }
     589                 :         }
     590                 : 
     591               0 :         nsINodeInfo *ni = element->NodeInfo();
     592                 : 
     593                 :         rv = aCompiler->startElement(ni->NamespaceID(),
     594                 :                                      ni->NameAtom(),
     595                 :                                      ni->GetPrefixAtom(), atts,
     596               0 :                                      attsCount);
     597               0 :         NS_ENSURE_SUCCESS(rv, rv);
     598                 : 
     599                 :         // explicitly destroy the attrs here since we no longer need it
     600               0 :         atts = nsnull;
     601                 : 
     602               0 :         for (nsIContent* child = element->GetFirstChild();
     603                 :              child;
     604               0 :              child = child->GetNextSibling()) {
     605                 :              
     606               0 :             rv = handleNode(child, aCompiler);
     607               0 :             NS_ENSURE_SUCCESS(rv, rv);
     608                 :         }
     609                 : 
     610               0 :         rv = aCompiler->endElement();
     611               0 :         NS_ENSURE_SUCCESS(rv, rv);
     612                 :     }
     613               0 :     else if (aNode->IsNodeOfType(nsINode::eTEXT)) {
     614               0 :         nsAutoString chars;
     615               0 :         static_cast<nsIContent*>(aNode)->AppendTextTo(chars);
     616               0 :         rv = aCompiler->characters(chars);
     617               0 :         NS_ENSURE_SUCCESS(rv, rv);
     618                 :     }
     619               0 :     else if (aNode->IsNodeOfType(nsINode::eDOCUMENT)) {
     620               0 :         for (nsIContent* child = aNode->GetFirstChild();
     621                 :              child;
     622               0 :              child = child->GetNextSibling()) {
     623                 :              
     624               0 :             rv = handleNode(child, aCompiler);
     625               0 :             NS_ENSURE_SUCCESS(rv, rv);
     626                 :         }
     627                 :     }
     628                 : 
     629               0 :     return NS_OK;
     630                 : }
     631                 : 
     632                 : class txSyncCompileObserver : public txACompileObserver
     633               0 : {
     634                 : public:
     635                 :     txSyncCompileObserver(txMozillaXSLTProcessor* aProcessor);
     636                 : 
     637                 :     TX_DECL_ACOMPILEOBSERVER
     638               0 :     NS_INLINE_DECL_REFCOUNTING(txSyncCompileObserver)
     639                 : 
     640                 : protected:
     641                 :     nsRefPtr<txMozillaXSLTProcessor> mProcessor;
     642                 : };
     643                 : 
     644               0 : txSyncCompileObserver::txSyncCompileObserver(txMozillaXSLTProcessor* aProcessor)
     645               0 :   : mProcessor(aProcessor)
     646                 : {
     647               0 : }
     648                 : 
     649                 : nsresult
     650               0 : txSyncCompileObserver::loadURI(const nsAString& aUri,
     651                 :                                const nsAString& aReferrerUri,
     652                 :                                txStylesheetCompiler* aCompiler)
     653                 : {
     654               0 :     if (mProcessor->IsLoadDisabled()) {
     655               0 :         return NS_ERROR_XSLT_LOAD_BLOCKED_ERROR;
     656                 :     }
     657                 : 
     658               0 :     nsCOMPtr<nsIURI> uri;
     659               0 :     nsresult rv = NS_NewURI(getter_AddRefs(uri), aUri);
     660               0 :     NS_ENSURE_SUCCESS(rv, rv);
     661                 : 
     662               0 :     nsCOMPtr<nsIURI> referrerUri;
     663               0 :     rv = NS_NewURI(getter_AddRefs(referrerUri), aReferrerUri);
     664               0 :     NS_ENSURE_SUCCESS(rv, rv);
     665                 : 
     666               0 :     nsCOMPtr<nsIPrincipal> referrerPrincipal;
     667               0 :     rv = nsContentUtils::GetSecurityManager()->
     668               0 :       GetCodebasePrincipal(referrerUri, getter_AddRefs(referrerPrincipal));
     669               0 :     NS_ENSURE_SUCCESS(rv, rv);
     670                 : 
     671                 :     // Content Policy
     672               0 :     PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
     673                 :     rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_STYLESHEET,
     674                 :                                    uri,
     675                 :                                    referrerPrincipal,
     676                 :                                    nsnull,
     677               0 :                                    NS_LITERAL_CSTRING("application/xml"),
     678                 :                                    nsnull,
     679               0 :                                    &shouldLoad);
     680               0 :     NS_ENSURE_SUCCESS(rv, rv);
     681               0 :     if (NS_CP_REJECTED(shouldLoad)) {
     682               0 :         return NS_ERROR_DOM_BAD_URI;
     683                 :     }
     684                 : 
     685                 :     // This is probably called by js, a loadGroup for the channel doesn't
     686                 :     // make sense.
     687               0 :     nsCOMPtr<nsIDOMDocument> document;
     688                 :     rv = nsSyncLoadService::LoadDocument(uri, referrerPrincipal, nsnull,
     689               0 :                                          false, getter_AddRefs(document));
     690               0 :     NS_ENSURE_SUCCESS(rv, rv);
     691                 : 
     692               0 :     nsCOMPtr<nsIDocument> doc = do_QueryInterface(document);
     693               0 :     rv = handleNode(doc, aCompiler);
     694               0 :     if (NS_FAILED(rv)) {
     695               0 :         nsCAutoString spec;
     696               0 :         uri->GetSpec(spec);
     697               0 :         aCompiler->cancel(rv, nsnull, NS_ConvertUTF8toUTF16(spec).get());
     698               0 :         return rv;
     699                 :     }
     700                 : 
     701               0 :     rv = aCompiler->doneLoading();
     702               0 :     return rv;
     703                 : }
     704                 : 
     705               0 : void txSyncCompileObserver::onDoneCompiling(txStylesheetCompiler* aCompiler,
     706                 :                                             nsresult aResult,
     707                 :                                             const PRUnichar *aErrorText,
     708                 :                                             const PRUnichar *aParam)
     709                 : {
     710               0 : }
     711                 : 
     712                 : nsresult
     713               0 : TX_CompileStylesheet(nsINode* aNode, txMozillaXSLTProcessor* aProcessor,
     714                 :                      nsIPrincipal* aCallerPrincipal,
     715                 :                      txStylesheet** aStylesheet)
     716                 : {
     717                 :     // If we move GetBaseURI to nsINode this can be simplified.
     718               0 :     nsCOMPtr<nsIDocument> doc = aNode->OwnerDoc();
     719                 : 
     720               0 :     nsCOMPtr<nsIURI> uri;
     721               0 :     if (aNode->IsNodeOfType(nsINode::eCONTENT)) {
     722               0 :       uri = static_cast<nsIContent*>(aNode)->GetBaseURI();
     723                 :     }
     724                 :     else { 
     725               0 :       NS_ASSERTION(aNode->IsNodeOfType(nsINode::eDOCUMENT), "not a doc");
     726               0 :       uri = static_cast<nsIDocument*>(aNode)->GetBaseURI();
     727                 :     }
     728               0 :     NS_ENSURE_TRUE(uri, NS_ERROR_FAILURE);
     729                 :     
     730               0 :     nsCAutoString spec;
     731               0 :     uri->GetSpec(spec);
     732               0 :     NS_ConvertUTF8toUTF16 baseURI(spec);
     733                 : 
     734               0 :     nsIURI* docUri = doc->GetDocumentURI();
     735               0 :     NS_ENSURE_TRUE(docUri, NS_ERROR_FAILURE);
     736                 : 
     737                 :     // We need to remove the ref, a URI with a ref would mean that we have an
     738                 :     // embedded stylesheet.
     739               0 :     docUri->CloneIgnoringRef(getter_AddRefs(uri));
     740               0 :     NS_ENSURE_TRUE(uri, NS_ERROR_FAILURE);
     741                 : 
     742               0 :     uri->GetSpec(spec);
     743               0 :     NS_ConvertUTF8toUTF16 stylesheetURI(spec);
     744                 : 
     745                 :     nsRefPtr<txSyncCompileObserver> obs =
     746               0 :         new txSyncCompileObserver(aProcessor);
     747               0 :     NS_ENSURE_TRUE(obs, NS_ERROR_OUT_OF_MEMORY);
     748                 : 
     749                 :     nsRefPtr<txStylesheetCompiler> compiler =
     750               0 :         new txStylesheetCompiler(stylesheetURI, obs);
     751               0 :     NS_ENSURE_TRUE(compiler, NS_ERROR_OUT_OF_MEMORY);
     752                 : 
     753               0 :     compiler->setBaseURI(baseURI);
     754                 : 
     755               0 :     nsresult rv = handleNode(aNode, compiler);
     756               0 :     if (NS_FAILED(rv)) {
     757               0 :         compiler->cancel(rv);
     758               0 :         return rv;
     759                 :     }
     760                 : 
     761               0 :     rv = compiler->doneLoading();
     762               0 :     NS_ENSURE_SUCCESS(rv, rv);
     763                 :     
     764               0 :     *aStylesheet = compiler->getStylesheet();
     765               0 :     NS_ADDREF(*aStylesheet);
     766                 : 
     767               0 :     return NS_OK;
     768                 : }

Generated by: LCOV version 1.7