Guard against stack overflow on deeply nested input#229
Open
bartveneman wants to merge 1 commit into
Open
Conversation
print_list, print_selector_list, print_block, print_rule and print_atrule recurse with the input's nesting depth and had no guard, so pathological input (thousands of nested rules, or deeply nested calc()/parentheses) crashed with an opaque, unhandled "Maximum call stack size exceeded" RangeError. Add an explicit recursion-depth guard, well below the real stack limit, so the printer throws a clear format-css-branded RangeError instead. Also wrap the initial parse() call: for extremely deep input the underlying parser can itself exceed the call stack before our own guard ever runs, so normalize that failure into the same kind of clear error.
Contributor
|
| 📦 Package | 📋 Versions |
|---|---|
| @babel/parser | 2 versions
|
| @babel/types | 2 versions
|
| @babel/helper-string-parser | 2 versions
|
| @babel/helper-validator-identifier | 2 versions
|
| @rolldown/binding-wasm32-wasi | 2 versions
|
| picomatch | 2 versions
|
| rolldown | 2 versions
|
| @oxc-project/types | 2 versions
|
| @rolldown/binding-android-arm64 | 2 versions
|
| @rolldown/binding-darwin-arm64 | 2 versions
|
| @rolldown/binding-darwin-x64 | 2 versions
|
| @rolldown/binding-freebsd-x64 | 2 versions
|
| @rolldown/binding-linux-arm-gnueabihf | 2 versions
|
| @rolldown/binding-linux-arm64-gnu | 2 versions
|
| @rolldown/binding-linux-arm64-musl | 2 versions
|
| @rolldown/binding-linux-ppc64-gnu | 2 versions
|
| @rolldown/binding-linux-s390x-gnu | 2 versions
|
| @rolldown/binding-linux-x64-gnu | 2 versions
|
| @rolldown/binding-linux-x64-musl | 2 versions
|
| @rolldown/binding-openharmony-arm64 | 2 versions
|
| @rolldown/binding-win32-arm64-msvc | 2 versions
|
| @rolldown/binding-win32-x64-msvc | 2 versions
|
💡 To find out what depends on a specific package, run: pnpm -r why example-package
⚠️ Package Size Increase
| 📦 Package | 📏 Base Size | 📏 Source Size | 📈 Size Change |
|---|---|---|---|
| @projectwallace/format-css | 8.6 kB | 8.8 kB | +236 B |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
print_list,print_selector_list,print_block,print_ruleandprint_atruleall recurse with the input's nesting depth and had no guard. Confirmed a crash with ~2,500 nested rules or deeply nestedcalc()/parentheses — an opaque, unhandledRangeError: Maximum call stack size exceeded.enter_recursion, capped at 250, tracked viatry/finallyso it always unwinds correctly on both success and error paths) so the printer throws a clearformat-css:-brandedRangeErrorinstead.parse()call from@projectwallace/css-parsercan itself exceed the call stack before our own guard ever runs, since parsing happens first. Wrapped that call so anyRangeErrorfrom parsing is normalized into the same kind of clear, catchable error rather than leaking the dependency's raw crash.Test plan
vitest run— all 258 tests pass (added 4 new cases covering deep rule nesting, deep paren nesting, recovery after a rejected input, and that realistic nesting depths still format fine)tsc --noEmit— no type errorsoxlint/oxfmt --check— cleanGenerated by Claude Code