Skip to content

Fix ReDoS hang in dimension shorthand expansion - #191

Merged
grosser merged 1 commit into
masterfrom
grosser/redos-fix
Sep 20, 2026
Merged

grosser merged 1 commit into
masterfrom
grosser/redos-fix

Conversation

@grosser

@grosser grosser commented Sep 20, 2026

Copy link
Copy Markdown
Contributor

RE_FUNCTIONS (used by expand_dimensions_shorthand!) backtracked exponentially on unclosed CSS functions: ~30 bytes like margin: x() calc(aaaa... pinned a CPU for hours. (The x() prefix gets the value past the unmatched_open_parenthesis? check in parse_declarations!.)

  • regex: recursion-first alternation + possessive quantifiers, so failed matches cost O(n) per attempt instead of O(2^n); a function name before ( is never swallowed by a possessive text run, keeping nested calc(var(...)) matching intact
  • 10ms regexp timeout as backstop: on timeout, fall back to plain whitespace splitting so hostile values mis-render instead of hanging the process (budget covers a whole scan, so residual quadratic cost is capped too)
  • no output change on benign values (verified against the old regex on nested calc/var/url cases); regexp speed within ~10-25% of the old one

Pre-Merge Checklist

  • CHANGELOG.md updated with short summary

RE_FUNCTIONS backtracked exponentially on unclosed CSS functions
(e.g. `margin: x() calc(aaaa...)`), pinning a CPU on a few dozen
bytes of input.

- recursion-first alternation + possessive quantifiers: failed
  matches cost O(n) per attempt instead of O(2^n)
- 10ms regexp timeout as backstop, falls back to plain whitespace
  splitting so hostile values mis-render instead of hanging
@grosser
grosser marked this pull request as ready for review September 20, 2026 23:23
@grosser
grosser merged commit 4d09a2d into master Sep 20, 2026
5 checks passed
@grosser
grosser deleted the grosser/redos-fix branch September 20, 2026 23:23
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