Skip to content

fix(pseudos): avoid overlapping whitespace in nth parsing - #1909

Merged
fb55 merged 1 commit into
masterfrom
fix/nth-of-whitespace
Oct 9, 2026
Merged

fb55 merged 1 commit into
masterfrom
fix/nth-of-whitespace

Conversation

@fb55

@fb55 fb55 commented Oct 9, 2026 •

Copy link
Copy Markdown
Owner

The :nth-child(… of …) argument was split with ^(.+?)\s+of\s+(.+)$. Both .+? and \s+ can claim the same whitespace, so an argument made of a long run of spaces made the engine try every split before giving up, taking seconds for a few thousand spaces. ^(.+?\s)of\s+(.+)$ lets the lazy group own the whitespace, so there is one way to match and failure is immediate.

A test parses a 350,000-space argument and expects the parse error within a short timeout; on the previous pattern that input took minutes.

🤖 Generated with Claude Code

View guided diff Turn on auto-fix

Summary by CodeRabbit

  • Bug Fixes
    • Improved parsing of :nth-child expressions with whitespace before of, preventing excessive delays on very long inputs.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 9, 2026 22:09
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-09T22:11:39.115491Z b11676a PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 111b362e-cb8e-40c8-9ca1-c44e45c3e4a3

📥 Commits

Reviewing files that changed from the base of the PR and between 7db1b2c and b11676a.


📒 Files selected for processing (2)
  • src/pseudo-selectors/filters.ts
  • test/pseudo-classes.ts

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review.



📝 Walkthrough

Walkthrough

The nthOfRegex pattern now captures whitespace before of with the preceding selector expression. A regression test checks that compiling an :nth-child argument with 350,000 spaces throws the expected parse error within 2,000 ms.

Changes

Nth-child whitespace parsing

Layer / File(s) Summary
Whitespace parsing and regression test
src/pseudo-selectors/filters.ts, test/pseudo-classes.ts
The regex captures whitespace before of with the selector expression. The regression test checks the expected parse error for 350,000 spaces within 2,000 ms.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~8 minutes

Change: Bug fix · Severity of issue fixed: Low


Merge Risk: ⚪ Minimal · up to b1167

The change updates nth-of whitespace parsing and adds a targeted long-whitespace regression check. No material merge risk is identified in the supplied context.

Pre-merge checks | Passed 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: preventing overlapping whitespace during nth pseudo-selector parsing.
Docstring Coverage Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 2 files.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.


✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR

🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR


  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Warning

Some tools did not complete. Review the errors below.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

src/pseudo-selectors/filters.ts

ESLint skipped: missing config or dependency (missing-dependency). The ESLint configuration references a package that is not available in the sandbox.


test/pseudo-classes.ts

ESLint skipped: the matched ESLint configuration already failed (missing-dependency).




Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

A rabbit checks the parser’s pace,
As spaces stretch across the place.
The regex finds the boundary clear,
The expected error soon appears.
The rabbit hops, its test complete,
And leaves neat tracks with nimble feet.

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The focused regex change preserves parsing behavior while resolving the demonstrated performance issue with regression coverage.

0 open findings

What changed in this PR

Prevents excessive regex backtracking when parsing invalid :nth-child(... of ...) arguments.

Changes:

  • Reworks nthOfRegex to eliminate overlapping whitespace matching.
  • Adds a regression test using a long whitespace argument.
File Description
src/​pseudo-selectors/​filters.ts Makes nth-of parsing fail efficiently.
test/​pseudo-classes.ts Verifies prompt rejection of pathological input.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

View guided diff | Turn on auto-fix | Re-trigger cubic

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b11676a0bc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread test/pseudo-classes.ts
expect(() =>
CSSselect.compile(`:nth-child(${" ".repeat(350_000)})`),
).toThrow("n-th rule couldn't be parsed");
}, 2000);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Measure the synchronous parse duration explicitly

If this regex regresses to synchronous backtracking again, the parser blocks the event loop, so Vitest cannot fire this 2-second timeout; the test eventually completes and passes once compile() throws, even if that takes minutes. Vitest's own reproduction confirms that synchronous work completing after a test timeout is still reported as passing. As a result, this test does not enforce the performance property described by its name and comment; measure elapsed time explicitly or run the parse in a worker/subprocess that can be terminated.

Useful? React with 👍 / 👎.

@greptile-apps

greptile-apps Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[Medium impact] The PR appears safe to merge.

Summary

The PR removes overlapping whitespace matching from nthOfRegex.

  • Long whitespace in an nth argument reaches its parse error quickly.

Reviews (1) · Last reviewed commit: "fix(pseudos): avoid overlapping whitespa..." · Reviewed by Greptile

@fb55
fb55 merged commit b0a34d9 into master Oct 9, 2026
17 checks passed
@fb55
fb55 deleted the fix/nth-of-whitespace branch October 9, 2026 23:16
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.

2 participants