author | Eddy Bruel <ejpbruel@mozilla.com> |
Fri, 22 Mar 2013 19:43:12 -0700 | |
changeset 126571 | 804c5ca59d99e89c7ee1e1d223a6ceafd34e0b65 |
parent 126570 | a4e200fe684d5717113a5374ffe5ec3ace820118 |
child 126572 | 2e564ec4c11d2cbc37a43e1247c4c72078ebcb24 |
push id | 24488 |
push user | ryanvm@gmail.com |
push date | Fri, 29 Mar 2013 00:54:52 +0000 |
treeherder | mozilla-central@8aeabe064932 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jwalden, ejpbruel, bholley, two-turtle-doves-and-a-partridge-in-a-pear-tree |
bugs | 789897 |
milestone | 22.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/jsproxy.cpp +++ b/js/src/jsproxy.cpp @@ -311,16 +311,24 @@ BaseProxyHandler::isExtensible(JSObject { // Unaltered proxies always claim to be extensible. (Whether defining a // property will actually *work* is an entirely different question.) As a // necessary consequence, they can't be made non-extensible. return true; } bool +BaseProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy) +{ + // See above. + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_CHANGE_EXTENSIBILITY); + return false; +} + +bool BaseProxyHandler::call(JSContext *cx, HandleObject proxy, unsigned argc, Value *vp) { assertEnteredPolicy(cx, proxy, JSID_VOID); AutoValueRooter rval(cx); RootedValue call(cx, GetCall(proxy)); JSBool ok = Invoke(cx, vp[1], call, argc, JS_ARGV(cx, vp), rval.addr()); if (ok) @@ -646,16 +654,23 @@ DirectProxyHandler::iterate(JSContext *c } bool DirectProxyHandler::isExtensible(JSObject *proxy) { return GetProxyTargetObject(proxy)->isExtensible(); } +bool +DirectProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy) +{ + RootedObject target(cx, GetProxyTargetObject(proxy)); + return JSObject::preventExtensions(cx, target); +} + static bool GetFundamentalTrap(JSContext *cx, HandleObject handler, HandlePropertyName name, MutableHandleValue fvalp) { JS_CHECK_RECURSION(cx, return false); return JSObject::getProperty(cx, handler, handler, name, fvalp); } @@ -2485,16 +2500,24 @@ Proxy::iterate(JSContext *cx, HandleObje ? !Proxy::keys(cx, proxy, props) : !Proxy::enumerate(cx, proxy, props)) { return false; } return EnumeratedIdVectorToIterator(cx, proxy, flags, props, vp); } bool +Proxy::preventExtensions(JSContext *cx, HandleObject proxy) +{ + JS_CHECK_RECURSION(cx, return false); + BaseProxyHandler *handler = GetProxyHandler(proxy); + return handler->preventExtensions(cx, proxy); +} + +bool Proxy::isExtensible(JSObject *proxy) { return GetProxyHandler(proxy)->isExtensible(proxy); } bool Proxy::call(JSContext *cx, HandleObject proxy, unsigned argc, Value *vp) {
--- a/js/src/jsproxy.h +++ b/js/src/jsproxy.h @@ -99,16 +99,17 @@ class JS_FRIEND_API(BaseProxyHandler) { GET, SET, CALL }; virtual bool enter(JSContext *cx, HandleObject wrapper, HandleId id, Action act, bool *bp); /* ES5 Harmony fundamental proxy traps. */ + virtual bool preventExtensions(JSContext *cx, HandleObject proxy); virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, PropertyDescriptor *desc, unsigned flags) = 0; virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, PropertyDescriptor *desc, unsigned flags) = 0; virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id, PropertyDescriptor *desc) = 0; virtual bool getOwnPropertyNames(JSContext *cx, HandleObject proxy, @@ -154,16 +155,17 @@ class JS_FRIEND_API(BaseProxyHandler) { * allows consumers of this class to forward to another object as transparently * and efficiently as possible. */ class JS_PUBLIC_API(DirectProxyHandler) : public BaseProxyHandler { public: explicit DirectProxyHandler(void *family); /* ES5 Harmony fundamental proxy traps. */ + virtual bool preventExtensions(JSContext *cx, HandleObject proxy) MOZ_OVERRIDE; virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE; virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE; virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id, PropertyDescriptor *desc) MOZ_OVERRIDE; virtual bool getOwnPropertyNames(JSContext *cx, HandleObject proxy, @@ -204,16 +206,17 @@ public: MutableHandleValue vp) MOZ_OVERRIDE; virtual JSObject *weakmapKeyDelegate(JSObject *proxy); }; /* Dispatch point for handlers that executes the appropriate C++ or scripted traps. */ class Proxy { public: /* ES5 Harmony fundamental proxy traps. */ + static bool preventExtensions(JSContext *cx, HandleObject proxy); static bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, PropertyDescriptor *desc, unsigned flags); static bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, unsigned flags, HandleId id, MutableHandleValue vp); static bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, PropertyDescriptor *desc, unsigned flags); static bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, unsigned flags, HandleId id, MutableHandleValue vp);
--- a/js/src/jswrapper.cpp +++ b/js/src/jswrapper.cpp @@ -633,26 +633,35 @@ SecurityWrapper<Base>::isExtensible(JSOb // Just like BaseProxyHandler, SecurityWrappers claim by default to always // be extensible, so as not to leak information about the state of the // underlying wrapped thing. return true; } template <class Base> bool +SecurityWrapper<Base>::preventExtensions(JSContext *cx, HandleObject wrapper) +{ + // See above. + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_UNWRAP_DENIED); + return false; +} + +template <class Base> +bool SecurityWrapper<Base>::enter(JSContext *cx, HandleObject wrapper, HandleId id, Wrapper::Action act, bool *bp) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_UNWRAP_DENIED); *bp = false; return false; } - template <class Base> - bool +template <class Base> +bool SecurityWrapper<Base>::nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_UNWRAP_DENIED); return false; } template <class Base>
--- a/js/src/jswrapper.h +++ b/js/src/jswrapper.h @@ -139,16 +139,17 @@ class JS_FRIEND_API(CrossCompartmentWrap */ template <class Base> class JS_FRIEND_API(SecurityWrapper) : public Base { public: SecurityWrapper(unsigned flags); virtual bool isExtensible(JSObject *wrapper) MOZ_OVERRIDE; + virtual bool preventExtensions(JSContext *cx, HandleObject wrapper) MOZ_OVERRIDE; virtual bool enter(JSContext *cx, HandleObject wrapper, HandleId id, Wrapper::Action act, bool *bp) MOZ_OVERRIDE; virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args) MOZ_OVERRIDE; virtual bool objectClassIs(HandleObject obj, ESClassValue classValue, JSContext *cx) MOZ_OVERRIDE; virtual bool regexp_toShared(JSContext *cx, HandleObject proxy, RegExpGuard *g) MOZ_OVERRIDE;
--- a/js/src/vm/ObjectImpl-inl.h +++ b/js/src/vm/ObjectImpl-inl.h @@ -88,17 +88,16 @@ js::ObjectImpl::isExtensible() const { if (this->isProxy()) return Proxy::isExtensible(const_cast<JSObject*>(this->asObjectPtr())); // [[Extensible]] for ordinary non-proxy objects is an object flag. return !lastProperty()->hasObjectFlag(BaseShape::NOT_EXTENSIBLE); } - inline uint32_t js::ObjectImpl::getDenseInitializedLength() { MOZ_ASSERT(isNative()); return getElementsHeader()->initializedLength; } inline js::HeapSlotArray
--- a/js/src/vm/ObjectImpl.h +++ b/js/src/vm/ObjectImpl.h @@ -1107,16 +1107,18 @@ class ObjectImpl : public gc::Cell } Class *getClass() const { return type_->clasp; } inline bool isExtensible() const; + // Attempt to change the [[Extensible]] bit on |obj| to false. Callers + // must ensure that |obj| is currently extensible before calling this! static bool preventExtensions(JSContext *cx, Handle<ObjectImpl*> obj); inline HeapSlotArray getDenseElements(); inline const Value & getDenseElement(uint32_t idx); inline bool containsDenseElement(uint32_t idx); inline uint32_t getDenseInitializedLength();
--- a/js/src/vm/Shape.cpp +++ b/js/src/vm/Shape.cpp @@ -1026,17 +1026,24 @@ Shape::setObjectParent(JSContext *cx, JS RootedShape lastRoot(cx, last); return replaceLastProperty(cx, base, proto, lastRoot); } /* static */ bool js::ObjectImpl::preventExtensions(JSContext *cx, Handle<ObjectImpl*> obj) { - JS_ASSERT(obj->isExtensible()); + MOZ_ASSERT(obj->isExtensible(), + "Callers must ensure |obj| is extensible before calling " + "preventExtensions"); + + if (obj->isProxy()) { + RootedObject object(cx, obj->asObjectPtr()); + return js::Proxy::preventExtensions(cx, object); + } RootedObject self(cx, obj->asObjectPtr()); /* * Force lazy properties to be resolved by iterating over the objects' own * properties. */ AutoIdVector props(cx);
--- a/js/xpconnect/wrappers/XrayWrapper.cpp +++ b/js/xpconnect/wrappers/XrayWrapper.cpp @@ -1425,16 +1425,25 @@ XrayWrapper<Base, Traits>::isExtensible( // even if that script freezes the reflector, we don't want to make that // visible to the caller. DOM reflectors are always extensible by default, // so we can just return true here. return true; } template <typename Base, typename Traits> bool +XrayWrapper<Base, Traits>::preventExtensions(JSContext *cx, JS::Handle<JSObject*> wrapper) +{ + // See above. + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_CHANGE_EXTENSIBILITY); + return false; +} + +template <typename Base, typename Traits> +bool XrayWrapper<Base, Traits>::getPropertyDescriptor(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id, js::PropertyDescriptor *desc, unsigned flags) { assertEnteredPolicy(cx, wrapper, id); JSObject *holder = Traits::singleton.ensureHolder(cx, wrapper); if (Traits::isResolving(cx, holder, id)) { desc->obj = NULL;
--- a/js/xpconnect/wrappers/XrayWrapper.h +++ b/js/xpconnect/wrappers/XrayWrapper.h @@ -62,16 +62,17 @@ XrayTraits* GetXrayTraits(JSObject *obj) template <typename Base, typename Traits = XPCWrappedNativeXrayTraits > class XrayWrapper : public Base { public: XrayWrapper(unsigned flags); virtual ~XrayWrapper(); /* Fundamental proxy traps. */ virtual bool isExtensible(JSObject *wrapper) MOZ_OVERRIDE; + virtual bool preventExtensions(JSContext *cx, JS::Handle<JSObject*> wrapper) MOZ_OVERRIDE; virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id, js::PropertyDescriptor *desc, unsigned flags); virtual bool getOwnPropertyDescriptor(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id, js::PropertyDescriptor *desc, unsigned flags); virtual bool defineProperty(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id, js::PropertyDescriptor *desc); virtual bool getOwnPropertyNames(JSContext *cx, JS::Handle<JSObject*> wrapper,