Bug 713944 - Assert that a data descriptor referenced in the property cache was writable only if the property cache entry was a hit. If it wasn't, the descriptor might have been made writable in the interim -- and if the cache entry was for finding the property along the prototype chain, the shape key used for the entry lookup would be invariant across the data descriptor's mutation. This also fixes bug 643847. r=jorendorff

This commit is contained in:
Jeff Walden 2011-12-29 05:44:10 -06:00
Родитель b3b6939d31
Коммит 7624bdbe59
3 изменённых файлов: 50 добавлений и 3 удалений

Просмотреть файл

@ -3161,11 +3161,13 @@ BEGIN_CASE(JSOP_SETMETHOD)
* on a prototype property that has a setter.
*/
const Shape *shape = entry->prop;
if (entry->isOwnPropertyHit() ||
((obj2 = obj->getProto()) && obj2->lastProperty() == entry->pshape))
{
JS_ASSERT_IF(shape->isDataDescriptor(), shape->writable());
JS_ASSERT_IF(shape->hasSlot(), entry->isOwnPropertyHit());
if (entry->isOwnPropertyHit() ||
((obj2 = obj->getProto()) && obj2->lastProperty() == entry->pshape)) {
#ifdef DEBUG
if (entry->isOwnPropertyHit()) {
JS_ASSERT(obj->nativeContains(cx, *shape));

Просмотреть файл

@ -38,6 +38,7 @@ skip-if(!xulRuntime.shell) script 15.2.3.6-dictionary-redefinition-8-of-8.js # u
script 15.2.3.6-define-over-method.js
script mutation-prevention-methods.js
script object-toString-01.js
script proto-property-change-writability-set.js
script vacuous-accessor-unqualified-name.js
script add-property-non-extensible.js
skip-if(!xulRuntime.shell) script freeze-global-eval-const.js # uses evalcx

Просмотреть файл

@ -0,0 +1,44 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
* Contributors:
* Gary Kwong
* Jeff Walden
* Jason Orendorff
*/
var accDesc = { set: function() {} };
var dataDesc = { value: 3 };
function f()
{
constructor = {};
}
function g()
{
constructor = {};
}
Object.defineProperty(Object.prototype, "constructor", accDesc);
f();
Object.defineProperty(Object.prototype, "constructor", dataDesc);
assertEq(constructor, 3);
f();
assertEq(constructor, 3);
g();
assertEq(constructor, 3);
var a = { p1: 1, p2: 2 };
var b = Object.create(a);
Object.defineProperty(a, "p1", {set: function () {}});
for (var i = 0; i < 2; i++)
{
b.p1 = {};
Object.defineProperty(a, "p1", {value: 3});
}
assertEq(b.p1, 3);
assertEq(a.p1, 3);
reportCompare(true, true);