зеркало из https://github.com/mozilla/gecko-dev.git
Bug 911864 - Expose an API to copy a single property across compartments. r=jorendorff
This commit is contained in:
Родитель
4828e1811f
Коммит
28781ba0db
|
@ -173,9 +173,23 @@ extern JS_FRIEND_API(void)
|
||||||
js_DumpChars(const jschar *s, size_t n);
|
js_DumpChars(const jschar *s, size_t n);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copies all own properties from |obj| to |target|. |obj| must be a "native"
|
||||||
|
* object (that is to say, normal-ish - not an Array or a Proxy).
|
||||||
|
*
|
||||||
|
* On entry, |cx| must be in the compartment of |target|.
|
||||||
|
*/
|
||||||
extern JS_FRIEND_API(bool)
|
extern JS_FRIEND_API(bool)
|
||||||
JS_CopyPropertiesFrom(JSContext *cx, JSObject *target, JSObject *obj);
|
JS_CopyPropertiesFrom(JSContext *cx, JSObject *target, JSObject *obj);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Single-property version of the above. This function asserts that an |own|
|
||||||
|
* property of the given name exists on |obj|.
|
||||||
|
*/
|
||||||
|
extern JS_FRIEND_API(bool)
|
||||||
|
JS_CopyPropertyFrom(JSContext *cx, JS::HandleId id, JS::HandleObject target,
|
||||||
|
JS::HandleObject obj);
|
||||||
|
|
||||||
extern JS_FRIEND_API(bool)
|
extern JS_FRIEND_API(bool)
|
||||||
JS_WrapPropertyDescriptor(JSContext *cx, JS::MutableHandle<JSPropertyDescriptor> desc);
|
JS_WrapPropertyDescriptor(JSContext *cx, JS::MutableHandle<JSPropertyDescriptor> desc);
|
||||||
|
|
||||||
|
|
|
@ -1756,11 +1756,54 @@ JSObject::deleteByValue(JSContext *cx, HandleObject obj, const Value &property,
|
||||||
return deleteProperty(cx, obj, propname, succeeded);
|
return deleteProperty(cx, obj, propname, succeeded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
CopyProperty(JSContext *cx, HandleObject target, HandleObject obj,
|
||||||
|
HandleShape shape)
|
||||||
|
{
|
||||||
|
// |shape| and |obj| are generally not same-compartment with |target| and
|
||||||
|
// |cx| here.
|
||||||
|
assertSameCompartment(cx, target);
|
||||||
|
|
||||||
|
unsigned attrs = shape->attributes();
|
||||||
|
PropertyOp getter = shape->getter();
|
||||||
|
StrictPropertyOp setter = shape->setter();
|
||||||
|
AutoRooterGetterSetter gsRoot(cx, attrs, &getter, &setter);
|
||||||
|
if ((attrs & JSPROP_GETTER) && !cx->compartment()->wrap(cx, &getter))
|
||||||
|
return false;
|
||||||
|
if ((attrs & JSPROP_SETTER) && !cx->compartment()->wrap(cx, &setter))
|
||||||
|
return false;
|
||||||
|
RootedValue v(cx, shape->hasSlot() ? obj->getSlot(shape->slot())
|
||||||
|
: UndefinedValue());
|
||||||
|
if (!cx->compartment()->wrap(cx, &v))
|
||||||
|
return false;
|
||||||
|
RootedId id(cx, shape->propid());
|
||||||
|
return JSObject::defineGeneric(cx, target, id, v, getter,
|
||||||
|
setter, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
JS_FRIEND_API(bool)
|
||||||
|
JS_CopyPropertyFrom(JSContext *cx, HandleId id, HandleObject target,
|
||||||
|
HandleObject obj)
|
||||||
|
{
|
||||||
|
assertSameCompartment(cx, target);
|
||||||
|
MOZ_ASSERT(obj->isNative());
|
||||||
|
RootedObject obj2(cx);
|
||||||
|
RootedShape shape(cx);
|
||||||
|
{
|
||||||
|
AutoCompartment ac(cx, obj);
|
||||||
|
if (!JSObject::lookupGeneric(cx, obj, id, &obj2, &shape))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
MOZ_ASSERT(shape && obj == obj2);
|
||||||
|
return CopyProperty(cx, target, obj, shape);
|
||||||
|
}
|
||||||
|
|
||||||
JS_FRIEND_API(bool)
|
JS_FRIEND_API(bool)
|
||||||
JS_CopyPropertiesFrom(JSContext *cx, JSObject *targetArg, JSObject *objArg)
|
JS_CopyPropertiesFrom(JSContext *cx, JSObject *targetArg, JSObject *objArg)
|
||||||
{
|
{
|
||||||
RootedObject target(cx, targetArg);
|
RootedObject target(cx, targetArg);
|
||||||
RootedObject obj(cx, objArg);
|
RootedObject obj(cx, objArg);
|
||||||
|
assertSameCompartment(cx, target);
|
||||||
|
|
||||||
// If we're not native, then we cannot copy properties.
|
// If we're not native, then we cannot copy properties.
|
||||||
JS_ASSERT(target->isNative() == obj->isNative());
|
JS_ASSERT(target->isNative() == obj->isNative());
|
||||||
|
@ -1773,25 +1816,11 @@ JS_CopyPropertiesFrom(JSContext *cx, JSObject *targetArg, JSObject *objArg)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
RootedShape shape(cx);
|
|
||||||
RootedValue v(cx);
|
|
||||||
RootedId id(cx);
|
|
||||||
size_t n = shapes.length();
|
size_t n = shapes.length();
|
||||||
|
RootedShape shape(cx);
|
||||||
while (n > 0) {
|
while (n > 0) {
|
||||||
shape = shapes[--n];
|
shape = shapes[--n];
|
||||||
unsigned attrs = shape->attributes();
|
if (!CopyProperty(cx, target, obj, shape))
|
||||||
PropertyOp getter = shape->getter();
|
|
||||||
StrictPropertyOp setter = shape->setter();
|
|
||||||
AutoRooterGetterSetter gsRoot(cx, attrs, &getter, &setter);
|
|
||||||
if ((attrs & JSPROP_GETTER) && !cx->compartment()->wrap(cx, &getter))
|
|
||||||
return false;
|
|
||||||
if ((attrs & JSPROP_SETTER) && !cx->compartment()->wrap(cx, &setter))
|
|
||||||
return false;
|
|
||||||
v = shape->hasSlot() ? obj->getSlot(shape->slot()) : UndefinedValue();
|
|
||||||
if (!cx->compartment()->wrap(cx, &v))
|
|
||||||
return false;
|
|
||||||
id = shape->propid();
|
|
||||||
if (!JSObject::defineGeneric(cx, target, id, v, getter, setter, attrs))
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче