Attribute regex test converts undefined attributes to strings
Closed this issue · 1 comments
When matching an attribute regex for an attribute that does not exist, esquery appears to test the regex on the string 'null'
. This can result in confusing false positives.
For example, I would expect the following selector to match any unicode regex literal:
Literal[regex.flags=/u/]
But it also matches all non-regex literals. This is because non-regex literals don't have a regex.flags
property, so the regex /u/
gets matched against null
, resulting in a successful match.
const esquery = require('esquery');
const espree = require('espree');
const selector = esquery.parse('Literal[regex.flags=/u/]');
const expressionStatement = espree.parse('1').body[0].expression;
esquery.matches(expressionStatement, selector) // => true
(Originally reported in eslint/eslint#8733)
esquery still regex matches against the string 'undefined'
for nodes that don't have the specified attribute.
For example:
In the demo, using the default code:
*
--> 44 nodes (all nodes)[name]
--> 14 nodes (14 nodes have a 'name' property)[name=undefined]
--> 30 nodes (14 nodes do not have a 'name' property)
Therefore,
[name=/f/]
--> 31 nodes (30 undefined + foo)
And if you actually just want to match any node that has a 'name' containing 'f', you use:
[name=/f/][name!=undefined]
--> 1 node (foo)
This holds true for any attribute name ('value', 'raw', 'operator', 'id', 'parms', etc.).
Even invalid attributes such as 'abc123{}^%$' or 'fakeAttr' will match against 'undefined'.
[fakeAttr=/u/]
--> 44 nodes (no node has a 'fakeAttr' property, so they all match against 'undefined')