Bug 1152550 - Make sure that cross-global Iterator can not be broken. r=Waldo, a=sledru
This commit is contained in:
11
js/src/jit-test/tests/basic/cross-global-for-in.js
Normal file
11
js/src/jit-test/tests/basic/cross-global-for-in.js
Normal file
@@ -0,0 +1,11 @@
|
||||
var global = newGlobal();
|
||||
|
||||
var arrayIter = (new global.Array())[global.Symbol.iterator]();
|
||||
var ArrayIteratorPrototype = Object.getPrototypeOf(arrayIter);
|
||||
var arrayIterProtoBase = Object.getPrototypeOf(ArrayIteratorPrototype);
|
||||
var IteratorPrototype = arrayIterProtoBase;
|
||||
delete IteratorPrototype.next;
|
||||
|
||||
var obj = global.eval('({a: 1})')
|
||||
for (var x in obj) {}
|
||||
assertEq(x, "a");
|
||||
@@ -477,6 +477,8 @@ Compare(T* a, T* b, size_t c)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool iterator_next(JSContext* cx, unsigned argc, Value* vp);
|
||||
|
||||
static inline PropertyIteratorObject*
|
||||
NewPropertyIteratorObject(JSContext* cx, unsigned flags)
|
||||
{
|
||||
@@ -500,13 +502,35 @@ NewPropertyIteratorObject(JSContext* cx, unsigned flags)
|
||||
GetInitialHeap(GenericObject, clasp), shape, group);
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
PropertyIteratorObject* res = &obj->as<PropertyIteratorObject>();
|
||||
|
||||
MOZ_ASSERT(res->numFixedSlots() == JSObject::ITER_CLASS_NFIXED_SLOTS);
|
||||
return res;
|
||||
}
|
||||
|
||||
return NewBuiltinClassInstance<PropertyIteratorObject>(cx);
|
||||
Rooted<PropertyIteratorObject*> res(cx, NewBuiltinClassInstance<PropertyIteratorObject>(cx));
|
||||
if (!res)
|
||||
return nullptr;
|
||||
|
||||
if (flags == 0) {
|
||||
// Redefine next as an own property. This ensure that deleting the
|
||||
// next method on the prototype doesn't break cross-global for .. in.
|
||||
// We don't have to do this for JSITER_ENUMERATE because that object always
|
||||
// takes an optimized path.
|
||||
RootedFunction next(cx, NewFunctionWithProto(cx, NullPtr(), iterator_next, 0,
|
||||
JSFunction::NATIVE_FUN, NullPtr(),
|
||||
HandlePropertyName(cx->names().next),
|
||||
NullPtr()));
|
||||
if (!next)
|
||||
return nullptr;
|
||||
|
||||
RootedValue value(cx, ObjectValue(*next));
|
||||
if (!DefineProperty(cx, res, cx->names().next, value))
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
NativeIterator*
|
||||
|
||||
Reference in New Issue
Block a user