Skip to content

Commit

Permalink
Avoid freezing child properties of unfreezable objects.
Browse files Browse the repository at this point in the history
  • Loading branch information
benjamn committed Sep 20, 2021
1 parent 87f604e commit ecfee99
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 4 deletions.
12 changes: 12 additions & 0 deletions src/utilities/common/__tests__/maybeDeepFeeze.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,16 @@ describe('maybeDeepFreeze', () => {
expect(Object.isFrozen(result)).toBe(true);
expect(Object.isFrozen(result.oyez)).toBe(false);
});

it('should not freeze child properties of unfreezable objects', () => {
const result = maybeDeepFreeze({
buffer: Object.assign(Buffer.from("oyez"), {
doNotFreeze: { please: "thanks" },
}),
});
expect(Object.isFrozen(result)).toBe(true);
expect(Object.isFrozen(result.buffer)).toBe(false);
expect(Object.isFrozen(result.buffer.doNotFreeze)).toBe(false);
expect(result.buffer.doNotFreeze).toEqual({ please: "thanks" });
});
});
7 changes: 3 additions & 4 deletions src/utilities/common/maybeDeepFreeze.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import { isNonNullObject } from './objects';
function deepFreeze(value: any) {
const workSet = new Set([value]);
workSet.forEach(obj => {
if (isNonNullObject(obj)) {
shallowFreeze(obj);
if (isNonNullObject(obj) && shallowFreeze(obj) === obj) {
Object.getOwnPropertyNames(obj).forEach(name => {
if (isNonNullObject(obj[name])) workSet.add(obj[name]);
});
Expand All @@ -14,15 +13,15 @@ function deepFreeze(value: any) {
return value;
}

function shallowFreeze<T extends object>(obj: T): T {
function shallowFreeze<T extends object>(obj: T): T | null {
if (__DEV__ && !Object.isFrozen(obj)) {
try {
Object.freeze(obj);
} catch (e) {
// Some types like Uint8Array and Node.js's Buffer cannot be frozen, but
// they all throw a TypeError when you try, so we re-throw any exceptions
// that are not TypeErrors, since that would be unexpected.
if (e instanceof TypeError) return obj;
if (e instanceof TypeError) return null;
throw e;
}
}
Expand Down

0 comments on commit ecfee99

Please sign in to comment.