Bug 999297 - Implement xpc::UnwrapReflectorToISupports. r=bz
authorBobby Holley <bobbyholley@gmail.com>
Thu, 01 May 2014 11:03:11 -0700
changeset 181268 660ddfb69dc52596869d62368b2194acac1d440a
parent 181267 9f4a5b6678ddcaa7b717865fb2a05d324d8075de
child 181269 d92c11752f44d1e9704f837a678ee218f9254620
push id26699
push usercbook@mozilla.com
push dateFri, 02 May 2014 12:30:59 +0000
treeherdermozilla-central@66ea09d0c951 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs999297
milestone32.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 999297 - Implement xpc::UnwrapReflectorToISupports. r=bz I kind of thought we already had something like this, but I couldn't find anything.
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcprivate.h
js/xpconnect/src/xpcpublic.h
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -623,38 +623,44 @@ nsXPConnect::GetWrappedNativeOfJSObject(
         return NS_ERROR_FAILURE;
     }
 
     nsRefPtr<XPCWrappedNative> temp = XPCWrappedNative::Get(aJSObj);
     temp.forget(_retval);
     return NS_OK;
 }
 
+nsISupports*
+xpc::UnwrapReflectorToISupports(JSObject *reflector)
+{
+    // Unwrap security wrappers, if allowed.
+    reflector = js::CheckedUnwrap(reflector, /* stopAtOuter = */ false);
+    if (!reflector)
+        return nullptr;
+
+    // Try XPCWrappedNatives.
+    if (IS_WN_REFLECTOR(reflector)) {
+        XPCWrappedNative *wn = XPCWrappedNative::Get(reflector);
+        if (!wn)
+            return nullptr;
+        return wn->Native();
+    }
+
+    // Try DOM objects.
+    nsCOMPtr<nsISupports> canonical =
+        do_QueryInterface(mozilla::dom::UnwrapDOMObjectToISupports(reflector));
+    return canonical;
+}
+
 /* nsISupports getNativeOfWrapper(in JSContextPtr aJSContext, in JSObjectPtr  aJSObj); */
 NS_IMETHODIMP_(nsISupports*)
 nsXPConnect::GetNativeOfWrapper(JSContext *aJSContext,
                                 JSObject *aJSObj)
 {
-    MOZ_ASSERT(aJSContext, "bad param");
-    MOZ_ASSERT(aJSObj, "bad param");
-
-    aJSObj = js::CheckedUnwrap(aJSObj, /* stopAtOuter = */ false);
-    if (!aJSObj) {
-        JS_ReportError(aJSContext, "Permission denied to get native of security wrapper");
-        return nullptr;
-    }
-    if (IS_WN_REFLECTOR(aJSObj)) {
-        if (XPCWrappedNative *wn = XPCWrappedNative::Get(aJSObj))
-            return wn->Native();
-        return nullptr;
-    }
-
-    nsCOMPtr<nsISupports> canonical =
-        do_QueryInterface(mozilla::dom::UnwrapDOMObjectToISupports(aJSObj));
-    return canonical;
+    return UnwrapReflectorToISupports(aJSObj);
 }
 
 /* nsIXPConnectWrappedNative getWrappedNativeOfNativeObject (in JSContextPtr aJSContext, in JSObjectPtr aScope, in nsISupports aCOMObj, in nsIIDRef aIID); */
 NS_IMETHODIMP
 nsXPConnect::GetWrappedNativeOfNativeObject(JSContext * aJSContext,
                                             JSObject * aScopeArg,
                                             nsISupports *aCOMObj,
                                             const nsIID & aIID,
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -2535,16 +2535,19 @@ public:
 
     static bool GetNativeInterfaceFromJSObject(void** dest, JSObject* src,
                                                const nsID* iid,
                                                nsresult* pErr);
     static bool JSObject2NativeInterface(void** dest, JS::HandleObject src,
                                          const nsID* iid,
                                          nsISupports* aOuter,
                                          nsresult* pErr);
+
+    // Note - This return the XPCWrappedNative, rather than the native itself,
+    // for the WN case. You probably want UnwrapReflectorToISupports.
     static bool GetISupportsFromJSObject(JSObject* obj, nsISupports** iface);
 
     /**
      * Convert a native array into a jsval.
      *
      * @param d [out] the resulting jsval
      * @param s the native array we're working with
      * @param type the type of objects in the array
--- a/js/xpconnect/src/xpcpublic.h
+++ b/js/xpconnect/src/xpcpublic.h
@@ -409,16 +409,23 @@ Throw(JSContext *cx, nsresult rv);
 
 /**
  * Every global should hold a native that implements the nsIGlobalObject interface.
  */
 nsIGlobalObject *
 GetNativeForGlobal(JSObject *global);
 
 /**
+ * Returns the nsISupports native behind a given reflector (either DOM or
+ * XPCWN).
+ */
+nsISupports *
+UnwrapReflectorToISupports(JSObject *reflector);
+
+/**
  * In some cases a native object does not really belong to any compartment (XBL,
  * document created from by XHR of a worker, etc.). But when for some reason we
  * have to wrap these natives (because of an event for example) instead of just
  * wrapping them into some random compartment we find on the context stack (like
  * we did previously) a default compartment is used. This function returns that
  * compartment's global. It is a singleton on the runtime.
  * If you find yourself wanting to use this compartment, you're probably doing
  * something wrong. Callers MUST consult with the XPConnect module owner before