зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
083ba18ef1
Коммит
1d2a7aa6cd
|
@ -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,
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче