Bug 1077587 - Handle non-existent properties in CPOW descriptor code (r=mrbkap)
authorBill McCloskey <wmccloskey@mozilla.com>
Mon, 20 Oct 2014 09:47:27 -0700
changeset 211341 8f34e100ffeae9f08d07a5e293533822c0656d52
parent 211340 5cb1c03335d069aa34bfb6c93e91a1a429cd2fc9
child 211342 30f4aa3c67903205f4a39d018d399b95f0ed7d56
push id27673
push userkwierso@gmail.com
push dateTue, 21 Oct 2014 01:57:45 +0000
treeherdermozilla-central@29fbfc1b31aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap
bugs1077587
milestone36.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
Bug 1077587 - Handle non-existent properties in CPOW descriptor code (r=mrbkap)
js/ipc/JavaScriptShared.cpp
js/ipc/JavaScriptShared.h
js/ipc/JavaScriptTypes.ipdlh
js/ipc/WrapperAnswer.cpp
--- a/js/ipc/JavaScriptShared.cpp
+++ b/js/ipc/JavaScriptShared.cpp
@@ -532,18 +532,17 @@ static const uint64_t UnknownPropertyOp 
 bool
 JavaScriptShared::fromDescriptor(JSContext *cx, Handle<JSPropertyDescriptor> desc,
                                  PPropertyDescriptor *out)
 {
     out->attrs() = desc.attributes();
     if (!toVariant(cx, desc.value(), &out->value()))
         return false;
 
-    MOZ_ASSERT(desc.object());
-    if (!toObjectVariant(cx, desc.object(), &out->obj()))
+    if (!toObjectOrNullVariant(cx, desc.object(), &out->obj()))
         return false;
 
     if (!desc.getter()) {
         out->getter() = 0;
     } else if (desc.hasGetterObject()) {
         JSObject *getter = desc.getterObject();
         ObjectVariant objVar;
         if (!toObjectVariant(cx, getter, &objVar))
@@ -590,21 +589,17 @@ UnknownStrictPropertyStub(JSContext *cx,
 
 bool
 JavaScriptShared::toDescriptor(JSContext *cx, const PPropertyDescriptor &in,
                                MutableHandle<JSPropertyDescriptor> out)
 {
     out.setAttributes(in.attrs());
     if (!fromVariant(cx, in.value(), out.value()))
         return false;
-    Rooted<JSObject*> obj(cx);
-    obj = fromObjectVariant(cx, in.obj());
-    if (!obj)
-        return false;
-    out.object().set(obj);
+    out.object().set(fromObjectOrNullVariant(cx, in.obj()));
 
     if (in.getter().type() == GetterSetter::Tuint64_t && !in.getter().get_uint64_t()) {
         out.setGetter(nullptr);
     } else if (in.attrs() & JSPROP_GETTER) {
         Rooted<JSObject*> getter(cx);
         getter = fromObjectVariant(cx, in.getter().get_ObjectVariant());
         if (!getter)
             return false;
@@ -629,16 +624,41 @@ JavaScriptShared::toDescriptor(JSContext
             out.setSetter(JS_StrictPropertyStub);
         else
             out.setSetter(UnknownStrictPropertyStub);
     }
 
     return true;
 }
 
+bool
+JavaScriptShared::toObjectOrNullVariant(JSContext *cx, JSObject *obj, ObjectOrNullVariant *objVarp)
+{
+    if (!obj) {
+        *objVarp = NullVariant();
+        return true;
+    }
+
+    ObjectVariant objVar;
+    if (!toObjectVariant(cx, obj, &objVar))
+        return false;
+
+    *objVarp = objVar;
+    return true;
+}
+
+JSObject *
+JavaScriptShared::fromObjectOrNullVariant(JSContext *cx, ObjectOrNullVariant objVar)
+{
+    if (objVar.type() == ObjectOrNullVariant::TNullVariant)
+        return nullptr;
+
+    return fromObjectVariant(cx, objVar.get_ObjectVariant());
+}
+
 CpowIdHolder::CpowIdHolder(dom::CPOWManagerGetter *managerGetter, const InfallibleTArray<CpowEntry> &cpows)
   : js_(nullptr),
     cpows_(cpows)
 {
     // Only instantiate the CPOW manager if we might need it later.
     if (cpows.Length())
         js_ = managerGetter->GetCPOWManager();
 }
--- a/js/ipc/JavaScriptShared.h
+++ b/js/ipc/JavaScriptShared.h
@@ -164,16 +164,19 @@ class JavaScriptShared
     bool toSymbolVariant(JSContext *cx, JS::Symbol *sym, SymbolVariant *symVarp);
     JS::Symbol *fromSymbolVariant(JSContext *cx, SymbolVariant symVar);
 
     bool fromDescriptor(JSContext *cx, JS::Handle<JSPropertyDescriptor> desc,
                         PPropertyDescriptor *out);
     bool toDescriptor(JSContext *cx, const PPropertyDescriptor &in,
                       JS::MutableHandle<JSPropertyDescriptor> out);
 
+    bool toObjectOrNullVariant(JSContext *cx, JSObject *obj, ObjectOrNullVariant *objVarp);
+    JSObject *fromObjectOrNullVariant(JSContext *cx, ObjectOrNullVariant objVar);
+
     bool convertIdToGeckoString(JSContext *cx, JS::HandleId id, nsString *to);
     bool convertGeckoStringToId(JSContext *cx, const nsString &from, JS::MutableHandleId id);
 
     virtual bool toObjectVariant(JSContext *cx, JSObject *obj, ObjectVariant *objVarp) = 0;
     virtual JSObject *fromObjectVariant(JSContext *cx, ObjectVariant objVar) = 0;
 
     static void ConvertID(const nsID &from, JSIID *to);
     static void ConvertID(const JSIID &from, nsID *to);
--- a/js/ipc/JavaScriptTypes.ipdlh
+++ b/js/ipc/JavaScriptTypes.ipdlh
@@ -57,16 +57,22 @@ union SymbolVariant
 {
     WellKnownSymbol;
     RegisteredSymbol;
 };
 
 struct UndefinedVariant {};
 struct NullVariant {};
 
+union ObjectOrNullVariant
+{
+    ObjectVariant;
+    NullVariant;
+};
+
 union JSVariant
 {
     UndefinedVariant;
     NullVariant;
     ObjectVariant;
     SymbolVariant;
     nsString;   /* StringValue(x) */
     double;     /* NumberValue(x) */
@@ -110,17 +116,17 @@ union JSParam
 union GetterSetter
 {
     uint64_t;
     ObjectVariant;
 };
 
 struct PPropertyDescriptor
 {
-    ObjectVariant obj;
+    ObjectOrNullVariant obj;
     uint32_t attrs;
     JSVariant value;
 
     // How to interpret these values depends on whether JSPROP_GETTER/SETTER
     // are set. If set, the corresponding value is a CPOW or 0 for NULL.
     // Otherwise, the following table is used:
     //
     //  0 - NULL
--- a/js/ipc/WrapperAnswer.cpp
+++ b/js/ipc/WrapperAnswer.cpp
@@ -106,19 +106,16 @@ WrapperAnswer::RecvGetPropertyDescriptor
     RootedId id(cx);
     if (!fromJSIDVariant(cx, idVar, &id))
         return fail(cx, rs);
 
     Rooted<JSPropertyDescriptor> desc(cx);
     if (!JS_GetPropertyDescriptorById(cx, obj, id, &desc))
         return fail(cx, rs);
 
-    if (!desc.object())
-        return ok(rs);
-
     if (!fromDescriptor(cx, desc, out))
         return fail(cx, rs);
 
     return ok(rs);
 }
 
 bool
 WrapperAnswer::RecvGetOwnPropertyDescriptor(const ObjectId &objId, const JSIDVariant &idVar,
@@ -137,22 +134,19 @@ WrapperAnswer::RecvGetOwnPropertyDescrip
 
     LOG("%s.getOwnPropertyDescriptor(%s)", ReceiverObj(objId), Identifier(idVar));
 
     RootedId id(cx);
     if (!fromJSIDVariant(cx, idVar, &id))
         return fail(cx, rs);
 
     Rooted<JSPropertyDescriptor> desc(cx);
-    if (!JS_GetPropertyDescriptorById(cx, obj, id, &desc))
+    if (!JS_GetOwnPropertyDescriptorById(cx, obj, id, &desc))
         return fail(cx, rs);
 
-    if (desc.object() != obj)
-        return ok(rs);
-
     if (!fromDescriptor(cx, desc, out))
         return fail(cx, rs);
 
     return ok(rs);
 }
 
 bool
 WrapperAnswer::RecvDefineProperty(const ObjectId &objId, const JSIDVariant &idVar,