Tue, 06 Jan 2015 21:39:09 +0100
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 }