Skip to content

Commit

Permalink
Ensure that existing properties are configurable before redefining
Browse files Browse the repository at this point in the history
Summary:
`Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js` attempts to setup global variables typical in most JavaScript environments. It finds the previous property value using `Object.getOwnPropertyDescriptor` and preserves it as `original[PropertyName]` (if it existed), it then redefines the property using `Object.defineProperty`.

Properties may only be redefined if the property descriptor specifies that it is configurable ([MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor)). Attempting to redefine an non-configurable property will result in an error: `TypeError: Cannot redefine property: [PropertyName]`.

Not all properties being setup in `InitializeJavaScriptAppEngine.js` are necessarily configurable in the target environment.
Closes facebook#9244

Differential Revision: D3679683

fbshipit-source-id: cd3398ef2cdf38e58c58862e64b159951c2b22c2
  • Loading branch information
cameronhunter authored and Morgan Pretty committed Aug 24, 2016
1 parent 9eee2e1 commit 816f5ab
Showing 1 changed file with 19 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,16 @@ function defineProperty(object: Object, name: string, newValue: mixed): void {
value: object[name],
});
}
const {enumerable, writable} = descriptor || {};
Object.defineProperty(object, name, {
configurable: true,
enumerable: enumerable !== false,
writable: writable !== false,
value: newValue,
});

const {enumerable, writable, configurable} = descriptor || {};
if (!descriptor || configurable) {
Object.defineProperty(object, name, {
configurable: true,
enumerable: enumerable !== false,
writable: writable !== false,
value: newValue,
});
}
}

function defineLazyProperty<T>(
Expand All @@ -98,11 +101,15 @@ function defineLazyProperty<T>(
const backupName = `original${name[0].toUpperCase()}${name.substr(1)}`;
Object.defineProperty(object, backupName, descriptor);
}
defineLazyObjectProperty(object, name, {
get: getNewValue,
enumerable: descriptor ? descriptor.enumerable !== false : true,
writable: descriptor ? descriptor.writable !== false : true,
});

const {configurable} = descriptor || {};
if (!descriptor || configurable) {
defineLazyObjectProperty(object, name, {
get: getNewValue,
enumerable: descriptor ? descriptor.enumerable !== false : true,
writable: descriptor ? descriptor.writable !== false : true,
});
}
}

function setUpErrorHandler(): void {
Expand Down

0 comments on commit 816f5ab

Please sign in to comment.