diff --git a/packages/react-native/src/private/webapis/structuredClone/__tests__/structuredClone-itest.js b/packages/react-native/src/private/webapis/structuredClone/__tests__/structuredClone-itest.js index 402e055048da..fc36c60a1b8c 100644 --- a/packages/react-native/src/private/webapis/structuredClone/__tests__/structuredClone-itest.js +++ b/packages/react-native/src/private/webapis/structuredClone/__tests__/structuredClone-itest.js @@ -92,6 +92,17 @@ describe('structuredClone', () => { expectDataCloneError(() => structuredClone(Promise.resolve(4))); }); + it('does not coerce non-serializable values', () => { + const values: Array<$FlowFixMe> = [() => {}, new WeakMap()]; + for (const value of values) { + value[Symbol.toPrimitive] = () => { + throw new Error('Unexpected coercion'); + }; + + expectDataCloneError(() => structuredClone(value)); + } + }); + it('clones simple objects', () => { const value = {foo: 'bar'}; const clone = structuredClone(value); diff --git a/packages/react-native/src/private/webapis/structuredClone/structuredClone.js b/packages/react-native/src/private/webapis/structuredClone/structuredClone.js index 89a7f90725be..fef5febe827b 100644 --- a/packages/react-native/src/private/webapis/structuredClone/structuredClone.js +++ b/packages/react-native/src/private/webapis/structuredClone/structuredClone.js @@ -35,6 +35,13 @@ const ObjectPrototype = Object.prototype; // any given point we only have one memory object alive anyway. const memory: Map = new Map(); +function createDataCloneError(): DOMException { + return new DOMException( + "Failed to execute 'structuredClone' on 'Window': value could not be cloned.", + 'DataCloneError', + ); +} + function structuredCloneInternal(value: T): T { // Handles `null` and `undefined`. if (value == null) { @@ -52,11 +59,7 @@ function structuredCloneInternal(value: T): T { // Handles unsupported types (symbols and functions). if (typeof value !== 'object') { - // value is symbol or function - throw new DOMException( - `Failed to execute 'structuredClone' on 'Window': ${String(value)} could not be cloned.`, - 'DataCloneError', - ); + throw createDataCloneError(); } // Handles circular references. @@ -168,10 +171,7 @@ function structuredCloneInternal(value: T): T { // Known non-serializable objects. if (isNonSerializableObject(value) || isPlatformObject(value)) { - throw new DOMException( - `Failed to execute 'structuredClone' on 'Window': ${String(value)} could not be cloned.`, - 'DataCloneError', - ); + throw createDataCloneError(); } // Arbitrary object slow path