Bug 924059. Give ArrayIterator and its prototype different JSClasses so we can't confuse them for each other. r=waldo

This commit is contained in:
Boris Zbarsky 2014-12-13 22:05:46 -05:00
parent a3cef658dd
commit a522e1acdf
5 changed files with 25 additions and 4 deletions

View File

@ -651,7 +651,7 @@ function ArrayIteratorIdentity() {
}
function ArrayIteratorNext() {
// FIXME: ArrayIterator prototype should not pass this test. Bug 924059.
// FIXME: Cross-compartment wrapper ArrayIterator objects should pass this test. Bug 1111170.
if (!IsObject(this) || !IsArrayIterator(this))
ThrowError(JSMSG_INCOMPATIBLE_METHOD, "ArrayIterator", "next", ToString(this));

View File

@ -207,7 +207,7 @@ function StringIteratorIdentity() {
}
function StringIteratorNext() {
// FIXME: Cross-compartment wrapper StringIterator objects should pass this test. Bug 924059.
// FIXME: Cross-compartment wrapper StringIterator objects should pass this test. Bug 1111170.
if (!IsObject(this) || !IsStringIterator(this))
ThrowError(JSMSG_INCOMPATIBLE_METHOD, "StringIterator", "next", ToString(this));

View File

@ -926,6 +926,11 @@ const Class PropertyIteratorObject::class_ = {
trace
};
static const Class ArrayIteratorPrototypeClass = {
"Array Iterator",
JSCLASS_IMPLEMENTS_BARRIERS
};
enum {
ArrayIteratorSlotIteratedObject,
ArrayIteratorSlotNextIndex,
@ -1335,7 +1340,7 @@ GlobalObject::initIteratorClasses(JSContext *cx, Handle<GlobalObject *> global)
RootedObject proto(cx);
if (global->getSlot(ARRAY_ITERATOR_PROTO).isUndefined()) {
const Class *cls = &ArrayIteratorObject::class_;
const Class *cls = &ArrayIteratorPrototypeClass;
proto = global->createBlankPrototypeInheriting(cx, cls, *iteratorProto);
if (!proto || !DefinePropertiesAndFunctions(cx, proto, nullptr, array_iterator_methods))
return false;

View File

@ -0,0 +1,16 @@
// Test that we can't confuse %ArrayIteratorPrototype% for an
// ArrayIterator object.
function TestArrayIteratorPrototypeConfusion() {
var iter = [][Symbol.iterator]();
try {
iter.next.call(Object.getPrototypeOf(iter))
throw new Error("Call did not throw");
} catch (e) {
assertEq(e instanceof TypeError, true);
assertEq(e.message, "ArrayIterator next called on incompatible [object Array Iterator]");
}
}
TestArrayIteratorPrototypeConfusion();
if (typeof reportCompare === "function")
reportCompare(true, true);

View File

@ -640,7 +640,7 @@ intrinsic_NewArrayIterator(JSContext *cx, unsigned argc, Value *vp)
if (!proto)
return false;
JSObject *obj = NewObjectWithGivenProto(cx, proto->getClass(), proto, cx->global());
JSObject *obj = NewObjectWithGivenProto(cx, &ArrayIteratorObject::class_, proto, cx->global());
if (!obj)
return false;