tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Wrapper.h (24754B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      3 * This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef js_Wrapper_h
      8 #define js_Wrapper_h
      9 
     10 #include "mozilla/Attributes.h"
     11 
     12 #include "js/Proxy.h"
     13 
     14 namespace js {
     15 struct CompartmentFilter;
     16 
     17 /*
     18 * Helper for Wrapper::New default options.
     19 *
     20 * Callers of Wrapper::New() who wish to specify a prototype for the created
     21 * Wrapper, *MUST* construct a WrapperOptions with a JSContext.
     22 */
     23 class MOZ_STACK_CLASS WrapperOptions : public ProxyOptions {
     24 public:
     25  WrapperOptions() : ProxyOptions(false), proto_() {}
     26 
     27  explicit WrapperOptions(JSContext* cx) : ProxyOptions(false), proto_() {
     28    proto_.emplace(cx);
     29  }
     30 
     31  inline JSObject* proto() const;
     32  WrapperOptions& setProto(JSObject* protoArg) {
     33    MOZ_ASSERT(proto_);
     34    *proto_ = protoArg;
     35    return *this;
     36  }
     37 
     38 private:
     39  mozilla::Maybe<JS::RootedObject> proto_;
     40 };
     41 
     42 // Base class for proxy handlers that want to forward all operations to an
     43 // object stored in the proxy's private slot.
     44 class JS_PUBLIC_API ForwardingProxyHandler : public BaseProxyHandler {
     45 public:
     46  using BaseProxyHandler::BaseProxyHandler;
     47 
     48  /* Standard internal methods. */
     49  virtual bool getOwnPropertyDescriptor(
     50      JSContext* cx, JS::HandleObject proxy, JS::HandleId id,
     51      JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> desc)
     52      const override;
     53  virtual bool defineProperty(JSContext* cx, JS::HandleObject proxy,
     54                              JS::HandleId id,
     55                              JS::Handle<JS::PropertyDescriptor> desc,
     56                              JS::ObjectOpResult& result) const override;
     57  virtual bool ownPropertyKeys(JSContext* cx, JS::HandleObject proxy,
     58                               JS::MutableHandleIdVector props) const override;
     59  virtual bool delete_(JSContext* cx, JS::HandleObject proxy, JS::HandleId id,
     60                       JS::ObjectOpResult& result) const override;
     61  virtual bool enumerate(JSContext* cx, JS::HandleObject proxy,
     62                         JS::MutableHandleIdVector props) const override;
     63  virtual bool getPrototype(JSContext* cx, JS::HandleObject proxy,
     64                            JS::MutableHandleObject protop) const override;
     65  virtual bool setPrototype(JSContext* cx, JS::HandleObject proxy,
     66                            JS::HandleObject proto,
     67                            JS::ObjectOpResult& result) const override;
     68  virtual bool getPrototypeIfOrdinary(
     69      JSContext* cx, JS::HandleObject proxy, bool* isOrdinary,
     70      JS::MutableHandleObject protop) const override;
     71  virtual bool setImmutablePrototype(JSContext* cx, JS::HandleObject proxy,
     72                                     bool* succeeded) const override;
     73  virtual bool preventExtensions(JSContext* cx, JS::HandleObject proxy,
     74                                 JS::ObjectOpResult& result) const override;
     75  virtual bool isExtensible(JSContext* cx, JS::HandleObject proxy,
     76                            bool* extensible) const override;
     77  virtual bool has(JSContext* cx, JS::HandleObject proxy, JS::HandleId id,
     78                   bool* bp) const override;
     79  virtual bool get(JSContext* cx, JS::HandleObject proxy,
     80                   JS::HandleValue receiver, JS::HandleId id,
     81                   JS::MutableHandleValue vp) const override;
     82  virtual bool set(JSContext* cx, JS::HandleObject proxy, JS::HandleId id,
     83                   JS::HandleValue v, JS::HandleValue receiver,
     84                   JS::ObjectOpResult& result) const override;
     85  virtual bool call(JSContext* cx, JS::HandleObject proxy,
     86                    const JS::CallArgs& args) const override;
     87  virtual bool construct(JSContext* cx, JS::HandleObject proxy,
     88                         const JS::CallArgs& args) const override;
     89 
     90  /* SpiderMonkey extensions. */
     91  virtual bool hasOwn(JSContext* cx, JS::HandleObject proxy, JS::HandleId id,
     92                      bool* bp) const override;
     93  virtual bool getOwnEnumerablePropertyKeys(
     94      JSContext* cx, JS::HandleObject proxy,
     95      JS::MutableHandleIdVector props) const override;
     96  virtual bool nativeCall(JSContext* cx, JS::IsAcceptableThis test,
     97                          JS::NativeImpl impl,
     98                          const JS::CallArgs& args) const override;
     99  virtual bool getBuiltinClass(JSContext* cx, JS::HandleObject proxy,
    100                               ESClass* cls) const override;
    101  virtual bool isArray(JSContext* cx, JS::HandleObject proxy,
    102                       JS::IsArrayAnswer* answer) const override;
    103  virtual const char* className(JSContext* cx,
    104                                JS::HandleObject proxy) const override;
    105  virtual JSString* fun_toString(JSContext* cx, JS::HandleObject proxy,
    106                                 bool isToSource) const override;
    107  virtual RegExpShared* regexp_toShared(JSContext* cx,
    108                                        JS::HandleObject proxy) const override;
    109  virtual bool boxedValue_unbox(JSContext* cx, JS::HandleObject proxy,
    110                                JS::MutableHandleValue vp) const override;
    111  virtual bool isCallable(JSObject* obj) const override;
    112  virtual bool isConstructor(JSObject* obj) const override;
    113 
    114  // Use the target object for private fields.
    115  virtual bool useProxyExpandoObjectForPrivateFields() const override {
    116    return false;
    117  }
    118 };
    119 
    120 /*
    121 * A wrapper is a proxy with a target object to which it generally forwards
    122 * operations, but may restrict access to certain operations or augment those
    123 * operations in various ways.
    124 *
    125 * A wrapper can be "unwrapped" in C++, exposing the underlying object.
    126 * Callers should be careful to avoid unwrapping security wrappers in the wrong
    127 * context.
    128 *
    129 * Important: If you add a method implementation here, you probably also need
    130 * to add an override in CrossCompartmentWrapper. If you don't, you risk
    131 * compartment mismatches. See bug 945826 comment 0.
    132 */
    133 class JS_PUBLIC_API Wrapper : public ForwardingProxyHandler {
    134  unsigned mFlags;
    135 
    136 public:
    137  explicit constexpr Wrapper(unsigned aFlags, bool aHasPrototype = false,
    138                             bool aHasSecurityPolicy = false)
    139      : ForwardingProxyHandler(&family, aHasPrototype, aHasSecurityPolicy),
    140        mFlags(aFlags) {}
    141 
    142  virtual bool finalizeInBackground(const JS::Value& priv) const override;
    143 
    144  /**
    145   * A hook subclasses can override to implement CheckedUnwrapDynamic
    146   * behavior.  The JSContext represents the "who is trying to unwrap?" Realm.
    147   * The JSObject is the wrapper that the caller is trying to unwrap.
    148   */
    149  virtual bool dynamicCheckedUnwrapAllowed(JS::HandleObject obj,
    150                                           JSContext* cx) const {
    151    MOZ_ASSERT(hasSecurityPolicy(), "Why are you asking?");
    152    return false;
    153  }
    154 
    155  using BaseProxyHandler::Action;
    156 
    157  enum Flags { CROSS_COMPARTMENT = 1 << 0, LAST_USED_FLAG = CROSS_COMPARTMENT };
    158 
    159  static JSObject* New(JSContext* cx, JSObject* obj, const Wrapper* handler,
    160                       const WrapperOptions& options = WrapperOptions());
    161 
    162  static JSObject* Renew(JSObject* existing, JSObject* obj,
    163                         const Wrapper* handler);
    164 
    165  static inline const Wrapper* wrapperHandler(const JSObject* wrapper);
    166 
    167  static JSObject* wrappedObject(JSObject* wrapper);
    168 
    169  unsigned flags() const { return mFlags; }
    170 
    171  bool isCrossCompartmentWrapper() const {
    172    return !!(mFlags & CROSS_COMPARTMENT);
    173  }
    174 
    175  static const char family;
    176  static const Wrapper singleton;
    177  static const Wrapper singletonWithPrototype;
    178 
    179  static JSObject* const defaultProto;
    180 };
    181 
    182 inline JSObject* WrapperOptions::proto() const {
    183  return proto_ ? *proto_ : Wrapper::defaultProto;
    184 }
    185 
    186 /* Base class for all cross compartment wrapper handlers. */
    187 class JS_PUBLIC_API CrossCompartmentWrapper : public Wrapper {
    188 public:
    189  explicit constexpr CrossCompartmentWrapper(unsigned aFlags,
    190                                             bool aHasPrototype = false,
    191                                             bool aHasSecurityPolicy = false)
    192      : Wrapper(CROSS_COMPARTMENT | aFlags, aHasPrototype, aHasSecurityPolicy) {
    193  }
    194 
    195  /* Standard internal methods. */
    196  virtual bool getOwnPropertyDescriptor(
    197      JSContext* cx, JS::HandleObject wrapper, JS::HandleId id,
    198      JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> desc)
    199      const override;
    200  virtual bool defineProperty(JSContext* cx, JS::HandleObject wrapper,
    201                              JS::HandleId id,
    202                              JS::Handle<JS::PropertyDescriptor> desc,
    203                              JS::ObjectOpResult& result) const override;
    204  virtual bool ownPropertyKeys(JSContext* cx, JS::HandleObject wrapper,
    205                               JS::MutableHandleIdVector props) const override;
    206  virtual bool delete_(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id,
    207                       JS::ObjectOpResult& result) const override;
    208  virtual bool enumerate(JSContext* cx, JS::HandleObject proxy,
    209                         JS::MutableHandleIdVector props) const override;
    210  virtual bool getPrototype(JSContext* cx, JS::HandleObject proxy,
    211                            JS::MutableHandleObject protop) const override;
    212  virtual bool setPrototype(JSContext* cx, JS::HandleObject proxy,
    213                            JS::HandleObject proto,
    214                            JS::ObjectOpResult& result) const override;
    215 
    216  virtual bool getPrototypeIfOrdinary(
    217      JSContext* cx, JS::HandleObject proxy, bool* isOrdinary,
    218      JS::MutableHandleObject protop) const override;
    219  virtual bool setImmutablePrototype(JSContext* cx, JS::HandleObject proxy,
    220                                     bool* succeeded) const override;
    221  virtual bool preventExtensions(JSContext* cx, JS::HandleObject wrapper,
    222                                 JS::ObjectOpResult& result) const override;
    223  virtual bool isExtensible(JSContext* cx, JS::HandleObject wrapper,
    224                            bool* extensible) const override;
    225  virtual bool has(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id,
    226                   bool* bp) const override;
    227  virtual bool get(JSContext* cx, JS::HandleObject wrapper,
    228                   JS::HandleValue receiver, JS::HandleId id,
    229                   JS::MutableHandleValue vp) const override;
    230  virtual bool set(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id,
    231                   JS::HandleValue v, JS::HandleValue receiver,
    232                   JS::ObjectOpResult& result) const override;
    233  virtual bool call(JSContext* cx, JS::HandleObject wrapper,
    234                    const JS::CallArgs& args) const override;
    235  virtual bool construct(JSContext* cx, JS::HandleObject wrapper,
    236                         const JS::CallArgs& args) const override;
    237 
    238  /* SpiderMonkey extensions. */
    239  virtual bool hasOwn(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id,
    240                      bool* bp) const override;
    241  virtual bool getOwnEnumerablePropertyKeys(
    242      JSContext* cx, JS::HandleObject wrapper,
    243      JS::MutableHandleIdVector props) const override;
    244  virtual bool nativeCall(JSContext* cx, JS::IsAcceptableThis test,
    245                          JS::NativeImpl impl,
    246                          const JS::CallArgs& args) const override;
    247  virtual const char* className(JSContext* cx,
    248                                JS::HandleObject proxy) const override;
    249  virtual JSString* fun_toString(JSContext* cx, JS::HandleObject wrapper,
    250                                 bool isToSource) const override;
    251  virtual RegExpShared* regexp_toShared(JSContext* cx,
    252                                        JS::HandleObject proxy) const override;
    253  virtual bool boxedValue_unbox(JSContext* cx, JS::HandleObject proxy,
    254                                JS::MutableHandleValue vp) const override;
    255 
    256  // Allocate CrossCompartmentWrappers in the nursery.
    257  virtual bool canNurseryAllocate() const override { return true; }
    258  void finalize(JS::GCContext* gcx, JSObject* proxy) const final {
    259    Wrapper::finalize(gcx, proxy);
    260  }
    261 
    262  static const CrossCompartmentWrapper singleton;
    263  static const CrossCompartmentWrapper singletonWithPrototype;
    264 };
    265 
    266 class JS_PUBLIC_API OpaqueCrossCompartmentWrapper
    267    : public CrossCompartmentWrapper {
    268 public:
    269  explicit constexpr OpaqueCrossCompartmentWrapper()
    270      : CrossCompartmentWrapper(0) {}
    271 
    272  /* Standard internal methods. */
    273  virtual bool getOwnPropertyDescriptor(
    274      JSContext* cx, JS::HandleObject wrapper, JS::HandleId id,
    275      JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> desc)
    276      const override;
    277  virtual bool defineProperty(JSContext* cx, JS::HandleObject wrapper,
    278                              JS::HandleId id,
    279                              JS::Handle<JS::PropertyDescriptor> desc,
    280                              JS::ObjectOpResult& result) const override;
    281  virtual bool ownPropertyKeys(JSContext* cx, JS::HandleObject wrapper,
    282                               JS::MutableHandleIdVector props) const override;
    283  virtual bool delete_(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id,
    284                       JS::ObjectOpResult& result) const override;
    285  virtual bool enumerate(JSContext* cx, JS::HandleObject proxy,
    286                         JS::MutableHandleIdVector props) const override;
    287  virtual bool getPrototype(JSContext* cx, JS::HandleObject wrapper,
    288                            JS::MutableHandleObject protop) const override;
    289  virtual bool setPrototype(JSContext* cx, JS::HandleObject wrapper,
    290                            JS::HandleObject proto,
    291                            JS::ObjectOpResult& result) const override;
    292  virtual bool getPrototypeIfOrdinary(
    293      JSContext* cx, JS::HandleObject wrapper, bool* isOrdinary,
    294      JS::MutableHandleObject protop) const override;
    295  virtual bool setImmutablePrototype(JSContext* cx, JS::HandleObject wrapper,
    296                                     bool* succeeded) const override;
    297  virtual bool preventExtensions(JSContext* cx, JS::HandleObject wrapper,
    298                                 JS::ObjectOpResult& result) const override;
    299  virtual bool isExtensible(JSContext* cx, JS::HandleObject wrapper,
    300                            bool* extensible) const override;
    301  virtual bool has(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id,
    302                   bool* bp) const override;
    303  virtual bool get(JSContext* cx, JS::HandleObject wrapper,
    304                   JS::HandleValue receiver, JS::HandleId id,
    305                   JS::MutableHandleValue vp) const override;
    306  virtual bool set(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id,
    307                   JS::HandleValue v, JS::HandleValue receiver,
    308                   JS::ObjectOpResult& result) const override;
    309  virtual bool call(JSContext* cx, JS::HandleObject wrapper,
    310                    const JS::CallArgs& args) const override;
    311  virtual bool construct(JSContext* cx, JS::HandleObject wrapper,
    312                         const JS::CallArgs& args) const override;
    313 
    314  /* SpiderMonkey extensions. */
    315  virtual bool hasOwn(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id,
    316                      bool* bp) const override;
    317  virtual bool getOwnEnumerablePropertyKeys(
    318      JSContext* cx, JS::HandleObject wrapper,
    319      JS::MutableHandleIdVector props) const override;
    320  virtual bool getBuiltinClass(JSContext* cx, JS::HandleObject wrapper,
    321                               ESClass* cls) const override;
    322  virtual bool isArray(JSContext* cx, JS::HandleObject obj,
    323                       JS::IsArrayAnswer* answer) const override;
    324  virtual const char* className(JSContext* cx,
    325                                JS::HandleObject wrapper) const override;
    326  virtual JSString* fun_toString(JSContext* cx, JS::HandleObject proxy,
    327                                 bool isToSource) const override;
    328 
    329  static const OpaqueCrossCompartmentWrapper singleton;
    330 };
    331 
    332 /*
    333 * Base class for security wrappers. A security wrapper is potentially hiding
    334 * all or part of some wrapped object thus SecurityWrapper defaults to denying
    335 * access to the wrappee. This is the opposite of Wrapper which tries to be
    336 * completely transparent.
    337 *
    338 * NB: Currently, only a few ProxyHandler operations are overridden to deny
    339 * access, relying on derived SecurityWrapper to block access when necessary.
    340 */
    341 template <class Base>
    342 class JS_PUBLIC_API SecurityWrapper : public Base {
    343 public:
    344  explicit constexpr SecurityWrapper(unsigned flags, bool hasPrototype = false)
    345      : Base(flags, hasPrototype, /* hasSecurityPolicy = */ true) {}
    346 
    347  virtual bool enter(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id,
    348                     Wrapper::Action act, bool mayThrow,
    349                     bool* bp) const override;
    350 
    351  virtual bool defineProperty(JSContext* cx, JS::HandleObject wrapper,
    352                              JS::HandleId id,
    353                              JS::Handle<JS::PropertyDescriptor> desc,
    354                              JS::ObjectOpResult& result) const override;
    355  virtual bool isExtensible(JSContext* cx, JS::HandleObject wrapper,
    356                            bool* extensible) const override;
    357  virtual bool preventExtensions(JSContext* cx, JS::HandleObject wrapper,
    358                                 JS::ObjectOpResult& result) const override;
    359  virtual bool setPrototype(JSContext* cx, JS::HandleObject proxy,
    360                            JS::HandleObject proto,
    361                            JS::ObjectOpResult& result) const override;
    362  virtual bool setImmutablePrototype(JSContext* cx, JS::HandleObject proxy,
    363                                     bool* succeeded) const override;
    364 
    365  virtual bool nativeCall(JSContext* cx, JS::IsAcceptableThis test,
    366                          JS::NativeImpl impl,
    367                          const JS::CallArgs& args) const override;
    368  virtual bool getBuiltinClass(JSContext* cx, JS::HandleObject wrapper,
    369                               ESClass* cls) const override;
    370  virtual bool isArray(JSContext* cx, JS::HandleObject wrapper,
    371                       JS::IsArrayAnswer* answer) const override;
    372  virtual RegExpShared* regexp_toShared(JSContext* cx,
    373                                        JS::HandleObject proxy) const override;
    374  virtual bool boxedValue_unbox(JSContext* cx, JS::HandleObject proxy,
    375                                JS::MutableHandleValue vp) const override;
    376 
    377  // Allow isCallable and isConstructor. They used to be class-level, and so
    378  // could not be guarded against.
    379 
    380  /*
    381   * Allow our subclasses to select the superclass behavior they want without
    382   * needing to specify an exact superclass.
    383   */
    384  typedef Base Permissive;
    385  typedef SecurityWrapper<Base> Restrictive;
    386 };
    387 
    388 typedef SecurityWrapper<CrossCompartmentWrapper>
    389    CrossCompartmentSecurityWrapper;
    390 
    391 extern JSObject* TransparentObjectWrapper(JSContext* cx,
    392                                          JS::HandleObject existing,
    393                                          JS::HandleObject obj);
    394 
    395 inline bool IsWrapper(const JSObject* obj) {
    396  return IsProxy(obj) && GetProxyHandler(obj)->family() == &Wrapper::family;
    397 }
    398 
    399 inline bool IsCrossCompartmentWrapper(const JSObject* obj) {
    400  return IsWrapper(obj) &&
    401         (Wrapper::wrapperHandler(obj)->flags() & Wrapper::CROSS_COMPARTMENT);
    402 }
    403 
    404 /* static */ inline const Wrapper* Wrapper::wrapperHandler(
    405    const JSObject* wrapper) {
    406  MOZ_ASSERT(IsWrapper(wrapper));
    407  return static_cast<const Wrapper*>(GetProxyHandler(wrapper));
    408 }
    409 
    410 // Given a JSObject, returns that object stripped of wrappers. If
    411 // stopAtWindowProxy is true, then this returns the WindowProxy if it was
    412 // previously wrapped. Otherwise, this returns the first object for which
    413 // JSObject::isWrapper returns false.
    414 //
    415 // ExposeToActiveJS is called on wrapper targets to allow gray marking
    416 // assertions to work while an incremental GC is in progress, but this means
    417 // that this cannot be called from the GC or off the main thread.
    418 JS_PUBLIC_API JSObject* UncheckedUnwrap(JSObject* obj,
    419                                        bool stopAtWindowProxy = true,
    420                                        unsigned* flagsp = nullptr);
    421 
    422 // Given a JSObject, returns that object stripped of wrappers, except
    423 // WindowProxy wrappers.  At each stage, the wrapper has the opportunity to veto
    424 // the unwrap. Null is returned if there are security wrappers that can't be
    425 // unwrapped.
    426 //
    427 // This does a static-only unwrap check: it basically checks whether _all_
    428 // globals in the wrapper's source compartment should be able to access the
    429 // wrapper target.  This won't necessarily return the right thing for the HTML
    430 // spec's cross-origin objects (WindowProxy and Location), but is fine to use
    431 // when failure to unwrap one of those objects wouldn't be a problem.  For
    432 // example, if you want to test whether your target object is a specific class
    433 // that's not WindowProxy or Location, you can use this.
    434 //
    435 // ExposeToActiveJS is called on wrapper targets to allow gray marking
    436 // assertions to work while an incremental GC is in progress, but this means
    437 // that this cannot be called from the GC or off the main thread.
    438 JS_PUBLIC_API JSObject* CheckedUnwrapStatic(JSObject* obj);
    439 
    440 // Unwrap only the outermost security wrapper, with the same semantics as
    441 // above. This is the checked version of Wrapper::wrappedObject.
    442 JS_PUBLIC_API JSObject* UnwrapOneCheckedStatic(JSObject* obj);
    443 
    444 // Given a JSObject, returns that object stripped of wrappers. At each stage,
    445 // the security wrapper has the opportunity to veto the unwrap. If
    446 // stopAtWindowProxy is true, then this returns the WindowProxy if it was
    447 // previously wrapped.  Null is returned if there are security wrappers that
    448 // can't be unwrapped.
    449 //
    450 // ExposeToActiveJS is called on wrapper targets to allow gray marking
    451 // assertions to work while an incremental GC is in progress, but this means
    452 // that this cannot be called from the GC or off the main thread.
    453 //
    454 // The JSContext argument will be used for dynamic checks (needed by WindowProxy
    455 // and Location) and should represent the Realm doing the unwrapping.  It is not
    456 // used to throw exceptions; this function never throws.
    457 //
    458 // This function may be able to GC (and the static analysis definitely thinks it
    459 // can), but it still takes a JSObject* argument, because some of its callers
    460 // would actually have a bit of a hard time producing a Rooted.  And it ends up
    461 // having to root internally anyway, because it wants to use the value in a loop
    462 // and you can't assign to a HandleObject.  What this means is that callers who
    463 // plan to use the argument object after they have called this function will
    464 // need to root it to avoid hazard failures, even though this function doesn't
    465 // require a Handle.
    466 JS_PUBLIC_API JSObject* CheckedUnwrapDynamic(JSObject* obj, JSContext* cx,
    467                                             bool stopAtWindowProxy = true);
    468 
    469 // Unwrap only the outermost security wrapper, with the same semantics as
    470 // above. This is the checked version of Wrapper::wrappedObject.
    471 JS_PUBLIC_API JSObject* UnwrapOneCheckedDynamic(JS::HandleObject obj,
    472                                                JSContext* cx,
    473                                                bool stopAtWindowProxy = true);
    474 
    475 // Given a JSObject, returns that object stripped of wrappers. This returns the
    476 // WindowProxy if it was previously wrapped.
    477 //
    478 // ExposeToActiveJS is not called on wrapper targets so this can be called from
    479 // the GC or off the main thread.
    480 JS_PUBLIC_API JSObject* UncheckedUnwrapWithoutExpose(JSObject* obj);
    481 
    482 void ReportAccessDenied(JSContext* cx);
    483 
    484 JS_PUBLIC_API void NukeCrossCompartmentWrapper(JSContext* cx,
    485                                               JSObject* wrapper);
    486 
    487 // If a cross-compartment wrapper source => target exists, nuke it.
    488 JS_PUBLIC_API void NukeCrossCompartmentWrapperIfExists(JSContext* cx,
    489                                                       JS::Compartment* source,
    490                                                       JSObject* target);
    491 
    492 void RemapWrapper(JSContext* cx, JSObject* wobj, JSObject* newTarget);
    493 void RemapDeadWrapper(JSContext* cx, JS::HandleObject wobj,
    494                      JS::HandleObject newTarget);
    495 
    496 JS_PUBLIC_API bool RemapAllWrappersForObject(JSContext* cx,
    497                                             JS::HandleObject oldTarget,
    498                                             JS::HandleObject newTarget);
    499 
    500 // API to recompute all cross-compartment wrappers whose source and target
    501 // match the given filters.
    502 JS_PUBLIC_API bool RecomputeWrappers(JSContext* cx,
    503                                     const CompartmentFilter& sourceFilter,
    504                                     const CompartmentFilter& targetFilter);
    505 
    506 } /* namespace js */
    507 
    508 #endif /* js_Wrapper_h */