Skip to content

Commit bdf6305

Browse files
authored
script: Don't try to evaluate xpath variable references (servo#39395)
Variables in xpath via the javascript bindings are a bit mysterious, as there is no way that a variable can be specified. We currently panic when encountering a variable, which is not good. Instead we now throw an error. We keep parsing the variables because the code is already there and it seems realistic that their behaviour will be specified in the future. I'm fine with removing them too if that is preferred. Testing: This behaviour is unspecified and different browser produce different results. There is no "correct" way to do this, but we should not crash Part of: servo#34527 --------- Signed-off-by: Simon Wülker <[email protected]>
1 parent e2241a9 commit bdf6305

File tree

3 files changed

+27
-5
lines changed

3 files changed

+27
-5
lines changed

components/script/xpath/eval.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,12 @@ pub(crate) enum Error {
3333
UnknownFunction {
3434
name: QualName,
3535
},
36-
UnknownVariable {
37-
name: QualName,
38-
},
36+
/// It is not clear where variables used in XPath expression should come from.
37+
/// Firefox throws "NS_ERROR_ILLEGAL_VALUE" when using them, chrome seems to return
38+
/// an empty result. We also error out.
39+
///
40+
/// See <https://github.com/whatwg/dom/issues/67>
41+
CannotUseVariables,
3942
UnknownNamespace {
4043
prefix: String,
4144
},
@@ -58,7 +61,7 @@ impl std::fmt::Display for Error {
5861
Error::NotANodeset => write!(f, "expression did not evaluate to a nodeset"),
5962
Error::InvalidPath => write!(f, "invalid path expression"),
6063
Error::UnknownFunction { name } => write!(f, "unknown function {:?}", name),
61-
Error::UnknownVariable { name } => write!(f, "unknown variable {:?}", name),
64+
Error::CannotUseVariables => write!(f, "cannot use variables"),
6265
Error::UnknownNamespace { prefix } => {
6366
write!(f, "unknown namespace prefix {:?}", prefix)
6467
},
@@ -745,7 +748,7 @@ impl Evaluatable for PrimaryExpr {
745748
fn evaluate(&self, context: &EvaluationCtx) -> Result<Value, Error> {
746749
match self {
747750
PrimaryExpr::Literal(literal) => literal.evaluate(context),
748-
PrimaryExpr::Variable(_qname) => todo!(),
751+
PrimaryExpr::Variable(_qname) => Err(Error::CannotUseVariables),
749752
PrimaryExpr::Parenthesized(expr) => expr.evaluate(context),
750753
PrimaryExpr::ContextItem => Ok(Value::Nodeset(vec![context.context_node.clone()])),
751754
PrimaryExpr::Function(core_function) => core_function.evaluate(context),

tests/wpt/meta/MANIFEST.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7036,6 +7036,13 @@
70367036
]
70377037
},
70387038
"domxpath": {
7039+
"variables-in-expression-crash.html": [
7040+
"d1f15a6abe0d9c8ecae08b4cdf5dd9ef3efbbbcc",
7041+
[
7042+
null,
7043+
{}
7044+
]
7045+
],
70397046
"xpath-evaluate-crash.html": [
70407047
"5303d85ad31ca0ee230ac36231898342b07ad2c3",
70417048
[
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
3+
<head>
4+
<link rel="help" href="https://github.com/servo/servo/issues/36971">
5+
<meta name="assert" content="Using variables in xpath expression should not crash.">
6+
</head>
7+
<body>
8+
<script>
9+
// The exact behaviour here is not defined. Firefox throws an error, Chrome doesn't.
10+
document.evaluate("$foo", document.createElement("div"));
11+
</script>
12+
</body>

0 commit comments

Comments
 (0)