Skip to content

Commit 7c6ae2e

Browse files
committed
Ensure the temporary corruption of internal state goes unnoticed
1 parent 26b5864 commit 7c6ae2e

File tree

2 files changed

+13
-5
lines changed

2 files changed

+13
-5
lines changed

packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMNode-test.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,7 @@ describe('ReactFlightDOMNode', () => {
809809
resolvePendingPromise = value => {
810810
p2.status = 'fulfilled';
811811
p2.value = value;
812+
resolve(value);
812813
};
813814
});
814815
const p3 = new Promise(() => {});
@@ -888,11 +889,11 @@ describe('ReactFlightDOMNode', () => {
888889
},
889890
);
890891

892+
resolvePendingPromise('custom-instrum-resolve');
891893
await serverAct(
892894
async () =>
893895
new Promise(resolve => {
894896
setImmediate(() => {
895-
resolvePendingPromise();
896897
clientAbortController.abort();
897898
resolve();
898899
});
@@ -908,7 +909,7 @@ describe('ReactFlightDOMNode', () => {
908909
expect(normalizeCodeLocInfo(componentStack)).toBe(
909910
'\n' +
910911
' in SharedComponent (at **)\n' +
911-
' in ServerComponent\n' +
912+
' in ServerComponent (at **)\n' +
912913
' in Suspense\n' +
913914
' in body\n' +
914915
' in html\n' +
@@ -932,8 +933,8 @@ describe('ReactFlightDOMNode', () => {
932933
// The concrete location may change as this test is updated.
933934
// Just make sure they still point at React.use(p2)
934935
'\n at SharedComponent (./ReactFlightDOMNode-test.js:794:7)' +
935-
'\n at ServerComponent (file://./ReactFlightDOMNode-test.js:815:26)' +
936-
'\n at App (file://./ReactFlightDOMNode-test.js:832:25)',
936+
'\n at ServerComponent (file://./ReactFlightDOMNode-test.js:816:26)' +
937+
'\n at App (file://./ReactFlightDOMNode-test.js:833:25)',
937938
);
938939
} else {
939940
expect(ownerStack).toBeNull();
@@ -1538,7 +1539,7 @@ describe('ReactFlightDOMNode', () => {
15381539
'\n' +
15391540
' in body\n' +
15401541
' in html\n' +
1541-
' in ClientRoot (ReactFlightDOMNode-test.js:1486:16)',
1542+
' in ClientRoot (ReactFlightDOMNode-test.js:1487:16)',
15421543
);
15431544
}
15441545

packages/react-server/src/ReactFizzThenable.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,12 +255,19 @@ export function ensureSuspendableThenableStateDEV(
255255
): () => void {
256256
if (__DEV__) {
257257
const lastThenable = thenableState[thenableState.length - 1];
258+
// Reset the last thenable back to pending.
258259
switch (lastThenable.status) {
259260
case 'fulfilled':
260261
const previousThenableValue = lastThenable.value;
262+
const previousThenableThen = lastThenable.then;
261263
delete lastThenable.value;
262264
delete (lastThenable: any).status;
265+
// We'll call .then again if we resuspend. Since we potentially corrupted
266+
// the internal state of unknown classes, we need to diffuse the potential
267+
// crash by replacing the .then method with a noop.
268+
lastThenable.then = noop;
263269
return () => {
270+
lastThenable.then = previousThenableThen.bind(lastThenable);
264271
lastThenable.value = previousThenableValue;
265272
lastThenable.status = 'fulfilled';
266273
};

0 commit comments

Comments
 (0)