Bug 1440949 - Allow plain JS objects to request addon interposition;r=kmag draft
authorBrian Grinstead <bgrinstead@mozilla.com>
Mon, 26 Feb 2018 13:37:15 -0800
changeset 760098 203fe656da3ecd514d4e27ad0eeb4885cf4e9b0b
parent 759477 bfe62272d2a21f9d10d45e5aaa680f5c735604ae
push id100538
push userbgrinstead@mozilla.com
push dateMon, 26 Feb 2018 21:37:24 +0000
reviewerskmag
bugs1440949, 1392352
milestone60.0a1
Bug 1440949 - Allow plain JS objects to request addon interposition;r=kmag This is needed to allow interposition for gBrowser, which will change from a DOM node into a plain JS object in Bug 1392352. An object can set the `requiresAddonInterpositions` property to enable this feature. MozReview-Commit-ID: 4Uw5xzgZtXO
js/xpconnect/wrappers/AddonWrapper.cpp
--- a/js/xpconnect/wrappers/AddonWrapper.cpp
+++ b/js/xpconnect/wrappers/AddonWrapper.cpp
@@ -34,29 +34,45 @@ ReportASCIIErrorWithId(JSContext* cx, co
         return;
     JSAutoByteString bytes;
     if (!bytes.encodeUtf8(cx, idstr))
         return;
     JS_ReportErrorUTF8(cx, msg, bytes.ptr());
 }
 
 bool
+RequiresInterpositions(JSContext* cx, HandleObject unwrapped)
+{
+    Rooted<PropertyDescriptor> desc(cx);
+    JSAutoCompartment ac(cx, unwrapped);
+
+    if (!JS_GetOwnPropertyDescriptor(cx, unwrapped, "requiresAddonInterpositions", &desc)) {
+        JS_ClearPendingException(cx);
+        return false;
+    }
+
+    return desc.hasValue() && desc.value().isTrue();
+}
+
+bool
 InterposeProperty(JSContext* cx, HandleObject target, const nsIID* iid, HandleId id,
                   MutableHandle<PropertyDescriptor> descriptor)
 {
-    // We only want to do interpostion on DOM instances and
-    // wrapped natives.
+    // We only want to do interpostion on DOM instances,
+    // wrapped natives, or if the object explicitly requests it.
     RootedObject unwrapped(cx, UncheckedUnwrap(target));
     const js::Class* clasp = js::GetObjectClass(unwrapped);
     bool isCPOW = jsipc::IsWrappedCPOW(unwrapped);
+
     if (!mozilla::dom::IsDOMClass(clasp) &&
         !IS_WN_CLASS(clasp) &&
         !IS_PROTO_CLASS(clasp) &&
         clasp != &OuterWindowProxyClass &&
-        !isCPOW) {
+        !isCPOW &&
+        !RequiresInterpositions(cx, unwrapped)) {
         return true;
     }
 
     XPCWrappedNativeScope* scope = ObjectScope(CurrentGlobalOrNull(cx));
     MOZ_ASSERT(scope->HasInterposition());
 
     nsCOMPtr<nsIAddonInterposition> interp = scope->GetInterposition();
     InterpositionWhitelist* wl = XPCWrappedNativeScope::GetInterpositionWhitelist(interp);