зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1525346. Fix the cross-compartment bug in MaybeCrossOriginObject::enumerate. r=jandem
Differential Revision: https://phabricator.services.mozilla.com/D18714 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
a35b931962
Коммит
c48f274465
|
@ -423,11 +423,37 @@ template <typename Base>
|
|||
JSObject* MaybeCrossOriginObject<Base>::enumerate(
|
||||
JSContext* cx, JS::Handle<JSObject*> proxy) const {
|
||||
// We want to avoid any possible magic here and just do the BaseProxyHandler
|
||||
// thing of using our property keys to enumerate.
|
||||
//
|
||||
// Note that we do not need to enter the Realm of "proxy" here, nor do we want
|
||||
// to: if this is a cross-origin access we want to handle it appropriately.
|
||||
return js::BaseProxyHandler::enumerate(cx, proxy);
|
||||
// thing of using our property keys to enumerate. But we can't actually call
|
||||
// BaseProxyHandler::enumerate, because that does two things: (1) Get the keys
|
||||
// and (2) create the iterator object. We want to do (1) in our current
|
||||
// Realm, because if this is a cross-origin access we want to handle it
|
||||
// appropriately. But the iterator object needs to be created in the Realm of
|
||||
// "proxy", because it might involve changing "proxy"'s shape, and that needs
|
||||
// to happen in at least the same zone as "proxy".
|
||||
JS::AutoIdVector props(cx);
|
||||
if (!GetPropertyKeys(cx, proxy, 0, &props)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Create the iterator object in the Realm of "proxy".
|
||||
JS::Rooted<JSObject*> iterator(cx);
|
||||
{ // Scope for JSAutoRealm
|
||||
JSAutoRealm ar(cx, proxy);
|
||||
for (auto& id : props) {
|
||||
JS_MarkCrossZoneId(cx, id);
|
||||
}
|
||||
iterator = EnumeratedIdVectorToIterator(cx, proxy, props);
|
||||
if (!iterator) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// And now put things back in the Realm we started with.
|
||||
if (!MaybeWrapObject(cx, &iterator)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return iterator;
|
||||
}
|
||||
|
||||
// Force instantiations of the out-of-line template methods we need.
|
||||
|
|
|
@ -2798,6 +2798,12 @@ extern JS_FRIEND_API void LogDtor(void* self, const char* type, uint32_t sz);
|
|||
*/
|
||||
extern JS_FRIEND_API uint64_t GetGCHeapUsageForObjectZone(JSObject* obj);
|
||||
|
||||
/**
|
||||
* Create an iterator for the given list of props and the given object
|
||||
* being iterated.
|
||||
*/
|
||||
extern JS_FRIEND_API JSObject* EnumeratedIdVectorToIterator(
|
||||
JSContext* cx, JS::HandleObject obj, JS::AutoIdVector& props);
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* jsfriendapi_h */
|
||||
|
|
|
@ -798,6 +798,8 @@ static inline PropertyIteratorObject* VectorToKeyIterator(JSContext* cx,
|
|||
HandleObject obj,
|
||||
AutoIdVector& props,
|
||||
uint32_t numGuards) {
|
||||
MOZ_ASSERT(cx->compartment() == obj->compartment(),
|
||||
"We may end up allocating shapes in the wrong zone!");
|
||||
if (obj->isSingleton() && !JSObject::setIteratedSingleton(cx, obj)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -806,8 +808,9 @@ static inline PropertyIteratorObject* VectorToKeyIterator(JSContext* cx,
|
|||
return CreatePropertyIterator(cx, obj, props, numGuards, 0);
|
||||
}
|
||||
|
||||
JSObject* js::EnumeratedIdVectorToIterator(JSContext* cx, HandleObject obj,
|
||||
AutoIdVector& props) {
|
||||
JS_FRIEND_API JSObject* js::EnumeratedIdVectorToIterator(JSContext* cx,
|
||||
HandleObject obj,
|
||||
AutoIdVector& props) {
|
||||
return VectorToKeyIterator(cx, obj, props, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -369,9 +369,6 @@ JSObject* GetIterator(JSContext* cx, HandleObject obj);
|
|||
|
||||
PropertyIteratorObject* LookupInIteratorCache(JSContext* cx, HandleObject obj);
|
||||
|
||||
JSObject* EnumeratedIdVectorToIterator(JSContext* cx, HandleObject obj,
|
||||
AutoIdVector& props);
|
||||
|
||||
JSObject* NewEmptyPropertyIterator(JSContext* cx);
|
||||
|
||||
JSObject* ValueToIterator(JSContext* cx, HandleValue vp);
|
||||
|
|
Загрузка…
Ссылка в новой задаче