Commit fd9f8312 authored by ap's avatar ap

Reviewed by Darin.

        http://bugs.webkit.org/show_bug.cgi?id=12359
        XPathEvaluator may return some nodes more than once in a result set

        Test: fast/xpath/nodeset-duplicates.html

        * xml/XPathPath.cpp:
        (WebCore::XPath::LocationPath::doEvaluate): Ensure uniqueness of elements
        in the node-set.

        * xml/XPathPredicate.cpp:
        (WebCore::XPath::Union::doEvaluate): Fixed a uniqueness algorithm that was
        already present here. Added a FIXME about incorrect result ordering.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@19227 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent af0e1445
2007-01-29 Alexey Proskuryakov <ap@webkit.org>
Reviewed by Darin.
http://bugs.webkit.org/show_bug.cgi?id=12359
XPathEvaluator may return some nodes more than once in a result set
* fast/xpath/nodeset-duplicates-expected.txt: Added.
* fast/xpath/nodeset-duplicates.html: Added.
2007-01-29 Alexey Proskuryakov <ap@webkit.org>
Reviewed by Darin.
Test for bug 12359: XPathEvaluator may return some nodes more than once in a result set.
SUCCESS
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<body>
<p>Test for <a href="http://bugs.webkit.org/show_bug.cgi?id=12359">bug 12359</a>:
XPathEvaluator may return some nodes more than once in a result set.</p>
<div>
<div>
<div></div>
</div>
</div>
<script type="text/javascript">
if (window.layoutTestController)
layoutTestController.dumpAsText();
try {
var result = document.evaluate("//div//div | //div/div", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
if (result.snapshotLength == 2)
document.write("SUCCESS");
else
document.write(result.snapshotLength + " matches (should be 2)");
} catch (ex) {
document.write("Exception: " + ex);
}
</script>
</body>
</html>
2007-01-29 Alexey Proskuryakov <ap@webkit.org>
Reviewed by Darin.
http://bugs.webkit.org/show_bug.cgi?id=12359
XPathEvaluator may return some nodes more than once in a result set
Test: fast/xpath/nodeset-duplicates.html
* xml/XPathPath.cpp:
(WebCore::XPath::LocationPath::doEvaluate): Ensure uniqueness of elements
in the node-set.
* xml/XPathPredicate.cpp:
(WebCore::XPath::Union::doEvaluate): Fixed a uniqueness algorithm that was
already present here. Added a FIXME about incorrect result ordering.
2007-01-29 Alexey Proskuryakov <ap@webkit.org>
Reviewed by Darin.
......
......@@ -94,7 +94,7 @@ void LocationPath::optimize()
Value LocationPath::doEvaluate() const
{
NodeVector inDomNodes, outDomNodes;
NodeVector inDOMNodes;
/* For absolute location paths, the context node is ignored - the
* document's root node is used instead.
......@@ -103,22 +103,27 @@ Value LocationPath::doEvaluate() const
if (m_absolute && context->nodeType() != Node::DOCUMENT_NODE)
context = context->ownerDocument();
inDomNodes.append(context);
inDOMNodes.append(context);
for (unsigned i = 0; i < m_steps.size(); i++) {
Step* step = m_steps[i];
NodeVector outDOMNodes;
HashSet<Node*> outDOMNodesSet;
for (unsigned j = 0; j < inDomNodes.size(); j++) {
NodeVector matches = step->evaluate(inDomNodes[j].get());
for (unsigned j = 0; j < inDOMNodes.size(); j++) {
NodeVector matches = step->evaluate(inDOMNodes[j].get());
outDomNodes.append(matches);
for (size_t nodeIndex = 0; nodeIndex < matches.size(); ++nodeIndex) {
Node* node = matches[nodeIndex].get();
if (outDOMNodesSet.add(node).second)
outDOMNodes.append(node);
}
}
inDomNodes = outDomNodes;
outDomNodes.clear();
inDOMNodes = outDOMNodes;
}
return inDomNodes;
return inDOMNodes;
}
Path::Path(Filter* filter, LocationPath* path)
......
......@@ -183,6 +183,7 @@ Value LogicalOp::doEvaluate() const
Value Union::doEvaluate() const
{
// FIXME: This algorithm doesn't return nodes in document order, as it should.
Value lhs = subExpr(0)->evaluate();
Value rhs = subExpr(1)->evaluate();
if (!lhs.isNodeVector() || !rhs.isNodeVector())
......@@ -193,14 +194,13 @@ Value Union::doEvaluate() const
NodeVector result = lhsNodes;
HashSet<Node*> nodes;
for (size_t i = 0; i < result.size(); ++i)
nodes.add(result[i].get());
for (unsigned i = 0; i < rhsNodes.size(); i++) {
for (size_t i = 0; i < rhsNodes.size(); ++i) {
Node* node = rhsNodes[i].get();
if (!nodes.contains(node)) {
if (nodes.add(node).second)
result.append(node);
nodes.add(node);
}
}
return result;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment