Bug 1085566 - Make the preventExtensions hook return succeeded/failed rather than always indicate failure by reporting an error. r=efaust

--HG--
extra : rebase_source : 3b61c22efe8b5b2b3135b11556b6b329479d3dcd
This commit is contained in:
Jeff Walden 2014-10-19 01:18:43 -07:00
parent 09421bed32
commit 7f782a5fda
34 changed files with 134 additions and 95 deletions

View File

@ -20,12 +20,11 @@ public:
{
}
virtual bool
preventExtensions(JSContext* aCx, JS::Handle<JSObject*> aProxy) const MOZ_OVERRIDE
preventExtensions(JSContext* aCx, JS::Handle<JSObject*> aProxy,
bool *succeeded) const MOZ_OVERRIDE
{
// Throw a TypeError, per WebIDL.
JS_ReportErrorNumber(aCx, js_GetErrorMessage, nullptr,
JSMSG_CANT_CHANGE_EXTENSIBILITY);
return false;
*succeeded = false;
return true;
}
virtual bool
getOwnPropDescriptor(JSContext* aCx, JS::Handle<JSObject*> aProxy,

View File

@ -623,7 +623,8 @@ public:
virtual bool isExtensible(JSContext *cx, JS::Handle<JSObject*> proxy, bool *extensible)
const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx,
JS::Handle<JSObject*> proxy) const MOZ_OVERRIDE;
JS::Handle<JSObject*> proxy,
bool *succeeded) const MOZ_OVERRIDE;
virtual bool has(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::Handle<jsid> id, bool *bp) const MOZ_OVERRIDE;
virtual bool get(JSContext *cx, JS::Handle<JSObject*> proxy,
@ -719,12 +720,12 @@ nsOuterWindowProxy::isExtensible(JSContext *cx, JS::Handle<JSObject*> proxy,
bool
nsOuterWindowProxy::preventExtensions(JSContext *cx,
JS::Handle<JSObject*> proxy) const
JS::Handle<JSObject*> proxy,
bool *succeeded) const
{
// See above.
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr,
JSMSG_CANT_CHANGE_EXTENSIBILITY);
return false;
*succeeded = false;
return true;
}
const char *

View File

@ -149,12 +149,11 @@ DOMProxyHandler::isExtensible(JSContext *cx, JS::Handle<JSObject*> proxy, bool *
}
bool
DOMProxyHandler::preventExtensions(JSContext *cx, JS::Handle<JSObject*> proxy) const
DOMProxyHandler::preventExtensions(JSContext *cx, JS::Handle<JSObject*> proxy,
bool *succeeded) const
{
// Throw a TypeError, per WebIDL.
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr,
JSMSG_CANT_CHANGE_EXTENSIBILITY);
return false;
*succeeded = false;
return true;
}
bool

View File

@ -117,7 +117,8 @@ public:
JS::Handle<jsid> id, bool* bp) const MOZ_OVERRIDE;
bool isExtensible(JSContext *cx, JS::Handle<JSObject*> proxy, bool *extensible)
const MOZ_OVERRIDE;
bool preventExtensions(JSContext *cx, JS::Handle<JSObject*> proxy) const MOZ_OVERRIDE;
bool preventExtensions(JSContext *cx, JS::Handle<JSObject*> proxy,
bool *succeeded) const MOZ_OVERRIDE;
bool has(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
bool* bp) const MOZ_OVERRIDE;
bool set(JSContext *cx, JS::Handle<JSObject*> proxy, JS::Handle<JSObject*> receiver,

View File

@ -35,8 +35,10 @@ class JavaScriptBase : public WrapperOwner, public WrapperAnswer, public Base
/*** IPC handlers ***/
bool RecvPreventExtensions(const uint64_t &objId, ReturnStatus *rs) {
return Answer::RecvPreventExtensions(ObjectId::deserialize(objId), rs);
bool RecvPreventExtensions(const uint64_t &objId, ReturnStatus *rs,
bool *succeeded) {
return Answer::RecvPreventExtensions(ObjectId::deserialize(objId), rs,
succeeded);
}
bool RecvGetPropertyDescriptor(const uint64_t &objId, const JSIDVariant &id,
ReturnStatus *rs,
@ -131,8 +133,9 @@ class JavaScriptBase : public WrapperOwner, public WrapperAnswer, public Base
bool SendDropObject(const ObjectId &objId) {
return Base::SendDropObject(objId.serialize());
}
bool SendPreventExtensions(const ObjectId &objId, ReturnStatus *rs) {
return Base::SendPreventExtensions(objId.serialize(), rs);
bool SendPreventExtensions(const ObjectId &objId, ReturnStatus *rs,
bool *succeeded) {
return Base::SendPreventExtensions(objId.serialize(), rs, succeeded);
}
bool SendGetPropertyDescriptor(const ObjectId &objId, const JSIDVariant &id,
ReturnStatus *rs,

View File

@ -24,7 +24,7 @@ both:
async DropObject(uint64_t objId);
// These roughly map to the ProxyHandler hooks that CPOWs need.
prio(high) sync PreventExtensions(uint64_t objId) returns (ReturnStatus rs);
prio(high) sync PreventExtensions(uint64_t objId) returns (ReturnStatus rs, bool result);
prio(high) sync GetPropertyDescriptor(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, PPropertyDescriptor result);
prio(high) sync GetOwnPropertyDescriptor(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, PPropertyDescriptor result);
prio(high) sync DefineProperty(uint64_t objId, JSIDVariant id, PPropertyDescriptor descriptor) returns (ReturnStatus rs);

View File

@ -58,7 +58,8 @@ WrapperAnswer::ok(ReturnStatus *rs)
}
bool
WrapperAnswer::RecvPreventExtensions(const ObjectId &objId, ReturnStatus *rs)
WrapperAnswer::RecvPreventExtensions(const ObjectId &objId, ReturnStatus *rs,
bool *succeeded)
{
AutoSafeJSContext cx;
JSAutoRequest request(cx);
@ -68,7 +69,7 @@ WrapperAnswer::RecvPreventExtensions(const ObjectId &objId, ReturnStatus *rs)
return fail(cx, rs);
JSAutoCompartment comp(cx, obj);
if (!JS_PreventExtensions(cx, obj))
if (!JS_PreventExtensions(cx, obj, succeeded))
return fail(cx, rs);
LOG("%s.preventExtensions()", ReceiverObj(objId));

View File

@ -18,7 +18,8 @@ class WrapperAnswer : public virtual JavaScriptShared
public:
explicit WrapperAnswer(JSRuntime *rt) : JavaScriptShared(rt) {}
bool RecvPreventExtensions(const ObjectId &objId, ReturnStatus *rs);
bool RecvPreventExtensions(const ObjectId &objId, ReturnStatus *rs,
bool *succeeded);
bool RecvGetPropertyDescriptor(const ObjectId &objId, const JSIDVariant &id,
ReturnStatus *rs,
PPropertyDescriptor *out);

View File

@ -72,7 +72,7 @@ class CPOWProxyHandler : public BaseProxyHandler
virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, HandleObject proxy) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const MOZ_OVERRIDE;
virtual bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver,
HandleId id, MutableHandleValue vp) const MOZ_OVERRIDE;
@ -113,18 +113,18 @@ const CPOWProxyHandler CPOWProxyHandler::singleton;
return owner->call args;
bool
CPOWProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy) const
CPOWProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const
{
FORWARD(preventExtensions, (cx, proxy));
FORWARD(preventExtensions, (cx, proxy, succeeded));
}
bool
WrapperOwner::preventExtensions(JSContext *cx, HandleObject proxy)
WrapperOwner::preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded)
{
ObjectId objId = idOf(proxy);
ReturnStatus status;
if (!SendPreventExtensions(objId, &status))
if (!SendPreventExtensions(objId, &status, succeeded))
return ipcfail(cx);
LOG_STACK();

View File

@ -41,7 +41,7 @@ class WrapperOwner : public virtual JavaScriptShared
bool delete_(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp);
bool enumerate(JSContext *cx, JS::HandleObject proxy, JS::AutoIdVector &props);
bool isExtensible(JSContext *cx, JS::HandleObject proxy, bool *extensible);
bool preventExtensions(JSContext *cx, JS::HandleObject proxy);
bool preventExtensions(JSContext *cx, JS::HandleObject proxy, bool *succeeded);
bool has(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp);
bool get(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver,
JS::HandleId id, JS::MutableHandleValue vp);
@ -106,7 +106,8 @@ class WrapperOwner : public virtual JavaScriptShared
/*** Dummy call handlers ***/
public:
virtual bool SendDropObject(const ObjectId &objId) = 0;
virtual bool SendPreventExtensions(const ObjectId &objId, ReturnStatus *rs) = 0;
virtual bool SendPreventExtensions(const ObjectId &objId, ReturnStatus *rs,
bool *succeeded) = 0;
virtual bool SendGetPropertyDescriptor(const ObjectId &objId, const JSIDVariant &id,
ReturnStatus *rs,
PPropertyDescriptor *out) = 0;

View File

@ -1012,7 +1012,7 @@ obj_isExtensible(JSContext *cx, unsigned argc, Value *vp)
return true;
}
// ES6 draft rev27 (2014/08/24) 19.1.2.15 Object.preventExtensions(O)
// ES6 20141014 draft 19.1.2.15 Object.preventExtensions(O)
static bool
obj_preventExtensions(JSContext *cx, unsigned argc, Value *vp)
{
@ -1023,10 +1023,21 @@ obj_preventExtensions(JSContext *cx, unsigned argc, Value *vp)
if (!args.get(0).isObject())
return true;
// Steps 2-5.
// Steps 2-3.
RootedObject obj(cx, &args.get(0).toObject());
return JSObject::preventExtensions(cx, obj);
bool status;
if (!JSObject::preventExtensions(cx, obj, &status))
return false;
// Step 4.
if (!status) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_CHANGE_EXTENSIBILITY);
return false;
}
// Step 5.
return true;
}
// ES6 draft rev27 (2014/08/24) 19.1.2.5 Object.freeze(O)

View File

@ -6458,9 +6458,9 @@ JS_DecodeInterpretedFunction(JSContext *cx, const void *data, uint32_t length)
}
JS_PUBLIC_API(bool)
JS_PreventExtensions(JSContext *cx, JS::HandleObject obj)
JS_PreventExtensions(JSContext *cx, JS::HandleObject obj, bool *succeeded)
{
return JSObject::preventExtensions(cx, obj);
return JSObject::preventExtensions(cx, obj, succeeded);
}
JS_PUBLIC_API(void)

View File

@ -2795,7 +2795,7 @@ extern JS_PUBLIC_API(bool)
JS_FreezeObject(JSContext *cx, JS::Handle<JSObject*> obj);
extern JS_PUBLIC_API(bool)
JS_PreventExtensions(JSContext *cx, JS::HandleObject obj);
JS_PreventExtensions(JSContext *cx, JS::HandleObject obj, bool *succeeded);
extern JS_PUBLIC_API(JSObject *)
JS_New(JSContext *cx, JS::HandleObject ctor, const JS::HandleValueArray& args);

View File

@ -868,10 +868,17 @@ CreateFunctionPrototype(JSContext *cx, JSProtoKey key)
SingletonObject));
if (!tte)
return nullptr;
bool succeeded;
RootedFunction throwTypeError(cx, NewFunction(cx, tte, ThrowTypeError, 0,
JSFunction::NATIVE_FUN, self, js::NullPtr()));
if (!throwTypeError || !JSObject::preventExtensions(cx, throwTypeError))
if (!throwTypeError || !JSObject::preventExtensions(cx, throwTypeError, &succeeded))
return nullptr;
if (!succeeded) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_CHANGE_EXTENSIBILITY);
return nullptr;
}
self->setThrowTypeError(throwTypeError);
return functionProto;

View File

@ -1229,8 +1229,13 @@ JSObject::sealOrFreeze(JSContext *cx, HandleObject obj, ImmutabilityType it)
assertSameCompartment(cx, obj);
MOZ_ASSERT(it == SEAL || it == FREEZE);
if (!JSObject::preventExtensions(cx, obj))
bool succeeded;
if (!JSObject::preventExtensions(cx, obj, &succeeded))
return false;
if (!succeeded) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_CHANGE_EXTENSIBILITY);
return false;
}
AutoIdVector props(cx);
if (!GetPropertyKeys(cx, obj, JSITER_HIDDEN | JSITER_OWNONLY | JSITER_SYMBOLS, &props))

View File

@ -514,10 +514,11 @@ class JSObject : public js::gc::Cell
return !lastProperty()->hasObjectFlag(js::BaseShape::NOT_EXTENSIBLE);
}
// Attempt to change the [[Extensible]] bit on |obj| to false. Callers
// must ensure that |obj| is currently extensible before calling this!
// Attempt to change the [[Extensible]] bit on |obj| to false. Indicate
// success or failure through the |*succeeded| outparam, or actual error
// through the return value.
static bool
preventExtensions(JSContext *cx, js::HandleObject obj);
preventExtensions(JSContext *cx, js::HandleObject obj, bool *succeeded);
private:
enum ImmutabilityType { SEAL, FREEZE };

View File

@ -257,7 +257,7 @@ class JS_FRIEND_API(BaseProxyHandler)
virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const = 0;
virtual bool enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props) const = 0;
virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const = 0;
virtual bool preventExtensions(JSContext *cx, HandleObject proxy) const = 0;
virtual bool preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const = 0;
/*
* These methods are standard, but the engine does not normally call them.
@ -369,7 +369,7 @@ class JS_PUBLIC_API(DirectProxyHandler) : public BaseProxyHandler
virtual bool enumerate(JSContext *cx, HandleObject proxy,
AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, HandleObject proxy) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const MOZ_OVERRIDE;
virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy,
MutableHandleObject protop) const MOZ_OVERRIDE;
virtual bool setPrototypeOf(JSContext *cx, HandleObject proxy, HandleObject proto,

View File

@ -123,7 +123,7 @@ class JS_FRIEND_API(CrossCompartmentWrapper) : public Wrapper
virtual bool delete_(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool enumerate(JSContext *cx, HandleObject wrapper, AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, HandleObject wrapper, bool *extensible) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, HandleObject wrapper) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, HandleObject wrapper, bool *succeeded) const MOZ_OVERRIDE;
virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy,
MutableHandleObject protop) const MOZ_OVERRIDE;
virtual bool setPrototypeOf(JSContext *cx, HandleObject proxy, HandleObject proto,
@ -185,7 +185,7 @@ class JS_FRIEND_API(SecurityWrapper) : public Base
virtual bool defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, HandleObject wrapper, bool *extensible) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, HandleObject wrapper) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, HandleObject wrapper, bool *succeeded) const MOZ_OVERRIDE;
virtual bool setPrototypeOf(JSContext *cx, HandleObject proxy, HandleObject proto,
bool *bp) const MOZ_OVERRIDE;
virtual bool setImmutablePrototype(JSContext *cx, HandleObject proxy, bool *succeeded) const MOZ_OVERRIDE;

View File

@ -37,11 +37,12 @@ CrossCompartmentWrapper::isExtensible(JSContext *cx, HandleObject wrapper, bool
}
bool
CrossCompartmentWrapper::preventExtensions(JSContext *cx, HandleObject wrapper) const
CrossCompartmentWrapper::preventExtensions(JSContext *cx, HandleObject wrapper,
bool *succeeded) const
{
PIERCE(cx, wrapper,
NOTHING,
Wrapper::preventExtensions(cx, wrapper),
Wrapper::preventExtensions(cx, wrapper, succeeded),
NOTHING);
}

View File

@ -24,7 +24,7 @@ DeadObjectProxy::isExtensible(JSContext *cx, HandleObject proxy, bool *extensibl
}
bool
DeadObjectProxy::preventExtensions(JSContext *cx, HandleObject proxy) const
DeadObjectProxy::preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const
{
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_DEAD_OBJECT);
return false;

View File

@ -28,7 +28,7 @@ class DeadObjectProxy : public BaseProxyHandler
virtual bool delete_(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool enumerate(JSContext *cx, HandleObject wrapper, AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, HandleObject proxy) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const MOZ_OVERRIDE;
virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy,
MutableHandleObject protop) const MOZ_OVERRIDE;
virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) const MOZ_OVERRIDE;

View File

@ -251,10 +251,10 @@ DirectProxyHandler::isExtensible(JSContext *cx, HandleObject proxy, bool *extens
}
bool
DirectProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy) const
DirectProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const
{
RootedObject target(cx, proxy->as<ProxyObject>().target());
return JSObject::preventExtensions(cx, target);
return JSObject::preventExtensions(cx, target, succeeded);
}
bool

View File

@ -387,11 +387,11 @@ Proxy::isExtensible(JSContext *cx, HandleObject proxy, bool *extensible)
}
bool
Proxy::preventExtensions(JSContext *cx, HandleObject proxy)
Proxy::preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded)
{
JS_CHECK_RECURSION(cx, return false);
const BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
return handler->preventExtensions(cx, proxy);
return handler->preventExtensions(cx, proxy, succeeded);
}
bool

View File

@ -36,7 +36,7 @@ class Proxy
static bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp);
static bool enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props);
static bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible);
static bool preventExtensions(JSContext *cx, HandleObject proxy);
static bool preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded);
static bool getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject protop);
static bool setPrototypeOf(JSContext *cx, HandleObject proxy, HandleObject proto, bool *bp);
static bool setImmutablePrototype(JSContext *cx, HandleObject proxy, bool *succeeded);

View File

@ -273,32 +273,31 @@ ArrayToIdVector(JSContext *cx, HandleObject proxy, HandleObject target, HandleVa
return true;
}
// ES6 (22 May, 2014) 9.5.4 Proxy.[[PreventExtensions]]()
// ES6 20141014 9.5.4 Proxy.[[PreventExtensions]]()
bool
ScriptedDirectProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy) const
ScriptedDirectProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy,
bool *succeeded) const
{
// step 1
// Steps 1-3.
RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));
// step 2
if (!handler) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_PROXY_REVOKED);
return false;
}
// step 3
// Step 4.
RootedObject target(cx, proxy->as<ProxyObject>().target());
// step 4-5
// Steps 5-6.
RootedValue trap(cx);
if (!JSObject::getProperty(cx, handler, handler, cx->names().preventExtensions, &trap))
return false;
// step 6
// Step 7.
if (trap.isUndefined())
return DirectProxyHandler::preventExtensions(cx, proxy);
return DirectProxyHandler::preventExtensions(cx, proxy, succeeded);
// step 7, 9
// Steps 8, 10.
Value argv[] = {
ObjectValue(*target)
};
@ -306,10 +305,11 @@ ScriptedDirectProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy)
if (!Invoke(cx, ObjectValue(*handler), trap, ArrayLength(argv), argv, &trapResult))
return false;
// step 8
bool success = ToBoolean(trapResult);
if (success) {
// step 10
// Step 9.
bool booleanTrapResult = ToBoolean(trapResult);
// Step 11.
if (booleanTrapResult) {
bool extensible;
if (!JSObject::isExtensible(cx, target, &extensible))
return false;
@ -317,15 +317,11 @@ ScriptedDirectProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy)
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_REPORT_AS_NON_EXTENSIBLE);
return false;
}
// step 11 "return true"
return true;
}
// step 11 "return false"
// This actually corresponds to 19.1.2.5 step 4. We cannot pass the failure back, so throw here
// directly instead.
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_CHANGE_EXTENSIBILITY);
return false;
// Step 12.
*succeeded = booleanTrapResult;
return true;
}
// ES6 implements both getPrototypeOf and setPrototypeOf traps. We don't have them yet (see bug

View File

@ -28,7 +28,7 @@ class ScriptedDirectProxyHandler : public DirectProxyHandler {
virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, HandleObject proxy) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const MOZ_OVERRIDE;
/* These two are standard internal methods but aren't implemented to spec yet. */
virtual bool getPrototypeOf(JSContext *cx, HandleObject proxy,

View File

@ -140,11 +140,11 @@ ScriptedIndirectProxyHandler::isExtensible(JSContext *cx, HandleObject proxy,
}
bool
ScriptedIndirectProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy) const
ScriptedIndirectProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const
{
// See above.
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_CHANGE_EXTENSIBILITY);
return false;
*succeeded = false;
return true;
}
static bool

View File

@ -29,7 +29,7 @@ class ScriptedIndirectProxyHandler : public BaseProxyHandler
virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, HandleObject proxy) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const MOZ_OVERRIDE;
virtual bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE;
virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
MutableHandleValue vp) const MOZ_OVERRIDE;

View File

@ -24,11 +24,12 @@ SecurityWrapper<Base>::isExtensible(JSContext *cx, HandleObject wrapper, bool *e
template <class Base>
bool
SecurityWrapper<Base>::preventExtensions(JSContext *cx, HandleObject wrapper) const
SecurityWrapper<Base>::preventExtensions(JSContext *cx, HandleObject wrapper,
bool *succeeded) const
{
// See above.
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_UNWRAP_DENIED);
return false;
*succeeded = false;
return true;
}
template <class Base>

View File

@ -5863,7 +5863,14 @@ DebuggerObject_sealHelper(JSContext *cx, unsigned argc, Value *vp, SealHelperOp
ok = JSObject::freeze(cx, obj);
} else {
MOZ_ASSERT(op == PreventExtensions);
ok = JSObject::preventExtensions(cx, obj);
bool succeeded;
ok = JSObject::preventExtensions(cx, obj, &succeeded);
if (!ok)
return false;
if (!succeeded) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_CHANGE_EXTENSIBILITY);
return false;
}
}
if (!ok)
return false;

