Commit 6baf6f98 authored by Kent Tamura's avatar Kent Tamura Committed by Commit Bot

XPath: Fix context node of rhs of union operator

The new behavior matches to Edge and Firefox.

Bug: 908632
Change-Id: I0dbb861e93836284a0c474cc486650dab27dc7b4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1973333
Commit-Queue: Kent Tamura <tkent@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#726224}
parent b943c6bf
...@@ -232,10 +232,16 @@ Value LogicalOp::Evaluate(EvaluationContext& context) const { ...@@ -232,10 +232,16 @@ Value LogicalOp::Evaluate(EvaluationContext& context) const {
} }
Value Union::Evaluate(EvaluationContext& context) const { Value Union::Evaluate(EvaluationContext& context) const {
// SubExpr(0)->Evaluate() can change the context node, but SubExpr(1) should
// start with the current context node.
EvaluationContext cloned_context = context;
Value lhs_result = SubExpr(0)->Evaluate(context); Value lhs_result = SubExpr(0)->Evaluate(context);
Value rhs = SubExpr(1)->Evaluate(context); Value rhs = SubExpr(1)->Evaluate(cloned_context);
context.had_type_conversion_error |= cloned_context.had_type_conversion_error;
NodeSet& result_set = lhs_result.ModifiableNodeSet(context); NodeSet& result_set = lhs_result.ModifiableNodeSet(context);
// We should pass |&context|, not |&cloned_context|, in order to propagate
// a type conversion error to the parent context.
const NodeSet& rhs_nodes = rhs.ToNodeSet(&context); const NodeSet& rhs_nodes = rhs.ToNodeSet(&context);
HeapHashSet<Member<Node>> nodes; HeapHashSet<Member<Node>> nodes;
......
...@@ -112,7 +112,7 @@ class CORE_EXPORT Value { ...@@ -112,7 +112,7 @@ class CORE_EXPORT Value {
bool IsString() const { return type_ == kStringValue; } bool IsString() const { return type_ == kStringValue; }
// If this is called during XPathExpression::evaluate(), EvaluationContext // If this is called during XPathExpression::evaluate(), EvaluationContext
// should be passed. // should be passed to record type conversion error.
const NodeSet& ToNodeSet(EvaluationContext*) const; const NodeSet& ToNodeSet(EvaluationContext*) const;
NodeSet& ModifiableNodeSet(EvaluationContext&); NodeSet& ModifiableNodeSet(EvaluationContext&);
bool ToBoolean() const; bool ToBoolean() const;
......
<!DOCTYPE html>
<link rel="help" href="https://www.w3.org/TR/1999/REC-xpath-19991116/#node-sets">
<body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
function nodesetToSet(result) {
const set = new Set();
for (let node = result.iterateNext(); node; node = result.iterateNext()) {
set.add(node);
}
return set;
}
test(() => {
const doc = document.implementation.createHTMLDocument();
doc.documentElement.innerHTML = '<body><div></div></body>';
const result = nodesetToSet(doc.evaluate('(.//div)[1]|.', doc.documentElement));
assert_equals(result.size, 2);
assert_true(result.has(doc.documentElement));
assert_true(result.has(doc.body.firstChild));
}, '| operator should evaluate both sides of expressions with the same context node');
</script>
</body>
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