Skip to content

Accept only ASCII digits in :nth-*() series - #205

Merged
wRAR merged 1 commit into
scrapy:masterfrom
itecz26:series-ascii-digits
Oct 19, 2026
Merged

wRAR merged 1 commit into
scrapy:masterfrom
itecz26:series-ascii-digits

Conversation

@itecz26

@itecz26 itecz26 commented Oct 17, 2026

Copy link
Copy Markdown
Contributor

:nth-*() series accept non-ASCII digits and digit separators

parse_series() converts the a and b parts of an An+B argument with Python's int(), which also accepts any Unicode decimal digit and _ separators. Non-ASCII characters tokenize as an IDENT, so they reach parse_series() and get turned into a position:

>>> GenericTranslator().css_to_xpath("p:nth-child(٣)")   # ARABIC-INDIC DIGIT THREE
'descendant-or-self::p[count(preceding-sibling::*) = 2]'
>>> GenericTranslator().css_to_xpath("p:nth-child(3)")   # FULLWIDTH DIGIT THREE
'descendant-or-self::p[count(preceding-sibling::*) = 2]'
>>> GenericTranslator().css_to_xpath("p:nth-child(2n+1_0)")
'descendant-or-self::p[(count(preceding-sibling::*) >= 9) and ((count(preceding-sibling::*) +1) mod 2 = 0)]'

The An+B microsyntax (CSS Syntax §6) is built from number and ident tokens with ASCII digits only, so browsers reject these selectors as invalid instead of matching the 3rd or 10th child. Anything that validates a selector with a browser or another CSS parser and then runs it through cssselect (or the other way round) sees two different meanings for the same string. The integer parts are now checked against [+-]?[0-9]+ before int(), so these raise ExpressionError like other invalid series; ASCII input is unaffected and the existing tests pass unchanged. Regression assertions are added to test_series.

@codecov

codecov Bot commented Oct 17, 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 (10f156b).

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #205   +/-   ##
=======================================
  Coverage   99.79%   99.79%           
=======================================
  Files           3        3           
  Lines         987      992    +5     
  Branches      162      163    +1     
=======================================
+ Hits          985      990    +5     
  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 5c8aeff 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