Skip to content

Don't treat an escaped * as the universal selector or wildcard - #206

Merged
wRAR merged 1 commit into
scrapy:masterfrom
itecz26:escaped-star-ident
Oct 19, 2026
Merged

wRAR merged 1 commit into
scrapy:masterfrom
itecz26:escaped-star-ident

Conversation

@itecz26

@itecz26 itecz26 commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

An escaped * is parsed as the * delimiter

parse_simple_selector() and parse_attrib() compare the decoded token value with "*" without looking at the token type, so \* or \2a (an IDENT whose value is *) is handled like a bare *:

>>> GenericTranslator().css_to_xpath(r"\*")
'descendant-or-self::*'                                # matches every element
>>> GenericTranslator().css_to_xpath(r"ns|\*")
"descendant-or-self::*[name() = 'ns:*']"               # matches nothing
>>> GenericTranslator().css_to_xpath(r"\*|a")
"descendant-or-self::*[local-name() = 'a']"            # any namespace
>>> GenericTranslator().css_to_xpath(r"[\*|x]")
"descendant-or-self::*[attribute::*[local-name() = 'x']]"

In CSS an escaped character is never a delimiter, so \* is a type selector for elements named * and matches nothing, which is what ns|\* already does. For anyone translating selectors they did not write, a selector that should match nothing currently matches the whole document. With the fix, an escaped * in element position becomes a name() = '*' test like other unsafe names. In namespace-prefix position it raises SelectorSyntaxError, because Element and Attrib use the string "*" for the wildcard and no XPath prefix can be * anyway. A bare * and *|a are unchanged.

@codecov

codecov Bot commented Oct 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.79%. Comparing base (ec61e4b) to head (400c1e6).

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #206   +/-   ##
=======================================
  Coverage   99.79%   99.79%           
=======================================
  Files           3        3           
  Lines         987      991    +4     
  Branches      162      164    +2     
=======================================
+ Hits          985      989    +4     
  Misses          1        1           
  Partials        1        1           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@wRAR
wRAR merged commit ef38db1 into scrapy:master Oct 19, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants