dom/xslt/xpath/nsXPathExpression.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     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/. */
     6 #include "nsXPathExpression.h"
     7 #include "txExpr.h"
     8 #include "txExprResult.h"
     9 #include "nsError.h"
    10 #include "nsIDOMCharacterData.h"
    11 #include "nsDOMClassInfoID.h"
    12 #include "nsIDOMDocument.h"
    13 #include "nsXPathResult.h"
    14 #include "txURIUtils.h"
    15 #include "txXPathTreeWalker.h"
    17 NS_IMPL_CYCLE_COLLECTION(nsXPathExpression, mDocument)
    19 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXPathExpression)
    20 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXPathExpression)
    22 DOMCI_DATA(XPathExpression, nsXPathExpression)
    24 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXPathExpression)
    25   NS_INTERFACE_MAP_ENTRY(nsIDOMXPathExpression)
    26   NS_INTERFACE_MAP_ENTRY(nsIDOMNSXPathExpression)
    27   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMXPathExpression)
    28   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(XPathExpression)
    29 NS_INTERFACE_MAP_END
    31 nsXPathExpression::nsXPathExpression(nsAutoPtr<Expr>& aExpression,
    32                                      txResultRecycler* aRecycler,
    33                                      nsIDOMDocument *aDocument)
    34     : mExpression(aExpression),
    35       mRecycler(aRecycler),
    36       mDocument(aDocument)
    37 {
    38 }
    40 NS_IMETHODIMP
    41 nsXPathExpression::Evaluate(nsIDOMNode *aContextNode,
    42                             uint16_t aType,
    43                             nsISupports *aInResult,
    44                             nsISupports **aResult)
    45 {
    46     return EvaluateWithContext(aContextNode, 1, 1, aType, aInResult, aResult);
    47 }
    49 NS_IMETHODIMP
    50 nsXPathExpression::EvaluateWithContext(nsIDOMNode *aContextNode,
    51                                        uint32_t aContextPosition,
    52                                        uint32_t aContextSize,
    53                                        uint16_t aType,
    54                                        nsISupports *aInResult,
    55                                        nsISupports **aResult)
    56 {
    57     nsCOMPtr<nsINode> context = do_QueryInterface(aContextNode);
    58     NS_ENSURE_ARG(context);
    60     if (aContextPosition > aContextSize)
    61         return NS_ERROR_FAILURE;
    63     if (!nsContentUtils::CanCallerAccess(aContextNode))
    64         return NS_ERROR_DOM_SECURITY_ERR;
    66     if (mDocument && mDocument != aContextNode) {
    67         nsCOMPtr<nsIDOMDocument> contextDocument;
    68         aContextNode->GetOwnerDocument(getter_AddRefs(contextDocument));
    70         if (mDocument != contextDocument) {
    71             return NS_ERROR_DOM_WRONG_DOCUMENT_ERR;
    72         }
    73     }
    75     uint16_t nodeType = context->NodeType();
    77     if (nodeType == nsIDOMNode::TEXT_NODE ||
    78         nodeType == nsIDOMNode::CDATA_SECTION_NODE) {
    79         nsCOMPtr<nsIDOMCharacterData> textNode = do_QueryInterface(aContextNode);
    80         NS_ENSURE_TRUE(textNode, NS_ERROR_FAILURE);
    82         if (textNode) {
    83             uint32_t textLength;
    84             textNode->GetLength(&textLength);
    85             if (textLength == 0)
    86                 return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
    87         }
    89         // XXX Need to get logical XPath text node for CDATASection
    90         //     and Text nodes.
    91     }
    92     else if (nodeType != nsIDOMNode::DOCUMENT_NODE &&
    93              nodeType != nsIDOMNode::ELEMENT_NODE &&
    94              nodeType != nsIDOMNode::ATTRIBUTE_NODE &&
    95              nodeType != nsIDOMNode::COMMENT_NODE &&
    96              nodeType != nsIDOMNode::PROCESSING_INSTRUCTION_NODE) {
    97         return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
    98     }
   100     NS_ENSURE_ARG(aResult);
   101     *aResult = nullptr;
   103     nsAutoPtr<txXPathNode> contextNode(txXPathNativeNode::createXPathNode(aContextNode));
   104     if (!contextNode) {
   105         return NS_ERROR_OUT_OF_MEMORY;
   106     }
   108     EvalContextImpl eContext(*contextNode, aContextPosition, aContextSize,
   109                              mRecycler);
   110     nsRefPtr<txAExprResult> exprResult;
   111     nsresult rv = mExpression->evaluate(&eContext, getter_AddRefs(exprResult));
   112     NS_ENSURE_SUCCESS(rv, rv);
   114     uint16_t resultType = aType;
   115     if (aType == nsIDOMXPathResult::ANY_TYPE) {
   116         short exprResultType = exprResult->getResultType();
   117         switch (exprResultType) {
   118             case txAExprResult::NUMBER:
   119                 resultType = nsIDOMXPathResult::NUMBER_TYPE;
   120                 break;
   121             case txAExprResult::STRING:
   122                 resultType = nsIDOMXPathResult::STRING_TYPE;
   123                 break;
   124             case txAExprResult::BOOLEAN:
   125                 resultType = nsIDOMXPathResult::BOOLEAN_TYPE;
   126                 break;
   127             case txAExprResult::NODESET:
   128                 resultType = nsIDOMXPathResult::UNORDERED_NODE_ITERATOR_TYPE;
   129                 break;
   130             case txAExprResult::RESULT_TREE_FRAGMENT:
   131                 NS_ERROR("Can't return a tree fragment!");
   132                 return NS_ERROR_FAILURE;
   133         }
   134     }
   136     // We need a result object and it must be our implementation.
   137     nsCOMPtr<nsIXPathResult> xpathResult = do_QueryInterface(aInResult);
   138     if (!xpathResult) {
   139         // Either no aInResult or not one of ours.
   140         xpathResult = new nsXPathResult();
   141         NS_ENSURE_TRUE(xpathResult, NS_ERROR_OUT_OF_MEMORY);
   142     }
   143     rv = xpathResult->SetExprResult(exprResult, resultType, context);
   144     NS_ENSURE_SUCCESS(rv, rv);
   146     return CallQueryInterface(xpathResult, aResult);
   147 }
   149 /*
   150  * Implementation of the txIEvalContext private to nsXPathExpression
   151  * EvalContextImpl bases on only one context node and no variables
   152  */
   154 nsresult
   155 nsXPathExpression::EvalContextImpl::getVariable(int32_t aNamespace,
   156                                                 nsIAtom* aLName,
   157                                                 txAExprResult*& aResult)
   158 {
   159     aResult = 0;
   160     return NS_ERROR_INVALID_ARG;
   161 }
   163 bool nsXPathExpression::EvalContextImpl::isStripSpaceAllowed(const txXPathNode& aNode)
   164 {
   165     return false;
   166 }
   168 void* nsXPathExpression::EvalContextImpl::getPrivateContext()
   169 {
   170     // we don't have a private context here.
   171     return nullptr;
   172 }
   174 txResultRecycler* nsXPathExpression::EvalContextImpl::recycler()
   175 {
   176     return mRecycler;
   177 }
   179 void nsXPathExpression::EvalContextImpl::receiveError(const nsAString& aMsg,
   180                                                       nsresult aRes)
   181 {
   182     mLastError = aRes;
   183     // forward aMsg to console service?
   184 }
   186 const txXPathNode& nsXPathExpression::EvalContextImpl::getContextNode()
   187 {
   188     return mContextNode;
   189 }
   191 uint32_t nsXPathExpression::EvalContextImpl::size()
   192 {
   193     return mContextSize;
   194 }
   196 uint32_t nsXPathExpression::EvalContextImpl::position()
   197 {
   198     return mContextPosition;
   199 }

mercurial