Bug 1521907 part 2. Add dynamic CheckedUnwrap support to CrossOriginObjectWrapper. r=peterv
☠☠ backed out by 0afc21b5734a ☠ ☠
authorBoris Zbarsky <bzbarsky@mit.edu>
Thu, 31 Jan 2019 11:22:53 +0000
changeset 456456 b3daf5ca3d1199a9e41b4564b1aa7f560039ab0b
parent 456455 1b0a09a46c70e80316da90c9696cc7a9580af478
child 456457 ca65b46b0d3708a115042dd4f5484bdc7a269a6b
push id111652
push userncsoregi@mozilla.com
push dateFri, 01 Feb 2019 22:14:41 +0000
treeherdermozilla-inbound@a36422c1abbc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv
bugs1521907
milestone67.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 1521907 part 2. Add dynamic CheckedUnwrap support to CrossOriginObjectWrapper. r=peterv This will allow us to correctly handle CheckedUnwrapDynamic on wrappers around WindowProxy and Location. Differential Revision: https://phabricator.services.mozilla.com/D17882
dom/base/MaybeCrossOriginObject.cpp
dom/base/MaybeCrossOriginObject.h
js/xpconnect/wrappers/WrapperFactory.cpp
js/xpconnect/wrappers/WrapperFactory.h
--- a/dom/base/MaybeCrossOriginObject.cpp
+++ b/dom/base/MaybeCrossOriginObject.cpp
@@ -22,18 +22,18 @@ static bool IsLocation(JSObject* obj) {
   return strcmp(js::GetObjectClass(obj)->name, "Location") == 0;
 }
 #endif  // DEBUG
 
 namespace mozilla {
 namespace dom {
 
 /* static */
-bool MaybeCrossOriginObjectMixins::IsPlatformObjectSameOrigin(
-    JSContext* cx, JS::Handle<JSObject*> obj) {
+bool MaybeCrossOriginObjectMixins::IsPlatformObjectSameOrigin(JSContext* cx,
+                                                              JSObject* obj) {
   MOZ_ASSERT(!js::IsCrossCompartmentWrapper(obj));
   // WindowProxy and Window must always be same-Realm, so we can do
   // our IsPlatformObjectSameOrigin check against either one.  But verify that
   // in case we have a WindowProxy the right things happen.
   MOZ_ASSERT(js::GetNonCCWObjectRealm(obj) ==
                  // "true" for second arg means to unwrap WindowProxy to
                  // get at the Window.
                  js::GetNonCCWObjectRealm(js::UncheckedUnwrap(obj, true)),
--- a/dom/base/MaybeCrossOriginObject.h
+++ b/dom/base/MaybeCrossOriginObject.h
@@ -33,27 +33,27 @@
 
 namespace mozilla {
 namespace dom {
 
 // Methods that MaybeCrossOriginObject wants that do not depend on the "Base"
 // template parameter.  We can avoid having multiple instantiations of them by
 // pulling them out into this helper class.
 class MaybeCrossOriginObjectMixins {
- protected:
+ public:
   /**
    * Implementation of
    * <https://html.spec.whatwg.org/multipage/browsers.html#isplatformobjectsameorigin-(-o-)>.
    * "cx" and "obj" may or may not be same-compartment and even when
    * same-compartment may not be same-Realm.  "obj" can be a WindowProxy, a
    * Window, or a Location.
    */
-  static bool IsPlatformObjectSameOrigin(JSContext* cx,
-                                         JS::Handle<JSObject*> obj);
+  static bool IsPlatformObjectSameOrigin(JSContext* cx, JSObject* obj);
 
+ protected:
   /**
    * Implementation of
    * <https://html.spec.whatwg.org/multipage/browsers.html#crossorigingetownpropertyhelper-(-o,-p-)>.
    *
    * "cx" and "obj" are expected to be different-Realm here, and may be
    * different-compartment.  "obj" can be a "WindowProxy" or a "Location" or a
    * cross-process proxy for one of those.
    */
--- a/js/xpconnect/wrappers/WrapperFactory.cpp
+++ b/js/xpconnect/wrappers/WrapperFactory.cpp
@@ -14,16 +14,17 @@
 
 #include "xpcprivate.h"
 #include "XPCMaps.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "jsfriendapi.h"
 #include "mozilla/jsipc/CrossProcessObjectWrappers.h"
 #include "mozilla/Likely.h"
 #include "mozilla/dom/ScriptSettings.h"
+#include "mozilla/dom/MaybeCrossOriginObject.h"
 #include "nsContentUtils.h"
 #include "nsXULAppAPI.h"
 
 using namespace JS;
 using namespace js;
 using namespace mozilla;
 
 namespace xpc {
@@ -358,16 +359,25 @@ static void DEBUG_CheckUnwrapSafety(Hand
 }
 #else
 #  define DEBUG_CheckUnwrapSafety(obj, handler, origin, target) \
     {}
 #endif
 
 const CrossOriginObjectWrapper CrossOriginObjectWrapper::singleton;
 
+bool CrossOriginObjectWrapper::dynamicCheckedUnwrapAllowed(
+    JSObject* obj, JSContext* cx) const {
+  MOZ_ASSERT(js::GetProxyHandler(obj) == this,
+             "Why are we getting called for some random object?");
+  JSObject* target = wrappedObject(obj);
+  return dom::MaybeCrossOriginObjectMixins::IsPlatformObjectSameOrigin(cx,
+                                                                       target);
+}
+
 static const Wrapper* SelectWrapper(bool securityWrapper, XrayType xrayType,
                                     bool waiveXrays, JSObject* obj) {
   // Waived Xray uses a modified CCW that has transparent behavior but
   // transitively waives Xrays on arguments.
   if (waiveXrays) {
     MOZ_ASSERT(!securityWrapper);
     return &WaiveXrayWrapper::singleton;
   }
--- a/js/xpconnect/wrappers/WrapperFactory.h
+++ b/js/xpconnect/wrappers/WrapperFactory.h
@@ -33,16 +33,18 @@ class CrossOriginObjectWrapper : public 
   // We don't want to inherit from CrossCompartmentWrapper, because we don't
   // want the compartment-entering behavior it has.  But we do want to set the
   // CROSS_COMPARTMENT flag on js::Wrapper so that we test true for
   // is<js::CrossCompartmentWrapperObject> and so forth.
   constexpr explicit CrossOriginObjectWrapper()
       : js::Wrapper(CROSS_COMPARTMENT, /* aHasPrototype = */ false,
                     /* aHasSecurityPolicy = */ true) {}
 
+  bool dynamicCheckedUnwrapAllowed(JSObject* obj, JSContext* cx) const override;
+
   static const CrossOriginObjectWrapper singleton;
 };
 
 class WrapperFactory {
  public:
   enum {
     WAIVE_XRAY_WRAPPER_FLAG = js::Wrapper::LAST_USED_FLAG << 1,
     IS_XRAY_WRAPPER_FLAG = WAIVE_XRAY_WRAPPER_FLAG << 1