From b49c0de7f82fe5e843da6906f1a6aa4bf7d79986 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20=C5=BBelawski?=
<40713406+tjzel@users.noreply.github.com>
Date: Mon, 10 Jun 2024 14:26:31 +0200
Subject: [PATCH] Fix configuring unconfigurable properties (#6098)
## Summary
Fixes #6066. When implementing more meaningful way of shareable freezing
I overlooked the case when some properties would be unconfigurable. This
PR fixes this.
## Test plan
New button in `ShareableFreezing` example checks that it doesn't throw
anymore.
---
.../src/examples/ShareableFreezingExample.tsx | 27 ++++++++++++++++---
.../react-native-reanimated/src/shareables.ts | 4 +++
2 files changed, 27 insertions(+), 4 deletions(-)
diff --git a/apps/common-app/src/examples/ShareableFreezingExample.tsx b/apps/common-app/src/examples/ShareableFreezingExample.tsx
index f4fa2e3ab7d..6bd98298c9a 100644
--- a/apps/common-app/src/examples/ShareableFreezingExample.tsx
+++ b/apps/common-app/src/examples/ShareableFreezingExample.tsx
@@ -68,6 +68,13 @@ export default function FreezingShareables() {
onPress={tryModifyConvertedInt32Array}
/>
+
+ 🤫
+
+
);
}
@@ -92,7 +99,7 @@ function tryModifyConvertedHostObject() {
return;
}
makeShareableCloneRecursive(obj);
- // @ts-expect-error
+ // @ts-expect-error It's ok
obj.prop = 2; // shouldn't warn because it's not frozen
}
@@ -107,21 +114,22 @@ function tryModifyConvertedPlainObject() {
function tryModifyConvertedRegExpLiteral() {
const obj = /a/;
makeShareableCloneRecursive(obj);
- // @ts-expect-error
+ // @ts-expect-error It's ok
obj.prop = 2; // shouldn't warn because it's not frozen
}
function tryModifyConvertedRegExpInstance() {
+ // eslint-disable-next-line prefer-regex-literals
const obj = new RegExp('a');
makeShareableCloneRecursive(obj);
- // @ts-expect-error
+ // @ts-expect-error It's ok
obj.prop = 2; // shouldn't warn because it's not frozen
}
function tryModifyConvertedArrayBuffer() {
const obj = new ArrayBuffer(8);
makeShareableCloneRecursive(obj);
- // @ts-expect-error
+ // @ts-expect-error It's ok
obj.prop = 2; // shouldn't warn because it's not frozen
}
@@ -131,6 +139,17 @@ function tryModifyConvertedInt32Array() {
obj[1] = 2; // shouldn't warn because it's not frozen
}
+function tryModifyUnconfigurableObject() {
+ const obj = {};
+ Object.defineProperty(obj, 'prop', {
+ value: 1,
+ writable: false,
+ enumerable: true,
+ configurable: false,
+ });
+ makeShareableCloneRecursive(obj);
+}
+
const styles = StyleSheet.create({
container: {
flex: 1,
diff --git a/packages/react-native-reanimated/src/shareables.ts b/packages/react-native-reanimated/src/shareables.ts
index d665b0cc4ef..87b812e047d 100644
--- a/packages/react-native-reanimated/src/shareables.ts
+++ b/packages/react-native-reanimated/src/shareables.ts
@@ -318,6 +318,10 @@ function freezeObjectIfDev(value: T) {
return;
}
Object.entries(value).forEach(([key, element]) => {
+ const descriptor = Object.getOwnPropertyDescriptor(value, key)!;
+ if (!descriptor.configurable) {
+ return;
+ }
Object.defineProperty(value, key, {
get() {
return element;