tor-browser

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

nsIGlobalObject.h (16196B)


      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 nsIGlobalObject_h__
      8 #define nsIGlobalObject_h__
      9 
     10 #include "js/TypeDecls.h"
     11 #include "mozilla/LinkedList.h"
     12 #include "mozilla/Maybe.h"
     13 #include "mozilla/OriginTrials.h"
     14 #include "mozilla/dom/ClientInfo.h"
     15 #include "mozilla/dom/ClientState.h"
     16 #include "mozilla/dom/ServiceWorkerDescriptor.h"
     17 #include "nsContentUtils.h"
     18 #include "nsHashKeys.h"
     19 #include "nsISupports.h"
     20 #include "nsRFPService.h"
     21 #include "nsStringFwd.h"
     22 #include "nsTArray.h"
     23 #include "nsTHashtable.h"
     24 
     25 // Must be kept in sync with xpcom/rust/xpcom/src/interfaces/nonidl.rs
     26 #define NS_IGLOBALOBJECT_IID \
     27  {0x11afa8be, 0xd997, 0x4e07, {0xa6, 0xa3, 0x6f, 0x87, 0x2e, 0xc3, 0xee, 0x7f}}
     28 
     29 class nsCycleCollectionTraversalCallback;
     30 class nsICookieJarSettings;
     31 class nsIPrincipal;
     32 class nsIURI;
     33 class nsPIDOMWindowInner;
     34 
     35 namespace mozilla {
     36 class DOMEventTargetHelper;
     37 class GlobalFreezeObserver;
     38 class GlobalTeardownObserver;
     39 template <typename V, typename E>
     40 class Result;
     41 enum class StorageAccess;
     42 namespace dom {
     43 class WorkerGlobalScopeBase;
     44 class VoidFunction;
     45 class DebuggerNotificationManager;
     46 class FontFaceSet;
     47 class Function;
     48 class Report;
     49 class ReportBody;
     50 class ReportingObserver;
     51 class ServiceWorker;
     52 class ServiceWorkerContainer;
     53 class ServiceWorkerRegistration;
     54 class ServiceWorkerRegistrationDescriptor;
     55 class StorageManager;
     56 class WebTaskSchedulingState;
     57 enum class CallerType : uint32_t;
     58 }  // namespace dom
     59 namespace ipc {
     60 class PrincipalInfo;
     61 }  // namespace ipc
     62 }  // namespace mozilla
     63 
     64 namespace JS::loader {
     65 class ModuleLoaderBase;
     66 }  // namespace JS::loader
     67 
     68 /**
     69 * See <https://developer.mozilla.org/en-US/docs/Glossary/Global_object>.
     70 */
     71 class nsIGlobalObject : public nsISupports {
     72 private:
     73  nsTArray<nsCString> mHostObjectURIs;
     74 
     75  // Raw pointers to bound DETH objects.  These are added by
     76  // AddGlobalTeardownObserver().
     77  mozilla::LinkedList<mozilla::GlobalTeardownObserver> mGlobalTeardownObservers;
     78  // And by AddGlobalFreezeObserver()
     79  mozilla::LinkedList<mozilla::GlobalFreezeObserver> mGlobalFreezeObservers;
     80 
     81  bool mIsDying;
     82 
     83 protected:
     84  bool mIsInnerWindow;
     85 
     86  nsIGlobalObject();
     87 
     88 public:
     89  using RTPCallerType = mozilla::RTPCallerType;
     90  using RFPTarget = mozilla::RFPTarget;
     91  NS_INLINE_DECL_STATIC_IID(NS_IGLOBALOBJECT_IID)
     92 
     93  /**
     94   * This check is added to deal with Promise microtask queues. On the main
     95   * thread, we do not impose restrictions about when script stops running or
     96   * when runnables can no longer be dispatched to the main thread. This means
     97   * it is possible for a Promise chain to keep resolving an infinite chain of
     98   * promises, preventing the browser from shutting down. See Bug 1058695. To
     99   * prevent this, the nsGlobalWindow subclass sets this flag when it is
    100   * closed. The Promise implementation checks this and prohibits new runnables
    101   * from being dispatched.
    102   *
    103   * We pair this with checks during processing the promise microtask queue
    104   * that pops up the slow script dialog when the Promise queue is preventing
    105   * a window from going away.
    106   */
    107  bool IsDying() const { return mIsDying; }
    108 
    109  /**
    110   * Is it currently forbidden to call into script?  JS-implemented WebIDL is
    111   * a special case that's always allowed because it has the system principal,
    112   * and callers should indicate this.
    113   */
    114  bool IsScriptForbidden(JSObject* aCallback,
    115                         bool aIsJSImplementedWebIDL = false) const;
    116 
    117  /**
    118   * Return the JSObject for this global, if it still has one.  Otherwise return
    119   * null.
    120   *
    121   * If non-null is returned, then the returned object will have been already
    122   * exposed to active JS, so callers do not need to do it.
    123   */
    124  virtual JSObject* GetGlobalJSObject() = 0;
    125 
    126  /**
    127   * Return the JSObject for this global _without_ exposing it to active JS.
    128   * This may return a gray object.
    129   *
    130   * This method is appropriate to use in assertions (so there is less of a
    131   * difference in GC/CC marking between debug and optimized builds) and in
    132   * situations where we are sure no CC activity can happen while the return
    133   * value is used and the return value does not end up escaping to the heap in
    134   * any way.  In all other cases, and in particular in cases where the return
    135   * value is held in a JS::Rooted or passed to the JSAutoRealm constructor, use
    136   * GetGlobalJSObject.
    137   */
    138  virtual JSObject* GetGlobalJSObjectPreserveColor() const = 0;
    139 
    140  /**
    141   * Check whether this nsIGlobalObject still has a JSObject associated with it,
    142   * or whether it's torn-down enough that the JSObject is gone.
    143   */
    144  bool HasJSGlobal() const { return GetGlobalJSObjectPreserveColor(); }
    145 
    146  virtual nsISerialEventTarget* SerialEventTarget() const = 0;
    147  virtual nsresult Dispatch(already_AddRefed<nsIRunnable>&&) const = 0;
    148 
    149  // This method is not meant to be overridden.
    150  nsIPrincipal* PrincipalOrNull() const;
    151 
    152  void RegisterHostObjectURI(const nsACString& aURI);
    153 
    154  void UnregisterHostObjectURI(const nsACString& aURI);
    155 
    156  // Any CC class inheriting nsIGlobalObject should call these 2 methods to
    157  // cleanup objects stored in nsIGlobalObject such as blobURLs and Reports.
    158  void UnlinkObjectsInGlobal();
    159  void TraverseObjectsInGlobal(nsCycleCollectionTraversalCallback& aCb);
    160 
    161  // GlobalTeardownObservers must register themselves on the global when they
    162  // bind to it in order to get the DisconnectFromOwner() method
    163  // called correctly.  RemoveGlobalTeardownObserver() must be called
    164  // before the GlobalTeardownObserver is destroyed.
    165  void AddGlobalTeardownObserver(mozilla::GlobalTeardownObserver* aObject);
    166  void RemoveGlobalTeardownObserver(mozilla::GlobalTeardownObserver* aObject);
    167 
    168  // Iterate the registered GlobalTeardownObservers and call the given function
    169  // for each one.
    170  void ForEachGlobalTeardownObserver(
    171      const std::function<void(mozilla::GlobalTeardownObserver*,
    172                               bool* aDoneOut)>& aFunc) const;
    173 
    174  // GlobalFreezeObservers must register themselves on the global too for
    175  // FreezeCallback and optionally ThawCallback.
    176  void AddGlobalFreezeObserver(mozilla::GlobalFreezeObserver* aObserver);
    177  void RemoveGlobalFreezeObserver(mozilla::GlobalFreezeObserver* aObserver);
    178 
    179  // Iterate the registered GlobalFreezeObservers and call the given function
    180  // for each one.
    181  void ForEachGlobalFreezeObserver(
    182      const std::function<void(mozilla::GlobalFreezeObserver*, bool* aDoneOut)>&
    183          aFunc) const;
    184 
    185  virtual bool IsInSyncOperation() { return false; }
    186 
    187  virtual mozilla::dom::DebuggerNotificationManager*
    188  GetOrCreateDebuggerNotificationManager() {
    189    return nullptr;
    190  }
    191 
    192  virtual mozilla::dom::DebuggerNotificationManager*
    193  GetExistingDebuggerNotificationManager() {
    194    return nullptr;
    195  }
    196 
    197  virtual void SetWebTaskSchedulingState(
    198      mozilla::dom::WebTaskSchedulingState* aState) {}
    199  virtual mozilla::dom::WebTaskSchedulingState* GetWebTaskSchedulingState()
    200      const {
    201    return nullptr;
    202  }
    203 
    204  // For globals with a concept of a Base URI (windows, workers), the base URI,
    205  // nullptr otherwise.
    206  virtual nsIURI* GetBaseURI() const;
    207 
    208  virtual mozilla::Maybe<mozilla::dom::ClientInfo> GetClientInfo() const;
    209  virtual mozilla::Maybe<mozilla::dom::ClientState> GetClientState() const;
    210 
    211  virtual mozilla::Maybe<nsID> GetAgentClusterId() const;
    212 
    213  virtual bool CrossOriginIsolated() const { return false; }
    214 
    215  virtual bool IsSharedMemoryAllowed() const { return false; }
    216 
    217  virtual mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor> GetController()
    218      const;
    219 
    220  virtual already_AddRefed<mozilla::dom::ServiceWorkerContainer>
    221  GetServiceWorkerContainer();
    222 
    223  // Get the DOM object for the given descriptor or attempt to create one.
    224  // Creation can still fail and return nullptr during shutdown, etc.
    225  virtual RefPtr<mozilla::dom::ServiceWorker> GetOrCreateServiceWorker(
    226      const mozilla::dom::ServiceWorkerDescriptor& aDescriptor);
    227 
    228  // Get the DOM object for the given descriptor or return nullptr if it does
    229  // not exist.
    230  virtual RefPtr<mozilla::dom::ServiceWorkerRegistration>
    231  GetServiceWorkerRegistration(
    232      const mozilla::dom::ServiceWorkerRegistrationDescriptor& aDescriptor)
    233      const;
    234 
    235  // Get the DOM object for the given descriptor or attempt to create one.
    236  // Creation can still fail and return nullptr during shutdown, etc.
    237  virtual RefPtr<mozilla::dom::ServiceWorkerRegistration>
    238  GetOrCreateServiceWorkerRegistration(
    239      const mozilla::dom::ServiceWorkerRegistrationDescriptor& aDescriptor);
    240 
    241  /**
    242   * Returns the storage access of this global.
    243   *
    244   * If you have a global that needs storage access, you should be overriding
    245   * this method in your subclass of this class!
    246   */
    247  virtual mozilla::StorageAccess GetStorageAccess();
    248 
    249  // For globals with cookie jars (windows, workers), the cookie jar settings;
    250  // will likely be null on other global types.
    251  virtual nsICookieJarSettings* GetCookieJarSettings();
    252 
    253  // Returns the set of active origin trials for this global.
    254  virtual mozilla::OriginTrials Trials() const = 0;
    255 
    256  // Returns a pointer to this object as an inner window if this is one or
    257  // nullptr otherwise.
    258  nsPIDOMWindowInner* GetAsInnerWindow();
    259 
    260  virtual void TriggerUpdateCCFlag() {}
    261 
    262  void QueueMicrotask(mozilla::dom::VoidFunction& aCallback);
    263 
    264  void RegisterReportingObserver(mozilla::dom::ReportingObserver* aObserver,
    265                                 bool aBuffered);
    266 
    267  void UnregisterReportingObserver(mozilla::dom::ReportingObserver* aObserver);
    268 
    269  void BroadcastReport(mozilla::dom::Report* aReport);
    270 
    271  MOZ_CAN_RUN_SCRIPT void NotifyReportingObservers();
    272 
    273  void RemoveReportRecords();
    274 
    275  // https://streams.spec.whatwg.org/#count-queuing-strategy-size-function
    276  // This function is set once by CountQueuingStrategy::GetSize.
    277  already_AddRefed<mozilla::dom::Function>
    278  GetCountQueuingStrategySizeFunction();
    279  void SetCountQueuingStrategySizeFunction(mozilla::dom::Function* aFunction);
    280 
    281  already_AddRefed<mozilla::dom::Function>
    282  GetByteLengthQueuingStrategySizeFunction();
    283  void SetByteLengthQueuingStrategySizeFunction(
    284      mozilla::dom::Function* aFunction);
    285 
    286  /**
    287   * Check whether we should avoid leaking distinguishing information to JS/CSS.
    288   * https://w3c.github.io/fingerprinting-guidance/
    289   */
    290  virtual bool ShouldResistFingerprinting(RFPTarget aTarget) const = 0;
    291 
    292  // CallerType::System callers never have to resist fingerprinting.
    293  bool ShouldResistFingerprinting(mozilla::dom::CallerType aCallerType,
    294                                  RFPTarget aTarget) const;
    295 
    296  RTPCallerType GetRTPCallerType() const;
    297 
    298  bool IsRFPTargetActive(const nsAString& aTargetName,
    299                         mozilla::ErrorResult& aRv);
    300 
    301  /**
    302   * Get the module loader to use for this global, if any. By default this
    303   * returns null.
    304   */
    305  virtual JS::loader::ModuleLoaderBase* GetModuleLoader(JSContext* aCx) {
    306    return nullptr;
    307  }
    308 
    309  virtual mozilla::dom::FontFaceSet* GetFonts() { return nullptr; }
    310 
    311  virtual mozilla::Result<mozilla::ipc::PrincipalInfo, nsresult>
    312  GetStorageKey();
    313  mozilla::Result<bool, nsresult> HasEqualStorageKey(
    314      const mozilla::ipc::PrincipalInfo& aStorageKey);
    315 
    316  virtual mozilla::dom::StorageManager* GetStorageManager() { return nullptr; }
    317 
    318  /**
    319   * https://html.spec.whatwg.org/multipage/web-messaging.html#eligible-for-messaging
    320   * * a Window object whose associated Document is fully active, or
    321   * * a WorkerGlobalScope object whose closing flag is false and whose worker
    322   *   is not a suspendable worker.
    323   */
    324  virtual bool IsEligibleForMessaging() { return false; };
    325  virtual bool IsBackgroundInternal() const { return false; }
    326  virtual mozilla::dom::TimeoutManager* GetTimeoutManager() { return nullptr; }
    327  virtual bool IsRunningTimeout() { return false; }
    328  virtual bool IsPlayingAudio() { return false; }
    329  // Determine if the window is suspended or frozen.  Outer windows
    330  // will forward this call to the inner window for convenience.  If
    331  // there is no inner window then the outer window is considered
    332  // suspended and frozen by default.
    333  virtual bool IsSuspended() const { return false; }
    334  virtual bool IsFrozen() const { return false; }
    335  MOZ_CAN_RUN_SCRIPT
    336  virtual bool RunTimeoutHandler(mozilla::dom::Timeout* aTimeout) {
    337    return false;
    338  }
    339  // Return true if there is any active IndexedDB databases which could block
    340  // timeout-throttling.
    341  virtual bool HasActiveIndexedDBDatabases() const { return false; }
    342  /**
    343   * Check whether the active peer connection count is non-zero.
    344   */
    345  virtual bool HasActivePeerConnections() { return false; }
    346  // Return true if there are any open WebSockets that could block
    347  // timeout-throttling.
    348  virtual bool HasOpenWebSockets() const { return false; }
    349 
    350  virtual bool IsXPCSandbox() { return false; }
    351 
    352  virtual bool HasScheduledNormalOrHighPriorityWebTasks() const {
    353    return false;
    354  }
    355 
    356  virtual void UpdateWebSocketCount(int32_t aDelta) {};
    357  // Increase/Decrease the number of active IndexedDB databases for the
    358  // decision making of timeout-throttling.
    359  virtual void UpdateActiveIndexedDBDatabaseCount(int32_t aDelta) {}
    360 
    361  /**
    362   * Report a localized error message to the error console.  Currently this
    363   * amounts to a wrapper around nsContentUtils::ReportToConsole for window
    364   * globals and a runnable bounced to the main thread to call
    365   * nsContentUtils::ReportToConsole for workers but the intent is to migrate
    366   * towards logging the messages to the `dom::Console` for the global.  See
    367   * bug 1900706 for more context.
    368   *
    369   * This method returns void because there is no reasonable action for a caller
    370   * for dynamic failure and we can assert on things like erroneous message
    371   * names.
    372   *
    373   *   @param aErrorFlags See nsIScriptError.
    374   *   @param aCategory Name of module reporting error.
    375   *   @param aFile Properties file containing localized message.
    376   *   @param aMessageName Name of localized message.
    377   *   @param [aParams=empty-array] (Optional) Parameters to be substituted into
    378   *          localized message.
    379   *   @param [aURI=nullptr] (Optional) URI of resource containing error; if
    380   *          omitted, an attempt will be made to use the URI associated with
    381   *          the global (ex: the document URI).
    382   *   @param [aSourceLine=u""_ns] (Optional) The text of the line that
    383   *          contains the error (may be empty).
    384   *   @param [aLineNumber=0] (Optional) Line number within resource
    385   *          containing error.
    386   *   @param [aColumnNumber=0] (Optional) Column number within resource
    387   *          containing error.
    388   */
    389  virtual void ReportToConsole(
    390      uint32_t aErrorFlags, const nsCString& aCategory,
    391      nsContentUtils::PropertiesFile aFile, const nsCString& aMessageName,
    392      const nsTArray<nsString>& aParams = nsTArray<nsString>(),
    393      const mozilla::SourceLocation& aLocation =
    394          mozilla::JSCallingLocation::Get());
    395 
    396 protected:
    397  virtual ~nsIGlobalObject();
    398 
    399  void StartDying() { mIsDying = true; }
    400 
    401  void DisconnectGlobalTeardownObservers();
    402  void DisconnectGlobalFreezeObservers();
    403  void NotifyGlobalFrozen();
    404  void NotifyGlobalThawed();
    405 
    406  size_t ShallowSizeOfExcludingThis(mozilla::MallocSizeOf aSizeOf) const;
    407 
    408 private:
    409  void ClearReports();
    410 
    411 private:
    412  // List of Report objects for ReportingObservers.
    413  nsTArray<RefPtr<mozilla::dom::ReportingObserver>> mReportingObservers;
    414  // https://w3c.github.io/reporting/#windoworworkerglobalscope-report-buffer
    415  nsTArray<RefPtr<mozilla::dom::Report>> mReportBuffer;
    416  nsTHashMap<nsString, uint32_t> mReportPerTypeCount;
    417 
    418  // https://streams.spec.whatwg.org/#count-queuing-strategy-size-function
    419  RefPtr<mozilla::dom::Function> mCountQueuingStrategySizeFunction;
    420 
    421  // https://streams.spec.whatwg.org/#byte-length-queuing-strategy-size-function
    422  RefPtr<mozilla::dom::Function> mByteLengthQueuingStrategySizeFunction;
    423 };
    424 
    425 #endif  // nsIGlobalObject_h__