зеркало из https://github.com/mozilla/gecko-dev.git
Bug 909602 - Don't blow away most/all elements above the purported "length" of a non-Array object passed to Array.prototype.pop. r=bhackett
This commit is contained in:
Родитель
7431244179
Коммит
659091681b
|
@ -1994,10 +1994,14 @@ js::array_pop(JSContext *cx, unsigned argc, Value *vp)
|
|||
return false;
|
||||
}
|
||||
|
||||
// Keep dense initialized length optimal, if possible. Note that this just
|
||||
// reflects the possible deletion above: in particular, it's okay to do
|
||||
// this even if the length is non-writable and SetLengthProperty throws.
|
||||
if (obj->isNative() && obj->getDenseInitializedLength() > index)
|
||||
// If this was an array, then there are no elements above the one we just
|
||||
// deleted (if we deleted an element). Thus we can shrink the dense
|
||||
// initialized length accordingly. (This is fine even if the array length
|
||||
// is non-writable: length-changing occurs after element-deletion effects.)
|
||||
// Don't do anything if this isn't an array, as any deletion above has no
|
||||
// effect on any elements after the "last" one indicated by the "length"
|
||||
// property.
|
||||
if (obj->is<ArrayObject>() && obj->getDenseInitializedLength() > index)
|
||||
obj->setDenseInitializedLength(index);
|
||||
|
||||
/* Steps 4a, 5d. */
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 909602;
|
||||
var summary =
|
||||
"Array.prototype.pop shouldn't touch elements greater than length on " +
|
||||
"non-arrays";
|
||||
|
||||
print(BUGNUMBER + ": " + summary);
|
||||
|
||||
/**************
|
||||
* BEGIN TEST *
|
||||
**************/
|
||||
|
||||
function doTest(obj, index)
|
||||
{
|
||||
// print("testing " + JSON.stringify(obj) + " with index " + index);
|
||||
assertEq(Array.prototype.pop.call(obj), undefined);
|
||||
assertEq(index in obj, true);
|
||||
assertEq(obj[index], 42);
|
||||
}
|
||||
|
||||
// not-super-much-later element
|
||||
|
||||
// non-zero length
|
||||
function testPop1()
|
||||
{
|
||||
var obj = { length: 2, 3: 42 };
|
||||
doTest(obj, 3);
|
||||
}
|
||||
for (var i = 0; i < 50; i++)
|
||||
testPop1();
|
||||
|
||||
// zero length
|
||||
function testPop2()
|
||||
{
|
||||
var obj = { length: 0, 3: 42 };
|
||||
doTest(obj, 3);
|
||||
}
|
||||
for (var i = 0; i < 50; i++)
|
||||
testPop2();
|
||||
|
||||
// much-later (but dense) element
|
||||
|
||||
// non-zero length
|
||||
function testPop3()
|
||||
{
|
||||
var obj = { length: 2, 55: 42 };
|
||||
doTest(obj, 55);
|
||||
}
|
||||
for (var i = 0; i < 50; i++)
|
||||
testPop3();
|
||||
|
||||
// zero length
|
||||
function testPop4()
|
||||
{
|
||||
var obj = { length: 0, 55: 42 };
|
||||
doTest(obj, 55);
|
||||
}
|
||||
for (var i = 0; i < 50; i++)
|
||||
testPop4();
|
||||
|
||||
// much much much later (sparse) element
|
||||
|
||||
// non-zero length
|
||||
function testPop5()
|
||||
{
|
||||
var obj = { length: 2, 65530: 42 };
|
||||
doTest(obj, 65530);
|
||||
}
|
||||
for (var i = 0; i < 50; i++)
|
||||
testPop5();
|
||||
|
||||
// zero length
|
||||
function testPop6()
|
||||
{
|
||||
var obj = { length: 0, 65530: 42 };
|
||||
doTest(obj, 65530);
|
||||
}
|
||||
for (var i = 0; i < 50; i++)
|
||||
testPop6();
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
||||
|
||||
print("Tests complete");
|
Загрузка…
Ссылка в новой задаче