From 6dbeb12cafe7a9cad58ec97578bed8ade080d18c Mon Sep 17 00:00:00 2001 From: rubennorte Date: Fri, 10 Nov 2023 15:53:53 +0000 Subject: [PATCH] Guard against unmounted components when accessing public instances on Fabric (#27687) ## Summary This fixes an error in `getPublicInstanceFromInstanceHandle` where we throw an error when trying to access the public instance from the fiber of an unmounted component. This shouldn't throw but return `null` instead. ## How did you test this change? Updated unit tests. Before: Screenshot 2023-11-10 at 15 26 14 After: Screenshot 2023-11-10 at 15 28 37 DiffTrain build for commit https://github.com/facebook/react/commit/6b3834a45b585e4340734139841ae81dc1b1a75d. --- .../cjs/ReactTestRenderer-dev.js | 2 +- .../cjs/ReactTestRenderer-prod.js | 4 +-- .../cjs/ReactTestRenderer-profiling.js | 4 +-- .../RKJSModules/vendor/react/cjs/React-dev.js | 2 +- .../vendor/react/cjs/React-prod.js | 2 +- .../vendor/react/cjs/React-profiling.js | 2 +- .../Libraries/Renderer/REVISION | 2 +- .../implementations/ReactFabric-dev.fb.js | 17 ++++++++---- .../implementations/ReactFabric-prod.fb.js | 27 ++++++++++--------- .../ReactFabric-profiling.fb.js | 27 ++++++++++--------- .../Renderer/shims/ReactNativeTypes.js | 4 +-- 11 files changed, 51 insertions(+), 42 deletions(-) diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-dev.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-dev.js index 469f17423f..7d86f9e3b0 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-dev.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-dev.js @@ -25474,7 +25474,7 @@ if (__DEV__) { return root; } - var ReactVersion = "18.3.0-canary-6a7f3aa85-20231110"; + var ReactVersion = "18.3.0-canary-6b3834a45-20231110"; // Might add PROFILE later. diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-prod.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-prod.js index d0f4dd2a27..ebb294d2b7 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-prod.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-prod.js @@ -9083,7 +9083,7 @@ var devToolsConfig$jscomp$inline_1033 = { throw Error("TestRenderer does not support findFiberByHostInstance()"); }, bundleType: 0, - version: "18.3.0-canary-6a7f3aa85-20231110", + version: "18.3.0-canary-6b3834a45-20231110", rendererPackageName: "react-test-renderer" }; var internals$jscomp$inline_1226 = { @@ -9114,7 +9114,7 @@ var internals$jscomp$inline_1226 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.3.0-canary-6a7f3aa85-20231110" + reconcilerVersion: "18.3.0-canary-6b3834a45-20231110" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { var hook$jscomp$inline_1227 = __REACT_DEVTOOLS_GLOBAL_HOOK__; diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-profiling.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-profiling.js index bc458bb672..0d6da210fa 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-profiling.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react-test-renderer/cjs/ReactTestRenderer-profiling.js @@ -9509,7 +9509,7 @@ var devToolsConfig$jscomp$inline_1075 = { throw Error("TestRenderer does not support findFiberByHostInstance()"); }, bundleType: 0, - version: "18.3.0-canary-6a7f3aa85-20231110", + version: "18.3.0-canary-6b3834a45-20231110", rendererPackageName: "react-test-renderer" }; var internals$jscomp$inline_1267 = { @@ -9540,7 +9540,7 @@ var internals$jscomp$inline_1267 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.3.0-canary-6a7f3aa85-20231110" + reconcilerVersion: "18.3.0-canary-6b3834a45-20231110" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { var hook$jscomp$inline_1268 = __REACT_DEVTOOLS_GLOBAL_HOOK__; diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-dev.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-dev.js index 8123b84391..5281139037 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-dev.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-dev.js @@ -24,7 +24,7 @@ if (__DEV__) { ) { __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error()); } - var ReactVersion = "18.3.0-canary-6a7f3aa85-20231110"; + var ReactVersion = "18.3.0-canary-6b3834a45-20231110"; // ATTENTION // When adding new symbols to this file, diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-prod.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-prod.js index 45a997dce6..e436324d4d 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-prod.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-prod.js @@ -580,4 +580,4 @@ exports.useSyncExternalStore = function ( exports.useTransition = function () { return ReactCurrentDispatcher.current.useTransition(); }; -exports.version = "18.3.0-canary-6a7f3aa85-20231110"; +exports.version = "18.3.0-canary-6b3834a45-20231110"; diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-profiling.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-profiling.js index 61d4b5b152..ce25bf225c 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-profiling.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/cjs/React-profiling.js @@ -576,7 +576,7 @@ exports.useSyncExternalStore = function ( exports.useTransition = function () { return ReactCurrentDispatcher.current.useTransition(); }; -exports.version = "18.3.0-canary-6a7f3aa85-20231110"; +exports.version = "18.3.0-canary-6b3834a45-20231110"; "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/REVISION b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/REVISION index 4ddf172a6d..15dbb2f076 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/REVISION +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/REVISION @@ -1 +1 @@ -6a7f3aa858b3a8670d6a4861e30f248b335e55bd +6b3834a45b585e4340734139841ae81dc1b1a75d diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-dev.fb.js b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-dev.fb.js index 5e8d250cb7..7b35a30d43 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-dev.fb.js +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-dev.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<82de3c20128bc9cf9a3e000de26414a9>> + * @generated SignedSource<<35562a820289897947536c61435e3dcd>> */ "use strict"; @@ -5111,13 +5111,20 @@ to return true:wantsResponderID| | function getPublicInstanceFromInternalInstanceHandle( internalInstanceHandle ) { + var instance = internalInstanceHandle.stateNode; // React resets all the fields in the fiber when the component is unmounted + // to prevent memory leaks. + + if (instance == null) { + return null; + } + if (internalInstanceHandle.tag === HostText) { - var textInstance = internalInstanceHandle.stateNode; + var textInstance = instance; return getPublicTextInstance(textInstance, internalInstanceHandle); } - var instance = internalInstanceHandle.stateNode; - return getPublicInstance(instance); + var elementInstance = internalInstanceHandle.stateNode; + return getPublicInstance(elementInstance); } function shouldSetTextContent(type, props) { // TODO (bvaughn) Revisit this decision. @@ -27805,7 +27812,7 @@ to return true:wantsResponderID| | return root; } - var ReactVersion = "18.3.0-canary-8403dc9a"; + var ReactVersion = "18.3.0-canary-884b3517"; function createPortal$1( children, diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-prod.fb.js b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-prod.fb.js index 22705b85a5..5e56126c15 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-prod.fb.js +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-prod.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<215b578b886f3eeea52b84f72bb15ec6>> + * @generated SignedSource<> */ "use strict"; @@ -9541,7 +9541,7 @@ var roots = new Map(), devToolsConfig$jscomp$inline_1048 = { findFiberByHostInstance: getInstanceFromNode, bundleType: 0, - version: "18.3.0-canary-1b86ce9f", + version: "18.3.0-canary-8f9ce9e2", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForInstance: getInspectorDataForInstance, @@ -9584,7 +9584,7 @@ var internals$jscomp$inline_1290 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.3.0-canary-1b86ce9f" + reconcilerVersion: "18.3.0-canary-8f9ce9e2" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { var hook$jscomp$inline_1291 = __REACT_DEVTOOLS_GLOBAL_HOOK__; @@ -9643,16 +9643,17 @@ exports.getNodeFromInternalInstanceHandle = function (internalInstanceHandle) { exports.getPublicInstanceFromInternalInstanceHandle = function ( internalInstanceHandle ) { - if (6 === internalInstanceHandle.tag) { - var textInstance = internalInstanceHandle.stateNode; - null == textInstance.publicInstance && - (textInstance.publicInstance = - ReactNativePrivateInterface.createPublicTextInstance( - internalInstanceHandle - )); - return textInstance.publicInstance; - } - return getPublicInstance(internalInstanceHandle.stateNode); + var instance = internalInstanceHandle.stateNode; + return null == instance + ? null + : 6 === internalInstanceHandle.tag + ? (null == instance.publicInstance && + (instance.publicInstance = + ReactNativePrivateInterface.createPublicTextInstance( + internalInstanceHandle + )), + instance.publicInstance) + : getPublicInstance(internalInstanceHandle.stateNode); }; exports.render = function (element, containerTag, callback, concurrentRoot) { var root = roots.get(containerTag); diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js index 6f87dafeb3..66ac0c3762 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<443d6fa46938bdd4041f48305e367a13>> + * @generated SignedSource<> */ "use strict"; @@ -10243,7 +10243,7 @@ var roots = new Map(), devToolsConfig$jscomp$inline_1126 = { findFiberByHostInstance: getInstanceFromNode, bundleType: 0, - version: "18.3.0-canary-5ad064e7", + version: "18.3.0-canary-8a2d4f06", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForInstance: getInspectorDataForInstance, @@ -10299,7 +10299,7 @@ var roots = new Map(), scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.3.0-canary-5ad064e7" + reconcilerVersion: "18.3.0-canary-8a2d4f06" }); exports.createPortal = function (children, containerTag) { return createPortal$1( @@ -10345,16 +10345,17 @@ exports.getNodeFromInternalInstanceHandle = function (internalInstanceHandle) { exports.getPublicInstanceFromInternalInstanceHandle = function ( internalInstanceHandle ) { - if (6 === internalInstanceHandle.tag) { - var textInstance = internalInstanceHandle.stateNode; - null == textInstance.publicInstance && - (textInstance.publicInstance = - ReactNativePrivateInterface.createPublicTextInstance( - internalInstanceHandle - )); - return textInstance.publicInstance; - } - return getPublicInstance(internalInstanceHandle.stateNode); + var instance = internalInstanceHandle.stateNode; + return null == instance + ? null + : 6 === internalInstanceHandle.tag + ? (null == instance.publicInstance && + (instance.publicInstance = + ReactNativePrivateInterface.createPublicTextInstance( + internalInstanceHandle + )), + instance.publicInstance) + : getPublicInstance(internalInstanceHandle.stateNode); }; exports.render = function (element, containerTag, callback, concurrentRoot) { var root = roots.get(containerTag); diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/shims/ReactNativeTypes.js b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/shims/ReactNativeTypes.js index c36c6bc9a8..e994301ee6 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/shims/ReactNativeTypes.js +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/shims/ReactNativeTypes.js @@ -7,7 +7,7 @@ * @noformat * @flow strict * @nolint - * @generated SignedSource<<652b117c94307244bcf5e4af18928903>> + * @generated SignedSource<<1836a1b6639552dce12199ef2c85f63d>> */ import type {ElementRef, ElementType, Element, AbstractComponent} from 'react'; @@ -247,7 +247,7 @@ export type ReactFabricType = { ): ?Node, getPublicInstanceFromInternalInstanceHandle( internalInstanceHandle: InternalInstanceHandle, - ): PublicInstance | PublicTextInstance, + ): PublicInstance | PublicTextInstance | null, ... };