tor-browser

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

DeadObjectProxy.cpp (4985B)


      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 #include "proxy/DeadObjectProxy.h"
      8 
      9 #include "js/ErrorReport.h"           // JS_ReportErrorNumberASCII
     10 #include "js/friend/ErrorMessages.h"  // js::GetErrorMessage, JSMSG_*
     11 #include "vm/JSFunction.h"            // XXXefaust Bug 1064662
     12 #include "vm/ProxyObject.h"
     13 
     14 #include "vm/JSObject-inl.h"
     15 
     16 using namespace js;
     17 
     18 const DeadObjectProxy DeadObjectProxy::singleton;
     19 const char DeadObjectProxy::family = 0;
     20 
     21 static void ReportDead(JSContext* cx) {
     22  JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_DEAD_OBJECT);
     23 }
     24 
     25 bool DeadObjectProxy::getOwnPropertyDescriptor(
     26    JSContext* cx, HandleObject wrapper, HandleId id,
     27    MutableHandle<mozilla::Maybe<PropertyDescriptor>> desc) const {
     28  ReportDead(cx);
     29  return false;
     30 }
     31 
     32 bool DeadObjectProxy::defineProperty(JSContext* cx, HandleObject wrapper,
     33                                     HandleId id,
     34                                     Handle<PropertyDescriptor> desc,
     35                                     ObjectOpResult& result) const {
     36  ReportDead(cx);
     37  return false;
     38 }
     39 
     40 bool DeadObjectProxy::ownPropertyKeys(JSContext* cx, HandleObject wrapper,
     41                                      MutableHandleIdVector props) const {
     42  ReportDead(cx);
     43  return false;
     44 }
     45 
     46 bool DeadObjectProxy::delete_(JSContext* cx, HandleObject wrapper, HandleId id,
     47                              ObjectOpResult& result) const {
     48  ReportDead(cx);
     49  return false;
     50 }
     51 
     52 bool DeadObjectProxy::getPrototype(JSContext* cx, HandleObject proxy,
     53                                   MutableHandleObject protop) const {
     54  protop.set(nullptr);
     55  return true;
     56 }
     57 
     58 bool DeadObjectProxy::getPrototypeIfOrdinary(JSContext* cx, HandleObject proxy,
     59                                             bool* isOrdinary,
     60                                             MutableHandleObject protop) const {
     61  *isOrdinary = false;
     62  return true;
     63 }
     64 
     65 bool DeadObjectProxy::preventExtensions(JSContext* cx, HandleObject proxy,
     66                                        ObjectOpResult& result) const {
     67  ReportDead(cx);
     68  return false;
     69 }
     70 
     71 bool DeadObjectProxy::isExtensible(JSContext* cx, HandleObject proxy,
     72                                   bool* extensible) const {
     73  // This is kind of meaningless, but dead-object semantics aside,
     74  // [[Extensible]] always being true is consistent with other proxy types.
     75  *extensible = true;
     76  return true;
     77 }
     78 
     79 bool DeadObjectProxy::call(JSContext* cx, HandleObject wrapper,
     80                           const CallArgs& args) const {
     81  ReportDead(cx);
     82  return false;
     83 }
     84 
     85 bool DeadObjectProxy::construct(JSContext* cx, HandleObject wrapper,
     86                                const CallArgs& args) const {
     87  ReportDead(cx);
     88  return false;
     89 }
     90 
     91 bool DeadObjectProxy::nativeCall(JSContext* cx, IsAcceptableThis test,
     92                                 NativeImpl impl, const CallArgs& args) const {
     93  ReportDead(cx);
     94  return false;
     95 }
     96 
     97 bool DeadObjectProxy::getBuiltinClass(JSContext* cx, HandleObject proxy,
     98                                      ESClass* cls) const {
     99  ReportDead(cx);
    100  return false;
    101 }
    102 
    103 bool DeadObjectProxy::isArray(JSContext* cx, HandleObject obj,
    104                              JS::IsArrayAnswer* answer) const {
    105  ReportDead(cx);
    106  return false;
    107 }
    108 
    109 const char* DeadObjectProxy::className(JSContext* cx,
    110                                       HandleObject wrapper) const {
    111  return "DeadObject";
    112 }
    113 
    114 JSString* DeadObjectProxy::fun_toString(JSContext* cx, HandleObject proxy,
    115                                        bool isToSource) const {
    116  ReportDead(cx);
    117  return nullptr;
    118 }
    119 
    120 RegExpShared* DeadObjectProxy::regexp_toShared(JSContext* cx,
    121                                               HandleObject proxy) const {
    122  ReportDead(cx);
    123  return nullptr;
    124 }
    125 
    126 bool js::IsDeadProxyObject(const JSObject* obj) {
    127  return IsDerivedProxyObject(obj, &DeadObjectProxy::singleton);
    128 }
    129 
    130 Value js::DeadProxyTargetValue(JSObject* obj) {
    131  // When nuking scripted proxies, isCallable and isConstructor values for
    132  // the proxy needs to be preserved.  So does background-finalization status.
    133  int32_t flags = 0;
    134  if (obj->isCallable()) {
    135    flags |= DeadObjectProxyIsCallable;
    136  }
    137  if (obj->isConstructor()) {
    138    flags |= DeadObjectProxyIsConstructor;
    139  }
    140  if (obj->isBackgroundFinalized()) {
    141    flags |= DeadObjectProxyIsBackgroundFinalized;
    142  }
    143  return Int32Value(flags);
    144 }
    145 
    146 JSObject* js::NewDeadProxyObject(JSContext* cx, JSObject* origObj) {
    147  RootedValue target(cx);
    148  if (origObj) {
    149    target = DeadProxyTargetValue(origObj);
    150  } else {
    151    target = Int32Value(DeadObjectProxyIsBackgroundFinalized);
    152  }
    153 
    154  return NewProxyObject(cx, &DeadObjectProxy::singleton, target, nullptr,
    155                        ProxyOptions());
    156 }