View File

@ -1513,11 +1513,11 @@ class DebugScopeProxy : public BaseProxyHandler
return true;
}
bool preventExtensions(JSContext *cx, HandleObject proxy) const MOZ_OVERRIDE
bool preventExtensions(JSContext *cx, HandleObject proxy, bool *succeeded) const MOZ_OVERRIDE
{
// See above.
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_CHANGE_EXTENSIBILITY);
return false;
*succeeded = false;
return true;
}
bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,

View File

@ -1345,13 +1345,15 @@ Shape::setObjectMetadata(JSContext *cx, JSObject *metadata, TaggedProto proto, S
}
/* static */ bool
JSObject::preventExtensions(JSContext *cx, HandleObject obj)
JSObject::preventExtensions(JSContext *cx, HandleObject obj, bool *succeeded)
{
if (obj->is<ProxyObject>())
return js::Proxy::preventExtensions(cx, obj);
return js::Proxy::preventExtensions(cx, obj, succeeded);
if (!obj->nonProxyIsExtensible())
if (!obj->nonProxyIsExtensible()) {
*succeeded = true;
return true;
}
/*
* Force lazy properties to be resolved by iterating over the objects' own
@ -1370,6 +1372,7 @@ JSObject::preventExtensions(JSContext *cx, HandleObject obj)
if (obj->isNative() && !NativeObject::sparsifyDenseElements(cx, obj.as<NativeObject>()))
return false;
*succeeded = true;
return obj->setFlag(cx, BaseShape::NOT_EXTENSIBLE, GENERATE_SHAPE);
}

View File

@ -1759,11 +1759,12 @@ XrayWrapper<Base, Traits>::isExtensible(JSContext *cx, JS::Handle<JSObject*> wra
template <typename Base, typename Traits>
bool
XrayWrapper<Base, Traits>::preventExtensions(JSContext *cx, HandleObject wrapper) const
XrayWrapper<Base, Traits>::preventExtensions(JSContext *cx, HandleObject wrapper, bool *succeeded)
const
{
// See above.
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_CHANGE_EXTENSIBILITY);
return false;
*succeeded = false;
return true;
}
template <typename Base, typename Traits>

View File

@ -415,7 +415,7 @@ class XrayWrapper : public Base {
JS::Handle<jsid> id, bool *bp) const MOZ_OVERRIDE;
virtual bool enumerate(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::AutoIdVector &props) const MOZ_OVERRIDE;
virtual bool isExtensible(JSContext *cx, JS::Handle<JSObject*> wrapper, bool *extensible) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, JS::Handle<JSObject*> wrapper) const MOZ_OVERRIDE;
virtual bool preventExtensions(JSContext *cx, JS::Handle<JSObject*> wrapper, bool *succeeded) const MOZ_OVERRIDE;
virtual bool getPrototypeOf(JSContext *cx, JS::HandleObject wrapper,
JS::MutableHandleObject protop) const MOZ_OVERRIDE;
virtual bool setPrototypeOf(JSContext *cx, JS::HandleObject wrapper,