Bug 1363208 part 9. Remove now-unused cross-origin Xray infrastructure. r=peterv
authorBoris Zbarsky <bzbarsky@mit.edu>
Mon, 21 Jan 2019 03:33:55 +0000
changeset 454672 dbab9ee37db197462dd3dee9d947d44e9d644428
parent 454671 d4d779afb736002a8621b86a24d52783f0f49e87
child 454673 311d09aeb1ab0e1ee583123634a4b28975172969
push id111317
push userrmaries@mozilla.com
push dateMon, 21 Jan 2019 18:01:55 +0000
treeherdermozilla-inbound@19db0edfbc10 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv
bugs1363208
milestone66.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 1363208 part 9. Remove now-unused cross-origin Xray infrastructure. r=peterv Differential Revision: https://phabricator.services.mozilla.com/D15433
dom/bindings/Codegen.py
js/xpconnect/wrappers/AccessCheck.cpp
js/xpconnect/wrappers/AccessCheck.h
js/xpconnect/wrappers/FilteringWrapper.cpp
js/xpconnect/wrappers/FilteringWrapper.h
js/xpconnect/wrappers/XrayWrapper.cpp
js/xpconnect/wrappers/XrayWrapper.h
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -4225,58 +4225,16 @@ class CGCrossOriginProperties(CGThing):
             #if defined(__clang__)
             #pragma clang diagnostic pop
             #endif
             """,
             attributeSpecs=",\n".join(self.attributeSpecs),
             methodSpecs=",\n".join(self.methodSpecs))
 
 
-class CGIsPermittedMethod(CGAbstractMethod):
-    """
-    crossOriginGetters/Setters/Methods are sets of names of the relevant members.
-    """
-    def __init__(self, descriptor, crossOriginGetters, crossOriginSetters,
-                 crossOriginMethods):
-        self.crossOriginGetters = crossOriginGetters
-        self.crossOriginSetters = crossOriginSetters
-        self.crossOriginMethods = crossOriginMethods
-        args = [Argument("JSFlatString*", "prop"),
-                Argument("char16_t", "propFirstChar"),
-                Argument("bool", "set")]
-        CGAbstractMethod.__init__(self, descriptor, "IsPermitted", "bool", args,
-                                  inline=True)
-
-    def definition_body(self):
-        allNames = self.crossOriginGetters | self.crossOriginSetters | self.crossOriginMethods
-        readwrite = self.crossOriginGetters & self.crossOriginSetters
-        readonly = (self.crossOriginGetters - self.crossOriginSetters) | self.crossOriginMethods
-        writeonly = self.crossOriginSetters - self.crossOriginGetters
-        cases = {}
-        for name in sorted(allNames):
-            cond = 'JS_FlatStringEqualsAscii(prop, "%s")' % name
-            if name in readonly:
-                cond = "!set && %s" % cond
-            elif name in writeonly:
-                cond = "set && %s" % cond
-            else:
-                assert name in readwrite
-            firstLetter = name[0]
-            case = cases.get(firstLetter, CGList([]))
-            case.append(CGGeneric("if (%s) {\n"
-                                  "  return true;\n"
-                                  "}\n" % cond))
-            cases[firstLetter] = case
-        caseList = []
-        for firstLetter in sorted(cases.keys()):
-            caseList.append(CGCase("'%s'" % firstLetter, cases[firstLetter]))
-        switch = CGSwitch("propFirstChar", caseList)
-        return switch.define() + "\nreturn false;\n"
-
-
 class CGCycleCollectionTraverseForOwningUnionMethod(CGAbstractMethod):
     """
     ImplCycleCollectionUnlink for owning union type.
     """
     def __init__(self, type):
         self.type = type
         args = [Argument("nsCycleCollectionTraversalCallback&", "aCallback"),
                 Argument("%s&" % CGUnionStruct.unionTypeName(type, True), "aUnion"),
@@ -13032,17 +12990,17 @@ class CGDescriptor(CGThing):
                                   descriptor.nativeType))
         parent = descriptor.interface.parent
         if parent:
             cgThings.append(CGGeneric("static_assert(IsRefcounted<NativeType>::value == IsRefcounted<%s::NativeType>::value,\n"
                                       "              \"Can't inherit from an interface with a different ownership model.\");\n" %
                                       toBindingNamespace(descriptor.parentPrototypeName)))
 
         defaultToJSONMethod = None
-        crossOriginMethods, crossOriginGetters, crossOriginSetters = set(), set(), set()
+        needCrossOriginPropertyArrays = False
         unscopableNames = list()
         for n in descriptor.interface.namedConstructors:
             cgThings.append(CGClassConstructor(descriptor, n,
                                                NamedConstructorName(n)))
         for m in descriptor.interface.members:
             if m.isMethod() and m.identifier.name == 'QueryInterface':
                 continue
 
@@ -13062,17 +13020,17 @@ class CGDescriptor(CGThing):
                             cgThings.append(CGStaticMethodJitinfo(m))
                     elif descriptor.interface.hasInterfacePrototypeObject():
                         specializedMethod = CGSpecializedMethod(descriptor, m)
                         cgThings.append(specializedMethod)
                         if m.returnsPromise():
                             cgThings.append(CGMethodPromiseWrapper(descriptor, specializedMethod))
                         cgThings.append(CGMemberJITInfo(descriptor, m))
                         if props.isCrossOriginMethod:
-                            crossOriginMethods.add(m.identifier.name)
+                            needCrossOriginPropertyArrays = True
             # If we've hit the maplike/setlike member itself, go ahead and
             # generate its convenience functions.
             elif m.isMaplikeOrSetlike():
                 cgThings.append(CGMaplikeOrSetlikeHelperGenerator(descriptor, m))
             elif m.isAttr():
                 if m.stringifier:
                     raise TypeError("Stringifier attributes not supported yet. "
                                     "See bug 824857.\n"
@@ -13086,29 +13044,29 @@ class CGDescriptor(CGThing):
                 elif descriptor.interface.hasInterfacePrototypeObject():
                     if isNonExposedNavigatorObjectGetter(m, descriptor):
                         continue
                     specializedGetter = CGSpecializedGetter(descriptor, m)
                     cgThings.append(specializedGetter)
                     if m.type.isPromise():
                         cgThings.append(CGGetterPromiseWrapper(descriptor, specializedGetter))
                     if props.isCrossOriginGetter:
-                        crossOriginGetters.add(m.identifier.name)
+                        needCrossOriginPropertyArrays = True
                 if not m.readonly:
                     if m.isStatic():
                         assert descriptor.interface.hasInterfaceObject()
                         cgThings.append(CGStaticSetter(descriptor, m))
                     elif descriptor.interface.hasInterfacePrototypeObject():
                         cgThings.append(CGSpecializedSetter(descriptor, m))
                         if props.isCrossOriginSetter:
-                            crossOriginSetters.add(m.identifier.name)
+                            needCrossOriginPropertyArrays = True
                 elif m.getExtendedAttribute("PutForwards"):
                     cgThings.append(CGSpecializedForwardingSetter(descriptor, m))
                     if props.isCrossOriginSetter:
-                        crossOriginSetters.add(m.identifier.name)
+                        needCrossOriginPropertyArrays = True
                 elif m.getExtendedAttribute("Replaceable"):
                     cgThings.append(CGSpecializedReplaceableSetter(descriptor, m))
                 elif m.getExtendedAttribute("LenientSetter"):
                     cgThings.append(CGSpecializedLenientSetter(descriptor, m))
                 if (not m.isStatic() and
                     descriptor.interface.hasInterfacePrototypeObject()):
                     cgThings.append(CGMemberJITInfo(descriptor, m))
             if m.isConst() and m.type.isPrimitive():
@@ -13250,23 +13208,19 @@ class CGDescriptor(CGThing):
         if descriptor.interface.hasInterfacePrototypeObject():
             cgThings.append(CGGetProtoObjectHandleMethod(descriptor))
             if descriptor.interface.hasChildInterfaces():
                 cgThings.append(CGGetProtoObjectMethod(descriptor))
         if descriptor.interface.hasInterfaceObject():
             cgThings.append(CGGetConstructorObjectHandleMethod(descriptor))
             cgThings.append(CGGetConstructorObjectMethod(descriptor))
 
-        # See whether we need we need to generate an IsPermitted method
-        if crossOriginGetters or crossOriginSetters or crossOriginMethods:
+        # See whether we need to generate cross-origin property arrays.
+        if needCrossOriginPropertyArrays:
             cgThings.append(CGCrossOriginProperties(descriptor))
-            cgThings.append(CGIsPermittedMethod(descriptor,
-                                                crossOriginGetters,
-                                                crossOriginSetters,
-                                                crossOriginMethods))
 
         cgThings = CGList((CGIndenter(t, declareOnly=True) for t in cgThings), "\n")
         cgThings = CGWrapper(cgThings, pre='\n', post='\n')
         self.cgRoot = CGWrapper(CGNamespace(toBindingNamespace(descriptor.name),
                                             cgThings),
                                 post='\n')
 
     def declare(self):
--- a/js/xpconnect/wrappers/AccessCheck.cpp
+++ b/js/xpconnect/wrappers/AccessCheck.cpp
@@ -84,145 +84,30 @@ bool AccessCheck::wrapperSubsumes(JSObje
 bool AccessCheck::isChrome(JS::Compartment* compartment) {
   return js::IsSystemCompartment(compartment);
 }
 
 bool AccessCheck::isChrome(JSObject* obj) {
   return isChrome(js::GetObjectCompartment(obj));
 }
 
-// Hardcoded policy for cross origin property access. See the HTML5 Spec.
-static bool IsPermitted(CrossOriginObjectType type, JSFlatString* prop,
-                        bool set) {
-  size_t propLength = JS_GetStringLength(JS_FORGET_STRING_FLATNESS(prop));
-  if (!propLength) {
-    return false;
-  }
-
-  char16_t propChar0 = JS_GetFlatStringCharAt(prop, 0);
-  if (type == CrossOriginLocation) {
-    return dom::Location_Binding::IsPermitted(prop, propChar0, set);
-  }
-  if (type == CrossOriginWindow) {
-    return dom::Window_Binding::IsPermitted(prop, propChar0, set);
-  }
-
-  return false;
-}
-
-static bool IsFrameId(JSContext* cx, JSObject* obj, jsid idArg) {
-  MOZ_ASSERT(!js::IsWrapper(obj));
-  RootedId id(cx, idArg);
-
-  nsGlobalWindowInner* win = WindowOrNull(obj);
-  if (!win) {
-    return false;
-  }
-
-  nsDOMWindowList* col = win->GetFrames();
-  if (!col) {
-    return false;
-  }
-
-  nsCOMPtr<mozIDOMWindowProxy> domwin;
-  if (JSID_IS_INT(id)) {
-    domwin = col->IndexedGetter(JSID_TO_INT(id));
-  } else if (JSID_IS_STRING(id)) {
-    nsAutoJSString idAsString;
-    if (!idAsString.init(cx, JSID_TO_STRING(id))) {
-      return false;
-    }
-    domwin = col->NamedItem(idAsString);
-  }
-
-  return domwin != nullptr;
-}
-
 CrossOriginObjectType IdentifyCrossOriginObject(JSObject* obj) {
   obj = js::UncheckedUnwrap(obj, /* stopAtWindowProxy = */ false);
   const js::Class* clasp = js::GetObjectClass(obj);
 
   if (clasp->name[0] == 'L' && !strcmp(clasp->name, "Location")) {
     return CrossOriginLocation;
   }
   if (clasp->name[0] == 'W' && !strcmp(clasp->name, "Window")) {
     return CrossOriginWindow;
   }
 
   return CrossOriginOpaque;
 }
 
-bool AccessCheck::isCrossOriginAccessPermitted(JSContext* cx,
-                                               HandleObject wrapper,
-                                               HandleId id,
-                                               Wrapper::Action act) {
-  if (act == Wrapper::CALL) {
-    return false;
-  }
-
-  if (act == Wrapper::ENUMERATE) {
-    return true;
-  }
-
-  // For the case of getting a property descriptor, we allow if either GET or
-  // SET is allowed, and rely on FilteringWrapper to filter out any disallowed
-  // accessors.
-  if (act == Wrapper::GET_PROPERTY_DESCRIPTOR) {
-    return isCrossOriginAccessPermitted(cx, wrapper, id, Wrapper::GET) ||
-           isCrossOriginAccessPermitted(cx, wrapper, id, Wrapper::SET);
-  }
-
-  RootedObject obj(
-      cx, js::UncheckedUnwrap(wrapper, /* stopAtWindowProxy = */ false));
-  CrossOriginObjectType type = IdentifyCrossOriginObject(obj);
-  if (JSID_IS_STRING(id)) {
-    if (IsPermitted(type, JSID_TO_FLAT_STRING(id), act == Wrapper::SET)) {
-      return true;
-    }
-  }
-
-  if (type != CrossOriginOpaque && IsCrossOriginWhitelistedProp(cx, id)) {
-    // We always allow access to "then", @@toStringTag, @@hasInstance, and
-    // @@isConcatSpreadable.  But then we nerf them to be a value descriptor
-    // with value undefined in CrossOriginXrayWrapper.
-    return true;
-  }
-
-  if (act != Wrapper::GET) {
-    return false;
-  }
-
-  // Check for frame IDs. If we're resolving named frames, make sure to only
-  // resolve ones that don't shadow native properties. See bug 860494.
-  if (type == CrossOriginWindow) {
-    if (JSID_IS_STRING(id)) {
-      bool wouldShadow = false;
-      if (!XrayUtils::HasNativeProperty(cx, wrapper, id, &wouldShadow) ||
-          wouldShadow) {
-        // If the named subframe matches the name of a DOM constructor,
-        // the global resolve triggered by the HasNativeProperty call
-        // above will try to perform a CheckedUnwrap on |wrapper|, and
-        // throw a security error if it fails. That exception isn't
-        // really useful for our callers, so we silence it and just
-        // deny access to the property (since it matched a builtin).
-        //
-        // Note that this would be a problem if the resolve code ever
-        // tried to CheckedUnwrap the wrapper _before_ concluding that
-        // the name corresponds to a builtin global property, since it
-        // would mean that we'd never permit cross-origin named subframe
-        // access (something we regrettably need to support).
-        JS_ClearPendingException(cx);
-        return false;
-      }
-    }
-    return IsFrameId(cx, obj, id);
-  }
-  return false;
-}
-
 bool AccessCheck::checkPassToPrivilegedCode(JSContext* cx, HandleObject wrapper,
                                             HandleValue v) {
   // Primitives are fine.
   if (!v.isObject()) {
     return true;
   }
   RootedObject obj(cx, &v.toObject());
 
--- a/js/xpconnect/wrappers/AccessCheck.h
+++ b/js/xpconnect/wrappers/AccessCheck.h
@@ -19,19 +19,16 @@ class AccessCheck {
  public:
   static bool subsumes(JSObject* a, JSObject* b);
   static bool wrapperSubsumes(JSObject* wrapper);
   static bool subsumesConsideringDomain(JS::Compartment* a, JS::Compartment* b);
   static bool subsumesConsideringDomainIgnoringFPD(JS::Compartment* a,
                                                    JS::Compartment* b);
   static bool isChrome(JS::Compartment* compartment);
   static bool isChrome(JSObject* obj);
-  static bool isCrossOriginAccessPermitted(JSContext* cx, JS::HandleObject obj,
-                                           JS::HandleId id,
-                                           js::Wrapper::Action act);
   static bool checkPassToPrivilegedCode(JSContext* cx, JS::HandleObject wrapper,
                                         JS::HandleValue value);
   static bool checkPassToPrivilegedCode(JSContext* cx, JS::HandleObject wrapper,
                                         const JS::CallArgs& args);
   // Called to report the correct sort of exception when our policy denies and
   // should throw.  The accessType argument should be one of "access",
   // "define", "delete", depending on which operation is being denied.
   static void reportCrossOriginDenial(JSContext* cx, JS::HandleId id,
@@ -84,41 +81,16 @@ struct OpaqueWithCall : public Policy {
     return false;
   }
   static bool checkCall(JSContext* cx, JS::HandleObject wrapper,
                         const JS::CallArgs& args) {
     return AccessCheck::checkPassToPrivilegedCode(cx, wrapper, args);
   }
 };
 
-// This policy only permits access to properties that are safe to be used
-// across origins.
-struct CrossOriginAccessiblePropertiesOnly : public Policy {
-  static bool check(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id,
-                    js::Wrapper::Action act) {
-    return AccessCheck::isCrossOriginAccessPermitted(cx, wrapper, id, act);
-  }
-  static bool deny(JSContext* cx, js::Wrapper::Action act, JS::HandleId id,
-                   bool mayThrow) {
-    // Silently fail for enumerate-like operations.
-    if (act == js::Wrapper::ENUMERATE) {
-      return true;
-    }
-    if (mayThrow) {
-      AccessCheck::reportCrossOriginDenial(cx, id,
-                                           NS_LITERAL_CSTRING("access"));
-    }
-    return false;
-  }
-  static bool allowNativeCall(JSContext* cx, JS::IsAcceptableThis test,
-                              JS::NativeImpl impl) {
-    return false;
-  }
-};
-
 // This class used to support permitting access to properties if they
 // appeared in an access list on the object, but now it acts like an
 // Opaque wrapper, with the exception that it fails silently for GET,
 // ENUMERATE, and GET_PROPERTY_DESCRIPTOR. This is done for backwards
 // compatibility. See bug 1397513.
 struct OpaqueWithSilentFailing : public Policy {
   static bool check(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id,
                     js::Wrapper::Action act) {
--- a/js/xpconnect/wrappers/FilteringWrapper.cpp
+++ b/js/xpconnect/wrappers/FilteringWrapper.cpp
@@ -232,122 +232,20 @@ bool FilteringWrapper<Base, Policy>::ent
     *bp =
         JS_IsExceptionPending(cx) ? false : Policy::deny(cx, act, id, mayThrow);
     return false;
   }
   *bp = true;
   return true;
 }
 
-bool CrossOriginXrayWrapper::getPropertyDescriptor(
-    JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id,
-    JS::MutableHandle<PropertyDescriptor> desc) const {
-  if (!SecurityXrayDOM::getPropertyDescriptor(cx, wrapper, id, desc)) {
-    return false;
-  }
-  if (desc.object()) {
-    // Cross-origin DOM objects do not have symbol-named properties apart
-    // from the ones we add ourselves here.
-    MOZ_ASSERT(!JSID_IS_SYMBOL(id),
-               "What's this symbol-named property that appeared on a "
-               "Window or Location instance?");
-
-    // All properties on cross-origin DOM objects are |own|.
-    desc.object().set(wrapper);
-
-    // All properties on cross-origin DOM objects are "configurable". Any
-    // value attributes are read-only.  Indexed properties are enumerable,
-    // but nothing else is.
-    if (!JSID_IS_INT(id)) {
-      desc.attributesRef() &= ~JSPROP_ENUMERATE;
-    }
-    desc.attributesRef() &= ~JSPROP_PERMANENT;
-    if (!desc.getter() && !desc.setter()) {
-      desc.attributesRef() |= JSPROP_READONLY;
-    }
-  } else if (IsCrossOriginWhitelistedProp(cx, id)) {
-    // Spec says to return PropertyDescriptor {
-    //   [[Value]]: undefined, [[Writable]]: false, [[Enumerable]]: false,
-    //   [[Configurable]]: true
-    // }.
-    //
-    desc.setDataDescriptor(JS::UndefinedHandleValue, JSPROP_READONLY);
-    desc.object().set(wrapper);
-  }
-
-  return true;
-}
-
-bool CrossOriginXrayWrapper::getOwnPropertyDescriptor(
-    JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id,
-    JS::MutableHandle<PropertyDescriptor> desc) const {
-  // All properties on cross-origin DOM objects are |own|.
-  return getPropertyDescriptor(cx, wrapper, id, desc);
-}
-
-bool CrossOriginXrayWrapper::ownPropertyKeys(JSContext* cx,
-                                             JS::Handle<JSObject*> wrapper,
-                                             JS::AutoIdVector& props) const {
-  // All properties on cross-origin objects are supposed |own|, despite what
-  // the underlying native object may report. Override the inherited trap to
-  // avoid passing JSITER_OWNONLY as a flag.
-  if (!SecurityXrayDOM::getPropertyKeys(cx, wrapper, JSITER_HIDDEN, props)) {
-    return false;
-  }
-
-  return AppendCrossOriginWhitelistedPropNames(cx, props);
-}
-
-bool CrossOriginXrayWrapper::defineProperty(JSContext* cx,
-                                            JS::Handle<JSObject*> wrapper,
-                                            JS::Handle<jsid> id,
-                                            JS::Handle<PropertyDescriptor> desc,
-                                            JS::ObjectOpResult& result) const {
-  AccessCheck::reportCrossOriginDenial(cx, id, NS_LITERAL_CSTRING("define"));
-  return false;
-}
-
-bool CrossOriginXrayWrapper::delete_(JSContext* cx,
-                                     JS::Handle<JSObject*> wrapper,
-                                     JS::Handle<jsid> id,
-                                     JS::ObjectOpResult& result) const {
-  AccessCheck::reportCrossOriginDenial(cx, id, NS_LITERAL_CSTRING("delete"));
-  return false;
-}
-
-bool CrossOriginXrayWrapper::setPrototype(JSContext* cx,
-                                          JS::HandleObject wrapper,
-                                          JS::HandleObject proto,
-                                          JS::ObjectOpResult& result) const {
-  // https://html.spec.whatwg.org/multipage/browsers.html#windowproxy-setprototypeof
-  // and
-  // https://html.spec.whatwg.org/multipage/browsers.html#location-setprototypeof
-  // both say to call SetImmutablePrototype, which does nothing and just
-  // returns whether the passed-in value equals the current prototype.  Our
-  // current prototype is always null, so this just comes down to returning
-  // whether null was passed in.
-  //
-  // In terms of ObjectOpResult that means calling one of the fail*() things
-  // on it if non-null was passed, and it's got one that does just what we
-  // want.
-  if (!proto) {
-    return result.succeed();
-  }
-  return result.failCantSetProto();
-}
-
-#define XOW \
-  FilteringWrapper<CrossOriginXrayWrapper, CrossOriginAccessiblePropertiesOnly>
 #define NNXOW FilteringWrapper<CrossCompartmentSecurityWrapper, Opaque>
 #define NNXOWC FilteringWrapper<CrossCompartmentSecurityWrapper, OpaqueWithCall>
 
 template <>
-const XOW XOW::singleton(0);
-template <>
 const NNXOW NNXOW::singleton(0);
 template <>
 const NNXOWC NNXOWC::singleton(0);
 
-template class XOW;
 template class NNXOW;
 template class NNXOWC;
 template class ChromeObjectWrapperBase;
 }  // namespace xpc
--- a/js/xpconnect/wrappers/FilteringWrapper.h
+++ b/js/xpconnect/wrappers/FilteringWrapper.h
@@ -48,43 +48,11 @@ class FilteringWrapper : public Base {
                           const JS::CallArgs& args) const override;
 
   virtual bool getPrototype(JSContext* cx, JS::HandleObject wrapper,
                             JS::MutableHandleObject protop) const override;
 
   static const FilteringWrapper singleton;
 };
 
-/*
- * The HTML5 spec mandates very particular object behavior for cross-origin DOM
- * objects (Window and Location), some of which runs contrary to the way that
- * other XrayWrappers behave. We use this class to implement those semantics.
- */
-class CrossOriginXrayWrapper : public SecurityXrayDOM {
- public:
-  constexpr explicit CrossOriginXrayWrapper(unsigned flags)
-      : SecurityXrayDOM(flags) {}
-
-  virtual bool getOwnPropertyDescriptor(
-      JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id,
-      JS::MutableHandle<JS::PropertyDescriptor> desc) const override;
-  virtual bool defineProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
-                              JS::Handle<jsid> id,
-                              JS::Handle<JS::PropertyDescriptor> desc,
-                              JS::ObjectOpResult& result) const override;
-  virtual bool ownPropertyKeys(JSContext* cx, JS::Handle<JSObject*> wrapper,
-                               JS::AutoIdVector& props) const override;
-  virtual bool delete_(JSContext* cx, JS::Handle<JSObject*> wrapper,
-                       JS::Handle<jsid> id,
-                       JS::ObjectOpResult& result) const override;
-
-  virtual bool getPropertyDescriptor(
-      JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id,
-      JS::MutableHandle<JS::PropertyDescriptor> desc) const override;
-
-  virtual bool setPrototype(JSContext* cx, JS::HandleObject wrapper,
-                            JS::HandleObject proto,
-                            JS::ObjectOpResult& result) const override;
-};
-
 }  // namespace xpc
 
 #endif /* __FilteringWrapper_h__ */
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -1869,18 +1869,17 @@ bool XrayWrapper<Base, Traits>::isExtens
   *extensible = true;
   return true;
 }
 
 template <typename Base, typename Traits>
 bool XrayWrapper<Base, Traits>::getPropertyDescriptor(
     JSContext* cx, HandleObject wrapper, HandleId id,
     JS::MutableHandle<PropertyDescriptor> desc) const {
-  // CrossOriginXrayWrapper::getOwnPropertyDescriptor calls this.
-
+  // FIXME: This method is unused.  Will get sorted out in bug 1160757.
   assertEnteredPolicy(cx, wrapper, id,
                       BaseProxyHandler::GET | BaseProxyHandler::SET |
                           BaseProxyHandler::GET_PROPERTY_DESCRIPTOR);
   RootedObject target(cx, Traits::getTargetObject(wrapper));
   RootedObject holder(cx, Traits::singleton.ensureHolder(cx, wrapper));
 
   if (!holder) {
     return false;
@@ -2371,17 +2370,16 @@ bool XrayWrapper<Base, Traits>::getPrope
  * unwrap the wrapper).
  */
 
 template <typename Base, typename Traits>
 const xpc::XrayWrapper<Base, Traits> xpc::XrayWrapper<Base, Traits>::singleton(
     0);
 
 template class PermissiveXrayDOM;
-template class SecurityXrayDOM;
 template class PermissiveXrayJS;
 template class PermissiveXrayOpaque;
 
 /*
  * This callback is used by the JS engine to test if a proxy handler is for a
  * cross compartment xray with no security requirements.
  */
 static bool IsCrossCompartmentXrayCallback(
--- a/js/xpconnect/wrappers/XrayWrapper.h
+++ b/js/xpconnect/wrappers/XrayWrapper.h
@@ -441,25 +441,22 @@ class XrayWrapper : public Base {
 
  protected:
   bool getPropertyKeys(JSContext* cx, JS::Handle<JSObject*> wrapper,
                        unsigned flags, JS::AutoIdVector& props) const;
 };
 
 #define PermissiveXrayDOM \
   xpc::XrayWrapper<js::CrossCompartmentWrapper, xpc::DOMXrayTraits>
-#define SecurityXrayDOM \
-  xpc::XrayWrapper<js::CrossCompartmentSecurityWrapper, xpc::DOMXrayTraits>
 #define PermissiveXrayJS \
   xpc::XrayWrapper<js::CrossCompartmentWrapper, xpc::JSXrayTraits>
 #define PermissiveXrayOpaque \
   xpc::XrayWrapper<js::CrossCompartmentWrapper, xpc::OpaqueXrayTraits>
 
 extern template class PermissiveXrayDOM;
-extern template class SecurityXrayDOM;
 extern template class PermissiveXrayJS;
 extern template class PermissiveXrayOpaque;
 
 /*
  * Slots for Xray expando objects.  See comments in XrayWrapper.cpp for details
  * of how these get used; we mostly want the value of JSSLOT_EXPANDO_COUNT here.
  */
 enum ExpandoSlots {