Bug 1002737 - Find a new home for PropDesc::unwrapDebuggerObjectsInto. (r=jorendorff)

This commit is contained in:
Eric Faust 2014-06-03 12:37:43 -07:00
Родитель 328066636f
Коммит 8f1835b4f0
4 изменённых файлов: 90 добавлений и 64 удалений

Просмотреть файл

@ -809,6 +809,63 @@ Debugger::unwrapDebuggeeValue(JSContext *cx, MutableHandleValue vp)
return true;
}
/*
* Convert Debugger.Objects in desc to debuggee values.
* Reject non-callable getters and setters.
*/
static bool
CheckArgCompartment(JSContext *cx, JSObject *obj, HandleValue v,
const char *methodname, const char *propname)
{
if (v.isObject() && v.toObject().compartment() != obj->compartment()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_DEBUG_COMPARTMENT_MISMATCH,
methodname, propname);
return false;
}
return true;
}
bool
Debugger::unwrapPropDescInto(JSContext *cx, HandleObject obj, Handle<PropDesc> wrapped,
MutableHandle<PropDesc> unwrapped)
{
MOZ_ASSERT(!wrapped.isUndefined());
unwrapped.set(wrapped);
if (unwrapped.hasValue()) {
RootedValue value(cx, unwrapped.value());
if (!unwrapDebuggeeValue(cx, &value) ||
!CheckArgCompartment(cx, obj, value, "defineProperty", "value"))
{
return false;
}
unwrapped.setValue(value);
}
if (unwrapped.hasGet()) {
RootedValue get(cx, unwrapped.getterValue());
if (!unwrapDebuggeeValue(cx, &get) ||
!CheckArgCompartment(cx, obj, get, "defineProperty", "get"))
{
return false;
}
unwrapped.setGetter(get);
}
if (unwrapped.hasSet()) {
RootedValue set(cx, unwrapped.setterValue());
if (!unwrapDebuggeeValue(cx, &set) ||
!CheckArgCompartment(cx, obj, set, "defineProperty", "set"))
{
return false;
}
unwrapped.setSetter(set);
}
return true;
}
JSTrapStatus
Debugger::handleUncaughtExceptionHelper(Maybe<AutoCompartment> &ac,
MutableHandleValue *vp, bool callHook)
@ -5262,7 +5319,7 @@ DebuggerObject_defineProperty(JSContext *cx, unsigned argc, Value *vp)
return false;
desc.clearPd();
if (!desc.get().unwrapDebuggerObjectsInto(cx, dbg, obj, desc.address()))
if (!dbg->unwrapPropDescInto(cx, obj, desc, &desc))
return false;
if (!desc.checkGetter(cx) || !desc.checkSetter(cx))
return false;
@ -5306,7 +5363,10 @@ DebuggerObject_defineProperties(JSContext *cx, unsigned argc, Value *vp)
for (size_t i = 0; i < n; i++) {
if (!unwrappedDescs.append())
return false;
if (!descs[i].unwrapDebuggerObjectsInto(cx, dbg, obj, &unwrappedDescs[i]))
Handle<PropDesc> wrapped = Handle<PropDesc>::fromMarkedLocation(&descs[i]);
MutableHandle<PropDesc> unwrapped =
MutableHandle<PropDesc>::fromMarkedLocation(&unwrappedDescs[i]);
if (!dbg->unwrapPropDescInto(cx, obj, wrapped, unwrapped))
return false;
if (!unwrappedDescs[i].checkGetter(cx) || !unwrappedDescs[i].checkSetter(cx))
return false;

Просмотреть файл

@ -506,6 +506,8 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
* happens in the target compartment--rotational symmetry.)
*/
bool unwrapDebuggeeValue(JSContext *cx, MutableHandleValue vp);
bool unwrapPropDescInto(JSContext *cx, HandleObject obj, Handle<PropDesc> wrapped,
MutableHandle<PropDesc> unwrapped);
/*
* Store the Debugger.Frame object for frame in *vp.

Просмотреть файл

@ -59,63 +59,6 @@ PropDesc::checkSetter(JSContext *cx)
return true;
}
static bool
CheckArgCompartment(JSContext *cx, JSObject *obj, HandleValue v,
const char *methodname, const char *propname)
{
if (v.isObject() && v.toObject().compartment() != obj->compartment()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_DEBUG_COMPARTMENT_MISMATCH,
methodname, propname);
return false;
}
return true;
}
/*
* Convert Debugger.Objects in desc to debuggee values.
* Reject non-callable getters and setters.
*/
bool
PropDesc::unwrapDebuggerObjectsInto(JSContext *cx, Debugger *dbg, HandleObject obj,
PropDesc *unwrapped) const
{
MOZ_ASSERT(!isUndefined());
*unwrapped = *this;
if (unwrapped->hasValue()) {
RootedValue value(cx, unwrapped->value_);
if (!dbg->unwrapDebuggeeValue(cx, &value) ||
!CheckArgCompartment(cx, obj, value, "defineProperty", "value"))
{
return false;
}
unwrapped->value_ = value;
}
if (unwrapped->hasGet()) {
RootedValue get(cx, unwrapped->get_);
if (!dbg->unwrapDebuggeeValue(cx, &get) ||
!CheckArgCompartment(cx, obj, get, "defineProperty", "get"))
{
return false;
}
unwrapped->get_ = get;
}
if (unwrapped->hasSet()) {
RootedValue set(cx, unwrapped->set_);
if (!dbg->unwrapDebuggeeValue(cx, &set) ||
!CheckArgCompartment(cx, obj, set, "defineProperty", "set"))
{
return false;
}
unwrapped->set_ = set;
}
return true;
}
/*
* Rewrap *idp and the fields of *desc for the current compartment. Also:
* defining a property on a proxy requires pd_ to contain a descriptor object,

Просмотреть файл

@ -12,8 +12,6 @@
namespace js {
class Debugger;
static inline JSPropertyOp
CastAsPropertyOp(JSObject *object)
{
@ -182,6 +180,11 @@ struct PropDesc {
MOZ_ASSERT(hasValue());
return HandleValue::fromMarkedLocation(&value_);
}
void setValue(const Value &value) {
MOZ_ASSERT(!isUndefined());
value_ = value;
hasValue_ = true;
}
JSObject * getterObject() const {
MOZ_ASSERT(!isUndefined());
@ -205,6 +208,17 @@ struct PropDesc {
return HandleValue::fromMarkedLocation(&set_);
}
void setGetter(const Value &getter) {
MOZ_ASSERT(!isUndefined());
get_ = getter;
hasGet_ = true;
}
void setSetter(const Value &setter) {
MOZ_ASSERT(!isUndefined());
set_ = setter;
hasSet_ = true;
}
/*
* Unfortunately the values produced by these methods are used such that
* we can't assert anything here. :-(
@ -224,9 +238,6 @@ struct PropDesc {
bool checkGetter(JSContext *cx);
bool checkSetter(JSContext *cx);
bool unwrapDebuggerObjectsInto(JSContext *cx, Debugger *dbg, HandleObject obj,
PropDesc *unwrapped) const;
bool wrapInto(JSContext *cx, HandleObject obj, const jsid &id, jsid *wrappedId,
PropDesc *wrappedDesc) const;
};
@ -299,6 +310,16 @@ class MutablePropDescOperations : public PropDescOperations<Outer>
return desc()->makeObject(cx);
}
void setValue(const Value &value) {
desc()->setValue(value);
}
void setGetter(const Value &getter) {
desc()->setGetter(getter);
}
void setSetter(const Value &setter) {
desc()->setSetter(setter);
}
void setUndefined() { desc()->setUndefined(); }
void clearPd() { desc()->clearPd(); }
};