Bug 975277 - Move the wrappedJSObject getter out of getPropertyDescriptor. r=gabor
authorBobby Holley <bobbyholley@gmail.com>
Fri, 21 Feb 2014 16:03:08 -0800
changeset 170338 02dffb9d2748f78b2e171a94834f130d36879852
parent 170337 fd04a8b8ccc489af9a2a9ad10f639f35dd0857ba
child 170339 84904662e2d567085b5c63f57aa2db45580940db
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersgabor
bugs975277
milestone30.0a1
Bug 975277 - Move the wrappedJSObject getter out of getPropertyDescriptor. r=gabor The current setup is kinda wrong, and doesn't work with HasPrototype Xrays. This change requires us to manually munge the holder, but that's probably ok for now.
js/xpconnect/wrappers/XrayWrapper.cpp
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -879,16 +879,35 @@ XrayTraits::resolveOwnProperty(JSContext
 
     if (found) {
         if (!JS_WrapPropertyDescriptor(cx, desc))
             return false;
         // Pretend the property lives on the wrapper.
         desc.object().set(wrapper);
         return true;
     }
+
+    // Handle .wrappedJSObject for subsuming callers. This should move once we
+    // sort out own-ness for the holder.
+    if (id == GetRTIdByIndex(cx, XPCJSRuntime::IDX_WRAPPED_JSOBJECT) &&
+        AccessCheck::wrapperSubsumes(wrapper))
+    {
+        if (!JS_AlreadyHasOwnPropertyById(cx, holder, id, &found))
+            return false;
+        if (!found && !JS_DefinePropertyById(cx, holder, id, UndefinedValue(),
+                                             wrappedJSObject_getter, nullptr,
+                                             JSPROP_ENUMERATE | JSPROP_SHARED)) {
+            return false;
+        }
+        if (!JS_GetPropertyDescriptorById(cx, holder, id, 0, desc))
+            return false;
+        desc.object().set(wrapper);
+        return true;
+    }
+
     return true;
 }
 
 bool
 XPCWrappedNativeXrayTraits::resolveOwnProperty(JSContext *cx, Wrapper &jsWrapper,
                                                HandleObject wrapper, HandleObject holder,
                                                HandleId id, MutableHandle<JSPropertyDescriptor> desc,
                                                unsigned flags)
@@ -1453,30 +1472,16 @@ XrayWrapper<Base, Traits>::getPropertyDe
         return true;
     }
 
     typename Traits::ResolvingIdImpl resolving(cx, wrapper, id);
 
     if (!holder)
         return false;
 
-    // Only chrome wrappers and same-origin xrays (used by jetpack sandboxes)
-    // get .wrappedJSObject. We can check this by determining if the compartment
-    // of the wrapper subsumes that of the wrappee.
-    XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
-    if (AccessCheck::wrapperSubsumes(wrapper) &&
-        id == rt->GetStringID(XPCJSRuntime::IDX_WRAPPED_JSOBJECT)) {
-        desc.object().set(wrapper);
-        desc.setAttributes(JSPROP_ENUMERATE|JSPROP_SHARED);
-        desc.setGetter(wrappedJSObject_getter);
-        desc.setSetter(nullptr);
-        desc.value().set(JSVAL_VOID);
-        return true;
-    }
-
     // Ordering is important here.
     //
     // We first need to call resolveOwnProperty, even before checking the holder,
     // because there might be a new dynamic |own| property that appears and
     // shadows a previously-resolved non-own property that we cached on the
     // holder. This can happen with indexed properties on NodeLists, for example,
     // which are |own| value props.
     //