refactor[devtools]: forbid editing class instances in props (#26522)

## Summary
Fixes https://github.com/facebook/react/issues/24781

Restricting from editing props, which are class instances, because their
internals should be opaque.

Proposed changes:
1. Adding new data type `class_instance`: based on prototype chain of an
object we will check if its plain or not. If not, then will be marked as
`class_instance`. This should not affect `arrays`, ..., because we do
this in the end of an `object` case in `getDataType` function.

Important detail: this approach won't work for objects created with
`Object.create`, because of the custom prototype. This can also be
bypassed by manually deleting a prototype ¯\\\_(ツ)_/¯
I am not sure if there might be a better solution (which will cover all
cases) to detect if object is a class instance. Initially I was trying
to use `Object.getPrototypeOf(object) === Object.prototype`, but this
won't work for cases when we are dealing with `iframe`.

2. Objects with a type `class_instance` will be marked as unserializable
and read-only.

## Demo
`person` is a class instance, `object` is a plain object

https://user-images.githubusercontent.com/28902667/228914791-ebdc8ab0-eb5c-426d-8163-66d56b5e8790.mov

DiffTrain build for commit https://github.com/facebook/react/commit/b14f8da15598cdc2253529a905421ac795d68ab1.
This commit is contained in:
hoxyq
2023-04-03 10:38:50 +00:00
parent 44c0913b5c
commit 329d0832ec
13 changed files with 19 additions and 19 deletions
@@ -23882,7 +23882,7 @@ function createFiberRoot(
return root;
}
var ReactVersion = "18.3.0-next-7329ea81c-20230402";
var ReactVersion = "18.3.0-next-b14f8da15-20230403";
// Might add PROFILE later.
@@ -8683,7 +8683,7 @@ var devToolsConfig$jscomp$inline_1028 = {
throw Error("TestRenderer does not support findFiberByHostInstance()");
},
bundleType: 0,
version: "18.3.0-next-7329ea81c-20230402",
version: "18.3.0-next-b14f8da15-20230403",
rendererPackageName: "react-test-renderer"
};
var internals$jscomp$inline_1220 = {
@@ -8714,7 +8714,7 @@ var internals$jscomp$inline_1220 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-next-7329ea81c-20230402"
reconcilerVersion: "18.3.0-next-b14f8da15-20230403"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1221 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
@@ -9108,7 +9108,7 @@ var devToolsConfig$jscomp$inline_1070 = {
throw Error("TestRenderer does not support findFiberByHostInstance()");
},
bundleType: 0,
version: "18.3.0-next-7329ea81c-20230402",
version: "18.3.0-next-b14f8da15-20230403",
rendererPackageName: "react-test-renderer"
};
var internals$jscomp$inline_1261 = {
@@ -9139,7 +9139,7 @@ var internals$jscomp$inline_1261 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-next-7329ea81c-20230402"
reconcilerVersion: "18.3.0-next-b14f8da15-20230403"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1262 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
@@ -27,7 +27,7 @@ if (
}
"use strict";
var ReactVersion = "18.3.0-next-7329ea81c-20230402";
var ReactVersion = "18.3.0-next-b14f8da15-20230403";
// ATTENTION
// When adding new symbols to this file,
@@ -639,4 +639,4 @@ exports.useSyncExternalStore = function (
);
};
exports.useTransition = useTransition;
exports.version = "18.3.0-next-7329ea81c-20230402";
exports.version = "18.3.0-next-b14f8da15-20230403";
@@ -642,7 +642,7 @@ exports.useSyncExternalStore = function (
);
};
exports.useTransition = useTransition;
exports.version = "18.3.0-next-7329ea81c-20230402";
exports.version = "18.3.0-next-b14f8da15-20230403";
/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
if (
@@ -1 +1 @@
7329ea81c154d40800e30104be40f050e8c2af3e
b14f8da15598cdc2253529a905421ac795d68ab1
@@ -27158,7 +27158,7 @@ function createFiberRoot(
return root;
}
var ReactVersion = "18.3.0-next-7329ea81c-20230402";
var ReactVersion = "18.3.0-next-b14f8da15-20230403";
function createPortal$1(
children,
@@ -9554,7 +9554,7 @@ var roots = new Map(),
devToolsConfig$jscomp$inline_1048 = {
findFiberByHostInstance: getInstanceFromNode,
bundleType: 0,
version: "18.3.0-next-7329ea81c-20230402",
version: "18.3.0-next-b14f8da15-20230403",
rendererPackageName: "react-native-renderer",
rendererConfig: {
getInspectorDataForViewTag: function () {
@@ -9596,7 +9596,7 @@ var internals$jscomp$inline_1293 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-next-7329ea81c-20230402"
reconcilerVersion: "18.3.0-next-b14f8da15-20230403"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1294 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
@@ -10262,7 +10262,7 @@ var roots = new Map(),
devToolsConfig$jscomp$inline_1126 = {
findFiberByHostInstance: getInstanceFromNode,
bundleType: 0,
version: "18.3.0-next-7329ea81c-20230402",
version: "18.3.0-next-b14f8da15-20230403",
rendererPackageName: "react-native-renderer",
rendererConfig: {
getInspectorDataForViewTag: function () {
@@ -10317,7 +10317,7 @@ var roots = new Map(),
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-next-7329ea81c-20230402"
reconcilerVersion: "18.3.0-next-b14f8da15-20230403"
});
exports.createPortal = function (children, containerTag) {
return createPortal$1(
@@ -27698,7 +27698,7 @@ function createFiberRoot(
return root;
}
var ReactVersion = "18.3.0-next-7329ea81c-20230402";
var ReactVersion = "18.3.0-next-b14f8da15-20230403";
function createPortal$1(
children,
@@ -9810,7 +9810,7 @@ var roots = new Map(),
devToolsConfig$jscomp$inline_1107 = {
findFiberByHostInstance: getInstanceFromTag,
bundleType: 0,
version: "18.3.0-next-7329ea81c-20230402",
version: "18.3.0-next-b14f8da15-20230403",
rendererPackageName: "react-native-renderer",
rendererConfig: {
getInspectorDataForViewTag: function () {
@@ -9852,7 +9852,7 @@ var internals$jscomp$inline_1359 = {
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-next-7329ea81c-20230402"
reconcilerVersion: "18.3.0-next-b14f8da15-20230403"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1360 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
@@ -10518,7 +10518,7 @@ var roots = new Map(),
devToolsConfig$jscomp$inline_1185 = {
findFiberByHostInstance: getInstanceFromTag,
bundleType: 0,
version: "18.3.0-next-7329ea81c-20230402",
version: "18.3.0-next-b14f8da15-20230403",
rendererPackageName: "react-native-renderer",
rendererConfig: {
getInspectorDataForViewTag: function () {
@@ -10573,7 +10573,7 @@ var roots = new Map(),
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "18.3.0-next-7329ea81c-20230402"
reconcilerVersion: "18.3.0-next-b14f8da15-20230403"
});
exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = {
computeComponentStackForErrorReporting: function (reactTag) {