diff --git a/packages/react-client/src/ReactFlightClient.js b/packages/react-client/src/ReactFlightClient.js index 14936d48e2b..b23b172b02c 100644 --- a/packages/react-client/src/ReactFlightClient.js +++ b/packages/react-client/src/ReactFlightClient.js @@ -98,6 +98,8 @@ import {getOwnerStackByComponentInfoInDev} from 'shared/ReactComponentInfoStack' import hasOwnProperty from 'shared/hasOwnProperty'; +import getPrototypeOf from 'shared/getPrototypeOf'; + import {injectInternals} from './ReactFlightClientDevToolsHook'; import {OMITTED_PROP_ERROR} from 'shared/ReactFlightPropertyAccess'; @@ -157,6 +159,9 @@ const HALTED = 'halted'; // DEV-only. Means it never resolves even if connection const __PROTO__ = '__proto__'; +const ObjectPrototype = Object.prototype; +const ArrayPrototype = Array.prototype; + type PendingChunk = { status: 'pending', value: null | Array mixed)>, @@ -2170,7 +2175,18 @@ function getOutlinedModel( } } } - value = value[path[i]]; + const name = path[i]; + if ( + typeof value === 'object' && + value !== null && + (getPrototypeOf(value) === ObjectPrototype || + getPrototypeOf(value) === ArrayPrototype) && + hasOwnProperty.call(value, name) + ) { + value = value[name]; + } else { + throw new Error('Invalid reference.'); + } } while ( @@ -5382,14 +5398,16 @@ function reviveModel( } // Plain object for (const k in value) { - if (k === __PROTO__) { - delete (value as any)[k]; - } else { - const walked = reviveModel(response, (value as any)[k], value, k); - if (walked !== undefined) { - (value as any)[k] = walked; - } else { + if (hasOwnProperty.call(value, k)) { + if (k === __PROTO__) { delete (value as any)[k]; + } else { + const walked = reviveModel(response, (value as any)[k], value, k); + if (walked !== undefined) { + (value as any)[k] = walked; + } else { + delete (value as any)[k]; + } } } }