source: webkit/trunk/WebCore/xml/XPathExpression.cpp@ 44361

Last change on this file since 44361 was 44361, checked in by [email protected], 16 years ago

Reviewed by Sam Weinig.

https://bugs.webkit.org/show_bug.cgi?id=26133
Adapt and import py-dom-xpath tests

Tests: fast/xpath/py-dom-xpath/abbreviations.html

fast/xpath/py-dom-xpath/axes.html
fast/xpath/py-dom-xpath/data.html
fast/xpath/py-dom-xpath/expressions.html
fast/xpath/py-dom-xpath/functions.html
fast/xpath/py-dom-xpath/nodetests.html
fast/xpath/py-dom-xpath/paths.html
fast/xpath/py-dom-xpath/predicates.html

Fix bugs found with this test suite:

  • name and local-name were incorrect for processing instructions (XPath expanded-name doesn't match DOM exactly);
  • name, local-name and namespace functions should crash on attribute nodes;
  • attemps to make node sets from other types were not detected as errors.

No performance impact.

  • xml/XPathExpressionNode.h: Track type conversion errors that happen during evaluation. An error won't stop evaluation, but an exception will be raised afterwards. We could also detect conversion errors at compile time, but not if we're going to support XPath variables (which is unnecessary for XPathEvaluator, but will be necessary if we decide to make our own XSLT one day).
  • xml/XPathExpression.cpp: (WebCore::XPathExpression::evaluate): Check whether a type conversion exception occurred during evaluation, and raise an excpetion if it did.
  • xml/XPathFunctions.cpp: (WebCore::XPath::expandedNameLocalPart): (WebCore::XPath::expandedName): XPath name(), local-name() and namespace-uri() functions are defined in terms of expanded-name, which doesn't match anything available via DOM exactly. Calculate the expanded name properly. (WebCore::XPath::FunNamespaceURI::evaluate): This function could crash if used with an attribute node, because it released what was possibly the only reference to attribute node before using it. Changed the function to avoid such situation. (WebCore::XPath::FunLocalName::evaluate): Ditto. Also, used the new expandedNameLocalPart() to work properly with processing instruction nodes. (WebCore::XPath::FunName::evaluate): Ditto (using expandedName()). (WebCore::XPath::FunCount::evaluate): Signal an error if the argument is not a node-set (by using toNodeSet unconditionally, which will raise an error, and return an empty set).
  • xml/XPathPath.cpp: (WebCore::XPath::Filter::evaluate): Signal an error if the expression evaluation result is not a node-set.
  • xml/XPathPath.h: (WebCore::XPath::Filter::resultType): A Filter's result is actually always a node-set (this is not so for FilterExpr production in the spec, but is for us, because we don't naively map BNF productions to classes).
  • xml/XPathPredicate.cpp: (WebCore::XPath::Union::evaluate): Signal an error if either side is not a node-set.
  • xml/XPathStep.cpp: Removed an unnecesary include.
  • xml/XPathValue.cpp: (WebCore::XPath::Value::toNodeSet): Signal an error if conversion fails. (WebCore::XPath::Value::modifiableNodeSet): Ditto. (WebCore::XPath::Value::toNumber): Don't allow inputs that don't match XPath Number production (in particular, those using exponential notation).
  • Property svn:eol-style set to native
File size: 3.4 KB
Line 
1/*
2 * Copyright (C) 2005 Frerich Raabe <[email protected]>
3 * Copyright (C) 2006, 2009 Apple Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "config.h"
28#include "XPathExpression.h"
29
30#if ENABLE(XPATH)
31
32#include "Document.h"
33#include "PlatformString.h"
34#include "XPathException.h"
35#include "XPathExpressionNode.h"
36#include "XPathNSResolver.h"
37#include "XPathParser.h"
38#include "XPathResult.h"
39#include "XPathUtil.h"
40
41namespace WebCore {
42
43using namespace XPath;
44
45PassRefPtr<XPathExpression> XPathExpression::createExpression(const String& expression, XPathNSResolver* resolver, ExceptionCode& ec)
46{
47 RefPtr<XPathExpression> expr = XPathExpression::create();
48 Parser parser;
49
50 expr->m_topExpression = parser.parseStatement(expression, resolver, ec);
51 if (!expr->m_topExpression)
52 return 0;
53
54 return expr.release();
55}
56
57XPathExpression::~XPathExpression()
58{
59 delete m_topExpression;
60}
61
62PassRefPtr<XPathResult> XPathExpression::evaluate(Node* contextNode, unsigned short type, XPathResult*, ExceptionCode& ec)
63{
64 if (!isValidContextNode(contextNode)) {
65 ec = NOT_SUPPORTED_ERR;
66 return 0;
67 }
68
69 EvaluationContext& evaluationContext = Expression::evaluationContext();
70 evaluationContext.node = contextNode;
71 evaluationContext.size = 1;
72 evaluationContext.position = 1;
73 evaluationContext.hadTypeConversionError = false;
74 RefPtr<XPathResult> result = XPathResult::create(contextNode->document(), m_topExpression->evaluate());
75 evaluationContext.node = 0; // Do not hold a reference to the context node, as this may prevent the whole document from being destroyed in time.
76
77 if (evaluationContext.hadTypeConversionError) {
78 // It is not specified what to do if type conversion fails while evaluating an expression, and INVALID_EXPRESSION_ERR is not exactly right
79 // when the failure happens in an otherwise valid expression because of a variable. But XPathEvaluator does not support variables, so it's close enough.
80 ec = XPathException::INVALID_EXPRESSION_ERR;
81 return 0;
82 }
83
84 if (type != XPathResult::ANY_TYPE) {
85 ec = 0;
86 result->convertTo(type, ec);
87 if (ec)
88 return 0;
89 }
90
91 return result;
92}
93
94}
95
96#endif // ENABLE(XPATH)
Note: See TracBrowser for help on using the repository browser.