зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1120503
- Fix seal/freeze for typed arrays. r=Waldo
This commit is contained in:
Родитель
4d3611e544
Коммит
b2df85cfa3
|
@ -1098,7 +1098,7 @@ js::SetIntegrityLevel(JSContext *cx, HandleObject obj, IntegrityLevel level)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* ES6 rev 29 (6 Dec 2014) 7.3.14. */
|
||||
// ES6 draft rev33 (12 Feb 2015) 7.3.15
|
||||
bool
|
||||
js::TestIntegrityLevel(JSContext *cx, HandleObject obj, IntegrityLevel level, bool *result)
|
||||
{
|
||||
|
@ -1111,38 +1111,26 @@ js::TestIntegrityLevel(JSContext *cx, HandleObject obj, IntegrityLevel level, bo
|
|||
return true;
|
||||
}
|
||||
|
||||
if (IsAnyTypedArray(obj)) {
|
||||
if (level == IntegrityLevel::Sealed) {
|
||||
// Typed arrays are considered sealed (bug 1120503).
|
||||
*result = true;
|
||||
} else {
|
||||
// Typed arrays cannot be frozen, but an empty typed array is
|
||||
// considered frozen (bug 1120503).
|
||||
*result = (AnyTypedArrayLength(obj) == 0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Steps 7-8.
|
||||
AutoIdVector props(cx);
|
||||
if (!GetPropertyKeys(cx, obj, JSITER_HIDDEN | JSITER_OWNONLY | JSITER_SYMBOLS, &props))
|
||||
return false;
|
||||
|
||||
// Step 11.
|
||||
// Step 9.
|
||||
RootedId id(cx);
|
||||
Rooted<PropertyDescriptor> desc(cx);
|
||||
for (size_t i = 0, len = props.length(); i < len; i++) {
|
||||
id = props[i];
|
||||
|
||||
// Steps 11.a-b.
|
||||
// Steps 9.a-b.
|
||||
if (!GetOwnPropertyDescriptor(cx, obj, id, &desc))
|
||||
return false;
|
||||
|
||||
// Step 11.c.
|
||||
// Step 9.c.
|
||||
if (!desc.object())
|
||||
continue;
|
||||
|
||||
// Steps 11.c.i-ii.
|
||||
// Steps 9.c.i-ii.
|
||||
if (!desc.isPermanent() ||
|
||||
(level == IntegrityLevel::Frozen && desc.isDataDescriptor() && desc.isWritable()))
|
||||
{
|
||||
|
@ -1151,7 +1139,7 @@ js::TestIntegrityLevel(JSContext *cx, HandleObject obj, IntegrityLevel level, bo
|
|||
}
|
||||
}
|
||||
|
||||
// Step 12.
|
||||
// Step 10.
|
||||
*result = true;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
"use strict";
|
||||
|
||||
// Seal
|
||||
assertEq(Object.isSealed(new Int32Array(2)), false);
|
||||
assertEq(Object.isSealed(new Int32Array(0)), false);
|
||||
|
||||
var array = new Int32Array(0);
|
||||
Object.preventExtensions(array);
|
||||
assertEq(Object.isSealed(array), true);
|
||||
|
||||
array = new Int32Array(1);
|
||||
array.b = "test";
|
||||
Object.preventExtensions(array);
|
||||
assertEq(Object.isSealed(array), false);
|
||||
Object.defineProperty(array, "b", {configurable: false});
|
||||
assertEq(Object.isSealed(array), true);
|
||||
|
||||
array = new Int32Array(2);
|
||||
array.b = "test";
|
||||
Object.seal(array);
|
||||
assertEq(Object.isSealed(array), true);
|
||||
assertThrowsInstanceOf(() => array.c = 15, TypeError);
|
||||
|
||||
// Freeze
|
||||
assertEq(Object.isFrozen(new Int32Array(2)), false);
|
||||
assertEq(Object.isFrozen(new Int32Array(0)), false);
|
||||
|
||||
// Empty non-extensible typed-array is trvially frozen
|
||||
var array = new Int32Array(0);
|
||||
Object.preventExtensions(array);
|
||||
assertEq(Object.isFrozen(array), true);
|
||||
|
||||
array = new Int32Array(0);
|
||||
array.b = "test";
|
||||
assertEq(Object.isFrozen(array), false);
|
||||
Object.preventExtensions(array);
|
||||
assertEq(Object.isFrozen(array), false);
|
||||
Object.defineProperty(array, "b", {configurable: false, writable: false});
|
||||
assertEq(Object.isFrozen(array), true);
|
||||
|
||||
// Non-empty typed arrays can never be frozen, because the elements stay writable
|
||||
array = new Int32Array(1);
|
||||
assertThrowsInstanceOf(() => Object.freeze(array), TypeError);
|
||||
assertEq(Object.isExtensible(array), false);
|
||||
assertEq(Object.isFrozen(array), false);
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
Загрузка…
Ссылка в новой задаче