Bug 1152550 - Make sure that cross-global Iterator can not be broken. r=Waldo, a=sledru

This commit is contained in:
Tom Schuster
2015-04-19 18:13:59 +02:00
parent 091e9b3783
commit 0088702fbc
2 changed files with 36 additions and 1 deletions

View 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");

View File

@@ -477,6 +477,8 @@ Compare(T* a, T* b, size_t c)
return true; return true;
} }
static bool iterator_next(JSContext* cx, unsigned argc, Value* vp);
static inline PropertyIteratorObject* static inline PropertyIteratorObject*
NewPropertyIteratorObject(JSContext* cx, unsigned flags) NewPropertyIteratorObject(JSContext* cx, unsigned flags)
{ {
@@ -500,13 +502,35 @@ NewPropertyIteratorObject(JSContext* cx, unsigned flags)
GetInitialHeap(GenericObject, clasp), shape, group); GetInitialHeap(GenericObject, clasp), shape, group);
if (!obj) if (!obj)
return nullptr; return nullptr;
PropertyIteratorObject* res = &obj->as<PropertyIteratorObject>(); PropertyIteratorObject* res = &obj->as<PropertyIteratorObject>();
MOZ_ASSERT(res->numFixedSlots() == JSObject::ITER_CLASS_NFIXED_SLOTS); MOZ_ASSERT(res->numFixedSlots() == JSObject::ITER_CLASS_NFIXED_SLOTS);
return res; 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* NativeIterator*