mirror of
https://github.com/zebrajr/react.git
synced 2026-01-15 12:15:22 +00:00
Improve cyclic thenable detection in ReactFlightReplyServer (#35369)
## Summary This PR improves cyclic thenable detection in `ReactFlightReplyServer.js`. Fixes #35368. The previous fix only detected direct self-references (`inspectedValue === chunk`) and relied on the `cycleProtection` counter to eventually bail out of longer cycles. This change keeps the existing MAX_THENABLE_CYCLE_DEPTH ($1000$) `cycleProtection` cap as a hard guardrail and adds a visited set so that we can detect self-cycles and multi-node cycles as soon as any `ReactPromise` is revisited and while still bounding the amount of work we do for deep acyclic chains via `cycleProtection`. ## How did you test this change? - Ran the existing test suite for the server renderer: ```bash yarn test react-server yarn test --prod react-server yarn flow dom-node yarn linc ``` --------- Co-authored-by: Hendrik Liebau <mail@hendrik-liebau.de>
This commit is contained in:
@@ -133,14 +133,20 @@ ReactPromise.prototype.then = function <T>(
|
||||
// Recursively check if the value is itself a ReactPromise and if so if it points
|
||||
// back to itself. This helps catch recursive thenables early error.
|
||||
let cycleProtection = 0;
|
||||
const visited = new Set<typeof ReactPromise>();
|
||||
while (inspectedValue instanceof ReactPromise) {
|
||||
cycleProtection++;
|
||||
if (inspectedValue === chunk || cycleProtection > 1000) {
|
||||
if (
|
||||
inspectedValue === chunk ||
|
||||
visited.has(inspectedValue) ||
|
||||
cycleProtection > 1000
|
||||
) {
|
||||
if (typeof reject === 'function') {
|
||||
reject(new Error('Cannot have cyclic thenables.'));
|
||||
}
|
||||
return;
|
||||
}
|
||||
visited.add(inspectedValue);
|
||||
if (inspectedValue.status === INITIALIZED) {
|
||||
inspectedValue = inspectedValue.value;
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user