Skip to content
This repository was archived by the owner on Feb 26, 2024. It is now read-only.

Commit 597c634

Browse files
marclavalmhevery
authored andcommitted
fix(browser): make Object.defineProperty patch safer (#392)
Fixes #391
1 parent 571a4c7 commit 597c634

File tree

3 files changed

+32
-2
lines changed

3 files changed

+32
-2
lines changed

Diff for: lib/browser/define-property.ts

+23-2
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ export function propertyPatch() {
1414
if (isUnconfigurable(obj, prop)) {
1515
throw new TypeError('Cannot assign to read only property \'' + prop + '\' of ' + obj);
1616
}
17+
const originalConfigurableFlag = desc.configurable;
1718
if (prop !== 'prototype') {
1819
desc = rewriteDescriptor(obj, prop, desc);
1920
}
20-
return _defineProperty(obj, prop, desc);
21+
return _tryDefineProperty(obj, prop, desc, originalConfigurableFlag);
2122
};
2223

2324
Object.defineProperties = function (obj, props) {
@@ -46,8 +47,9 @@ export function propertyPatch() {
4647
};
4748

4849
export function _redefineProperty(obj, prop, desc) {
50+
const originalConfigurableFlag = desc.configurable;
4951
desc = rewriteDescriptor(obj, prop, desc);
50-
return _defineProperty(obj, prop, desc);
52+
return _tryDefineProperty(obj, prop, desc, originalConfigurableFlag);
5153
};
5254

5355
function isUnconfigurable (obj, prop) {
@@ -65,4 +67,23 @@ function rewriteDescriptor (obj, prop, desc) {
6567
return desc;
6668
}
6769

70+
function _tryDefineProperty (obj, prop, desc, originalConfigurableFlag) {
71+
try {
72+
return _defineProperty(obj, prop, desc);
73+
}
74+
catch(e) {
75+
if (desc.configurable) {
76+
// In case of errors, when the configurable flag was likely set by rewriteDescriptor(), let's retry with the original flag value
77+
if (typeof originalConfigurableFlag == 'undefined') {
78+
delete desc.configurable;
79+
} else {
80+
desc.configurable = originalConfigurableFlag;
81+
}
82+
return _defineProperty(obj, prop, desc);
83+
} else {
84+
throw e;
85+
}
86+
}
87+
}
88+
6889

Diff for: test/browser/define-property.spec.ts

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
describe('defineProperty', function () {
2+
3+
it('should not throw when defining length on an array', function () {
4+
var someArray = [];
5+
expect(() => Object.defineProperty(someArray, 'length', {value: 2, writable: false})).not.toThrow();
6+
});
7+
8+
});

Diff for: test/browser_entry_point.ts

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import './test-env-setup';
1313
// List all tests here:
1414
import './common_tests';
1515
import './browser/browser.spec';
16+
import './browser/define-property.spec';
1617
import './browser/element.spec';
1718
import './browser/FileReader.spec';
1819
import './browser/HTMLImports.spec';

0 commit comments

Comments
 (0)