fix: Prevent exponential type re-traversal in SwiftCxxBridgedType#1387
Open
puckey wants to merge 2 commits into
Open
fix: Prevent exponential type re-traversal in SwiftCxxBridgedType#1387puckey wants to merge 2 commits into
puckey wants to merge 2 commits into
Conversation
`getRequiredImports()` and `getExtraFiles()` in nitrogen's `SwiftCxxBridgedType` (the TypeScript class that generates the Swift <-> C++ bridge code) have no protection against re-traversing the same type from multiple paths in the type graph, causing exponential blowup and a "Maximum call stack size exceeded" crash for projects with many interconnected struct types. mrousavy#1247 added a visited-set guard to the equivalent `KotlinCxxBridgedType`; this applies the same per-call-tree visited-set guard to `SwiftCxxBridgedType`, which still crashes on large specs. Fixes mrousavy#1079
…raversal A 7-struct graph where multiple structs reference the same shared types from many paths. Without the visited-set guard in SwiftCxxBridgedType, nitrogen crashes with "RangeError: Maximum call stack size exceeded" when generating the iOS autolinking bridge for this spec.
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
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.
#1247 fixed the
Maximum call stack size exceededcrash in nitrogen by adding a visited set toKotlinCxxBridgedType— but the same unguarded recursion exists inSwiftCxxBridgedType, the class that generates the Swift ↔ C++ bridge.getRequiredImports()andgetExtraFiles()re-traverse shared types from every path in the type graph, so for specs with many interconnected structs, nitrogen still crashes on currentmainwhile generating the iOS autolinking bridge:This PR applies the same per-call-tree visited-set guard to
SwiftCxxBridgedType. The actual fix is one file (+15/−5); everything else is the regression test and its generated output.Fixes #1079.
Real-world impact: react-native-iap currently works around this by raising Node's stack size to 64 MB (commit), and react-native-audio-browser ships a vendored patched build of nitrogen just to work around the same crash.
Test plan
Gallerygraph to the test specs, where multiple structs reference the same shared types from many paths (the shape that triggers the exponential blowup)main,bun run specscrashes withRangeError: Maximum call stack size exceededtscand eslint passExtracted from #1232 so the crash fix can land independently of the cyclic-struct discussion there.