Skip to content

Commit

Permalink
[Fix] Object.defineProperty: Chrome <= 36 has a broken dP when sett…
Browse files Browse the repository at this point in the history
…ing "prototype" while changing writability

See babel/babel#14056 (comment)
  • Loading branch information
ljharb committed Dec 21, 2021
1 parent be1ce31 commit 780abba
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 0 deletions.
21 changes: 21 additions & 0 deletions es5-shim.js
Expand Up @@ -126,6 +126,27 @@
};
}(ObjectPrototype.hasOwnProperty));

// this is needed in Chrome 15 (probably earlier) - 36
// https://bugs.chromium.org/p/v8/issues/detail?id=3334
if ($Object.defineProperty) {
var F = function () {};
var toStringSentinel = {};
var sentinel = { toString: toStringSentinel };
$Object.defineProperty(F, 'prototype', { value: sentinel, writable: false });
if ((new F()).toString !== toStringSentinel) {
var $dP = $Object.defineProperty;
defineProperties($Object, {
defineProperty: function defineProperty(o, k, d) {
var key = $String(k);
if (key === 'prototype' && 'writable' in d && 'value' in d) {
o[key] = d.value; // eslint-disable-line no-param-reassign
}
return $dP(o, key, d);
}
}, true);
}
}

//
// Util
// ======
Expand Down
14 changes: 14 additions & 0 deletions tests/spec/s-object.js
Expand Up @@ -247,6 +247,20 @@ describe('Object', function () {
Object.defineProperty({}, 'name', {});
}).not.toThrow();
});

(supportsDescriptors ? it : xit)('allows setting a nonwritable prototype', function () {
var F = function () {};
expect((new F()).toString).toEqual(Object.prototype.toString);

F.prototype = Number.prototype;
expect((new F()).toString).toEqual(Number.prototype.toString);

var toStringSentinel = {};
var sentinel = { toString: toStringSentinel };
Object.defineProperty(F, 'prototype', { value: sentinel, writable: false });

expect((new F()).toString).toEqual(toStringSentinel);
});
});

describe('.getOwnPropertyDescriptor()', function () {
Expand Down

0 comments on commit 780abba

Please sign in to comment.