tor-browser

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

WindowContext.h (20323B)


      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 mozilla_dom_WindowContext_h
      8 #define mozilla_dom_WindowContext_h
      9 
     10 #include "mozilla/PermissionDelegateHandler.h"
     11 #include "mozilla/WeakPtr.h"
     12 #include "mozilla/Span.h"
     13 #include "mozilla/dom/MaybeDiscarded.h"
     14 #include "mozilla/dom/SyncedContext.h"
     15 #include "mozilla/dom/UserActivation.h"
     16 #include "nsDOMNavigationTiming.h"
     17 #include "nsILoadInfo.h"
     18 #include "nsWrapperCache.h"
     19 
     20 class nsIGlobalObject;
     21 
     22 class nsGlobalWindowInner;
     23 
     24 namespace mozilla {
     25 class LogModule;
     26 class nsRFPTargetSetIDL;
     27 
     28 namespace dom {
     29 
     30 class WindowGlobalChild;
     31 class WindowGlobalParent;
     32 class WindowGlobalInit;
     33 class BrowsingContext;
     34 class BrowsingContextGroup;
     35 
     36 #define MOZ_EACH_WC_FIELD(FIELD)                                         \
     37  /* Whether the SHEntry associated with the current top-level           \
     38   * window has already seen user interaction.                           \
     39   * As such, this will be reset to false when a new SHEntry is          \
     40   * created without changing the WC (e.g. when using pushState or       \
     41   * sub-frame navigation)                                               \
     42   * This flag is set for optimization purposes, to avoid                \
     43   * having to get the top SHEntry and update it on every                \
     44   * user interaction.                                                   \
     45   * This is only meaningful on the top-level WC. */                     \
     46  FIELD(SHEntryHasUserInteraction, bool)                                 \
     47  FIELD(CookieBehavior, Maybe<uint32_t>)                                 \
     48  FIELD(IsOnContentBlockingAllowList, bool)                              \
     49  /* Whether the given window hierarchy is third party. See              \
     50   * ThirdPartyUtil::IsThirdPartyWindow for details */                   \
     51  FIELD(IsThirdPartyWindow, bool)                                        \
     52  /* Whether this window's channel has been marked as a third-party      \
     53   * tracking resource */                                                \
     54  FIELD(IsThirdPartyTrackingResourceWindow, bool)                        \
     55  /* Whether this window is using its unpartitioned cookies due to       \
     56   * the Storage Access API */                                           \
     57  FIELD(UsingStorageAccess, bool)                                        \
     58  FIELD(ShouldResistFingerprinting, bool)                                \
     59  FIELD(OverriddenFingerprintingSettings, Maybe<RFPTargetSet>)           \
     60  FIELD(IsSecureContext, bool)                                           \
     61  FIELD(IsOriginalFrameSource, bool)                                     \
     62  /* Mixed-Content: If the corresponding documentURI is https,           \
     63   * then this flag is true. */                                          \
     64  FIELD(IsSecure, bool)                                                  \
     65  /* Whether this window has registered a "beforeunload" event           \
     66   * handler */                                                          \
     67  FIELD(NeedsBeforeUnload, bool)                                         \
     68  /* Whether this window's navigation object has registered any          \
     69   * event handlers or has ongoing or upcoming method trackers. Only     \
     70   * valid for the top-level context. */                                 \
     71  FIELD(NeedsTraverse, bool)                                             \
     72  /* Controls whether the WindowContext is currently considered to be    \
     73   * activated by a gesture */                                           \
     74  FIELD(UserActivationStateAndModifiers,                                 \
     75        UserActivation::StateAndModifiers::DataT)                        \
     76  FIELD(EmbedderPolicy, nsILoadInfo::CrossOriginEmbedderPolicy)          \
     77  /* True if this document tree contained at least a HTMLMediaElement.   \
     78   * This should only be set on top level context. */                    \
     79  FIELD(DocTreeHadMedia, bool)                                           \
     80  FIELD(AutoplayPermission, uint32_t)                                    \
     81  FIELD(ShortcutsPermission, uint32_t)                                   \
     82  /* Store the Id of the browsing context where active media session     \
     83   * exists on the top level window context */                           \
     84  FIELD(ActiveMediaSessionContextId, Maybe<uint64_t>)                    \
     85  /* ALLOW_ACTION if it is allowed to open popups for the sub-tree       \
     86   * starting and including the current WindowContext */                 \
     87  FIELD(PopupPermission, uint32_t)                                       \
     88  FIELD(DelegatedPermissions,                                            \
     89        PermissionDelegateHandler::DelegatedPermissionList)              \
     90  FIELD(DelegatedExactHostMatchPermissions,                              \
     91        PermissionDelegateHandler::DelegatedPermissionList)              \
     92  FIELD(HasReportedShadowDOMUsage, bool)                                 \
     93  /* Whether the principal of this window is for a local                 \
     94   * IP address */                                                       \
     95  FIELD(IsLocalIP, bool)                                                 \
     96  /* Whether any of the windows in the subtree rooted at this window has \
     97   * active peer connections or not (only set on the top window). */     \
     98  FIELD(HasActivePeerConnections, bool)                                  \
     99  /* Whether we can execute scripts in this WindowContext. Has no effect \
    100   * unless scripts are also allowed in the BrowsingContext. */          \
    101  FIELD(AllowJavascript, bool)                                           \
    102  /* If this field is `true`, it means that this WindowContext's         \
    103   * WindowState was saved to be stored in the legacy (non-SHIP) BFCache \
    104   * implementation. Always false for SHIP */                            \
    105  FIELD(WindowStateSaved, bool)                                          \
    106  /* If this field is `true`, it means that this WindowContext's         \
    107   * CloseWatcherManager has active CloseWatchers, which some UIs may    \
    108   * want to dismiss (for example the Android "back button"). */         \
    109  FIELD(HasActiveCloseWatcher, bool)
    110 
    111 class WindowContext : public nsISupports, public nsWrapperCache {
    112  MOZ_DECL_SYNCED_CONTEXT(WindowContext, MOZ_EACH_WC_FIELD)
    113 
    114  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
    115  NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(WindowContext)
    116 
    117 public:
    118  static already_AddRefed<WindowContext> GetById(uint64_t aInnerWindowId);
    119  static LogModule* GetLog();
    120  static LogModule* GetSyncLog();
    121 
    122  BrowsingContext* GetBrowsingContext() const { return mBrowsingContext; }
    123  BrowsingContextGroup* Group() const;
    124  uint64_t Id() const { return InnerWindowId(); }
    125  uint64_t InnerWindowId() const { return mInnerWindowId; }
    126  uint64_t OuterWindowId() const { return mOuterWindowId; }
    127  bool IsDiscarded() const { return mIsDiscarded; }
    128 
    129  // Returns `true` if this WindowContext is the current WindowContext in its
    130  // BrowsingContext.
    131  bool IsCurrent() const;
    132 
    133  // Returns `true` if this WindowContext is currently in the BFCache.
    134  bool IsInBFCache();
    135 
    136  bool IsInProcess() const { return mIsInProcess; }
    137 
    138  bool NeedsBeforeUnload() const { return GetNeedsBeforeUnload(); }
    139 
    140  bool HasBeforeUnload() const { return NeedsBeforeUnload(); }
    141 
    142  bool IsLocalIP() const { return GetIsLocalIP(); }
    143 
    144  bool ShouldResistFingerprinting() const {
    145    return GetShouldResistFingerprinting();
    146  }
    147 
    148  bool UsingStorageAccess() const { return GetUsingStorageAccess(); }
    149 
    150  already_AddRefed<nsIRFPTargetSetIDL>
    151  GetOverriddenFingerprintingSettingsWebIDL() const;
    152 
    153  nsGlobalWindowInner* GetInnerWindow() const;
    154  Document* GetDocument() const;
    155  Document* GetExtantDoc() const;
    156 
    157  WindowGlobalChild* GetWindowGlobalChild() const;
    158 
    159  // Get the parent WindowContext of this WindowContext, taking the BFCache into
    160  // account. This will not cross chrome/content <browser> boundaries.
    161  WindowContext* GetParentWindowContext();
    162  WindowContext* TopWindowContext();
    163 
    164  bool SameOriginWithTop() const;
    165 
    166  bool IsTop() const;
    167 
    168  Span<RefPtr<BrowsingContext>> Children() { return mChildren; }
    169 
    170  // The filtered version of `Children()`, which contains no browsing contexts
    171  // for synthetic documents as created by object loading content.
    172  Span<RefPtr<BrowsingContext>> NonSyntheticChildren() {
    173    return mNonSyntheticChildren;
    174  }
    175 
    176  BrowsingContext* NonSyntheticLightDOMChildAt(uint32_t aIndex);
    177  uint32_t NonSyntheticLightDOMChildrenCount();
    178 
    179  // Cast this object to it's parent-process canonical form.
    180  WindowGlobalParent* Canonical();
    181 
    182  nsIGlobalObject* GetParentObject() const;
    183  JSObject* WrapObject(JSContext* cx,
    184                       JS::Handle<JSObject*> aGivenProto) override;
    185 
    186  void Discard();
    187 
    188  struct IPCInitializer {
    189    uint64_t mInnerWindowId;
    190    uint64_t mOuterWindowId;
    191    uint64_t mBrowsingContextId;
    192 
    193    FieldValues mFields;
    194  };
    195  IPCInitializer GetIPCInitializer();
    196 
    197  static void CreateFromIPC(IPCInitializer&& aInit);
    198 
    199  // Add new security state flags.
    200  // These should be some of the nsIWebProgressListener 'HTTPS_ONLY_MODE' or
    201  // 'MIXED' state flags, and should only be called on the top window context.
    202  void AddSecurityState(uint32_t aStateFlags);
    203 
    204  UserActivation::State GetUserActivationState() const {
    205    return UserActivation::StateAndModifiers(
    206               GetUserActivationStateAndModifiers())
    207        .GetState();
    208  }
    209 
    210  // This function would be called when its corresponding window is activated
    211  // by user gesture.
    212  void NotifyUserGestureActivation(
    213      UserActivation::Modifiers aModifiers = UserActivation::Modifiers::None());
    214 
    215  // This function would be called when we want to reset the user gesture
    216  // activation flag.
    217  void NotifyResetUserGestureActivation();
    218 
    219  // Return true if its corresponding window has been activated by user
    220  // gesture.
    221  bool HasBeenUserGestureActivated();
    222 
    223  // Return true if its corresponding window has transient user gesture
    224  // activation and the transient user gesture activation haven't yet timed
    225  // out.
    226  bool HasValidTransientUserGestureActivation();
    227 
    228  // See `mLastActivationTimestamp`.
    229  const TimeStamp& GetUserGestureStart() const;
    230 
    231  // Return true if the corresponding window has valid transient user gesture
    232  // activation and the transient user gesture activation had been consumed
    233  // successfully.
    234  bool ConsumeTransientUserGestureActivation();
    235 
    236  // Return true if its corresponding window has history activation.
    237  bool HasValidHistoryActivation() const;
    238 
    239  // Consume the history-action user activation.
    240  void ConsumeHistoryActivation();
    241 
    242  // Update the history-action user activation for this window context
    243  void UpdateLastHistoryActivation();
    244 
    245  bool GetTransientUserGestureActivationModifiers(
    246      UserActivation::Modifiers* aModifiers);
    247 
    248  bool CanShowPopup();
    249 
    250  bool AllowJavascript() const { return GetAllowJavascript(); }
    251  bool CanExecuteScripts() const { return mCanExecuteScripts; }
    252 
    253  void TransientSetHasActivePeerConnections();
    254 
    255  bool HasActiveCloseWatcher() const { return GetHasActiveCloseWatcher(); }
    256 
    257  void ProcessCloseRequest();
    258 
    259 protected:
    260  WindowContext(BrowsingContext* aBrowsingContext, uint64_t aInnerWindowId,
    261                uint64_t aOuterWindowId, FieldValues&& aFields);
    262  virtual ~WindowContext();
    263 
    264  virtual void Init();
    265 
    266 private:
    267  friend class BrowsingContext;
    268  friend class WindowGlobalChild;
    269  friend class WindowGlobalActor;
    270 
    271  void AppendChildBrowsingContext(BrowsingContext* aBrowsingContext);
    272  void RemoveChildBrowsingContext(BrowsingContext* aBrowsingContext);
    273 
    274  // Update non-synthetic children based on whether `aBrowsingContext`
    275  // is synthetic or not. Regardless the synthetic of `aBrowsingContext`, it is
    276  // kept in this WindowContext's all children list.
    277  void UpdateChildSynthetic(BrowsingContext* aBrowsingContext,
    278                            bool aIsSynthetic);
    279 
    280  // Send a given `BaseTransaction` object to the correct remote.
    281  void SendCommitTransaction(ContentParent* aParent,
    282                             const BaseTransaction& aTxn, uint64_t aEpoch);
    283  void SendCommitTransaction(ContentChild* aChild, const BaseTransaction& aTxn,
    284                             uint64_t aEpoch);
    285 
    286  bool CheckOnlyOwningProcessCanSet(ContentParent* aSource);
    287 
    288  // Overload `CanSet` to get notifications for a particular field being set.
    289  bool CanSet(FieldIndex<IDX_IsSecure>, const bool& aIsSecure,
    290              ContentParent* aSource);
    291 
    292  bool CanSet(FieldIndex<IDX_NeedsBeforeUnload>, const bool& aHasBeforeUnload,
    293              ContentParent* aSource);
    294 
    295  bool CanSet(FieldIndex<IDX_NeedsTraverse>, const bool& aNeedsTraverse,
    296              ContentParent* aSource);
    297 
    298  bool CanSet(FieldIndex<IDX_CookieBehavior>, const Maybe<uint32_t>& aValue,
    299              ContentParent* aSource);
    300 
    301  bool CanSet(FieldIndex<IDX_IsOnContentBlockingAllowList>, const bool& aValue,
    302              ContentParent* aSource);
    303 
    304  bool CanSet(FieldIndex<IDX_EmbedderPolicy>, const bool& aValue,
    305              ContentParent* aSource) {
    306    return true;
    307  }
    308 
    309  bool CanSet(FieldIndex<IDX_IsThirdPartyWindow>,
    310              const bool& IsThirdPartyWindow, ContentParent* aSource);
    311  bool CanSet(FieldIndex<IDX_IsThirdPartyTrackingResourceWindow>,
    312              const bool& aIsThirdPartyTrackingResourceWindow,
    313              ContentParent* aSource);
    314  bool CanSet(FieldIndex<IDX_UsingStorageAccess>,
    315              const bool& aUsingStorageAccess, ContentParent* aSource);
    316  bool CanSet(FieldIndex<IDX_ShouldResistFingerprinting>,
    317              const bool& aShouldResistFingerprinting, ContentParent* aSource);
    318  bool CanSet(FieldIndex<IDX_OverriddenFingerprintingSettings>,
    319              const Maybe<RFPTargetSet>& aValue, ContentParent* aSource);
    320  bool CanSet(FieldIndex<IDX_IsSecureContext>, const bool& aIsSecureContext,
    321              ContentParent* aSource);
    322  bool CanSet(FieldIndex<IDX_IsOriginalFrameSource>,
    323              const bool& aIsOriginalFrameSource, ContentParent* aSource);
    324  bool CanSet(FieldIndex<IDX_DocTreeHadMedia>, const bool& aValue,
    325              ContentParent* aSource);
    326  bool CanSet(FieldIndex<IDX_AutoplayPermission>, const uint32_t& aValue,
    327              ContentParent* aSource);
    328  bool CanSet(FieldIndex<IDX_ShortcutsPermission>, const uint32_t& aValue,
    329              ContentParent* aSource);
    330  bool CanSet(FieldIndex<IDX_ActiveMediaSessionContextId>,
    331              const Maybe<uint64_t>& aValue, ContentParent* aSource);
    332  bool CanSet(FieldIndex<IDX_PopupPermission>, const uint32_t&,
    333              ContentParent* aSource);
    334  bool CanSet(FieldIndex<IDX_SHEntryHasUserInteraction>,
    335              const bool& aSHEntryHasUserInteraction, ContentParent* aSource) {
    336    return true;
    337  }
    338  bool CanSet(FieldIndex<IDX_DelegatedPermissions>,
    339              const PermissionDelegateHandler::DelegatedPermissionList& aValue,
    340              ContentParent* aSource);
    341  bool CanSet(FieldIndex<IDX_DelegatedExactHostMatchPermissions>,
    342              const PermissionDelegateHandler::DelegatedPermissionList& aValue,
    343              ContentParent* aSource);
    344  bool CanSet(FieldIndex<IDX_UserActivationStateAndModifiers>,
    345              const UserActivation::StateAndModifiers::DataT&
    346                  aUserActivationStateAndModifiers,
    347              ContentParent* aSource) {
    348    return true;
    349  }
    350 
    351  bool CanSet(FieldIndex<IDX_HasReportedShadowDOMUsage>, const bool& aValue,
    352              ContentParent* aSource) {
    353    return true;
    354  }
    355 
    356  bool CanSet(FieldIndex<IDX_IsLocalIP>, const bool& aValue,
    357              ContentParent* aSource);
    358 
    359  bool CanSet(FieldIndex<IDX_AllowJavascript>, bool aValue,
    360              ContentParent* aSource);
    361  void DidSet(FieldIndex<IDX_AllowJavascript>, bool aOldValue);
    362 
    363  bool CanSet(FieldIndex<IDX_HasActivePeerConnections>, bool, ContentParent*);
    364 
    365  void DidSet(FieldIndex<IDX_HasReportedShadowDOMUsage>, bool aOldValue);
    366 
    367  void DidSet(FieldIndex<IDX_SHEntryHasUserInteraction>, bool aOldValue);
    368 
    369  void DidSet(FieldIndex<IDX_HasActivePeerConnections>, bool aOldValue);
    370 
    371  bool CanSet(FieldIndex<IDX_WindowStateSaved>, bool aValue,
    372              ContentParent* aSource);
    373 
    374  bool CanSet(FieldIndex<IDX_HasActiveCloseWatcher>, bool, ContentParent*) {
    375    return true;
    376  }
    377 
    378  // Overload `DidSet` to get notifications for a particular field being set.
    379  //
    380  // You can also overload the variant that gets the old value if you need it.
    381  template <size_t I>
    382  void DidSet(FieldIndex<I>) {}
    383  template <size_t I, typename T>
    384  void DidSet(FieldIndex<I>, T&& aOldValue) {}
    385  void DidSet(FieldIndex<IDX_UserActivationStateAndModifiers>);
    386 
    387  // Recomputes whether we can execute scripts in this WindowContext based on
    388  // the value of AllowJavascript() and whether scripts are allowed in the
    389  // BrowsingContext.
    390  void RecomputeCanExecuteScripts(bool aApplyChanges = true);
    391 
    392  void ClearLightDOMChildren();
    393 
    394  void EnsureLightDOMChildren();
    395 
    396  const uint64_t mInnerWindowId;
    397  const uint64_t mOuterWindowId;
    398  RefPtr<BrowsingContext> mBrowsingContext;
    399  WeakPtr<WindowGlobalChild> mWindowGlobalChild;
    400 
    401  // --- NEVER CHANGE `mChildren` DIRECTLY! ---
    402  // Changes to this list need to be synchronized to the list within our
    403  // `mBrowsingContext`, and should only be performed through the
    404  // `AppendChildBrowsingContext` and `RemoveChildBrowsingContext` methods.
    405  nsTArray<RefPtr<BrowsingContext>> mChildren;
    406 
    407  // --- NEVER CHANGE `mNonSyntheticChildren` DIRECTLY! ---
    408  // Same reason as for mChildren.
    409  // mNonSyntheticChildren contains the same browsing contexts except browsing
    410  // contexts created by the synthetic document for object loading contents
    411  // loading images. This is used to discern browsing contexts created when
    412  // loading images in <object> or <embed> elements, so that they can be hidden
    413  // from named targeting, `Window.frames` etc.
    414  nsTArray<RefPtr<BrowsingContext>> mNonSyntheticChildren;
    415 
    416  // mNonSyntheticLightDOMChildren is otherwise the same as
    417  // mNonSyntheticChildren, but it contains only those BrowsingContexts where
    418  // embedder is in light DOM. The contents of the array are computed lazily and
    419  // cleared if there are changes to mChildren.
    420  Maybe<nsTArray<RefPtr<BrowsingContext>>> mNonSyntheticLightDOMChildren;
    421 
    422  bool mIsDiscarded = false;
    423  bool mIsInProcess = false;
    424 
    425  // Determines if we can execute scripts in this WindowContext. True if
    426  // AllowJavascript() is true and script execution is allowed in the
    427  // BrowsingContext.
    428  bool mCanExecuteScripts = true;
    429 
    430  // https://html.spec.whatwg.org/multipage/interaction.html#last-activation-timestamp
    431  // The start time of user gesture, this is only available if the window
    432  // context is in process.
    433  TimeStamp mLastActivationTimestamp;
    434 
    435  // https://html.spec.whatwg.org/#history-action-activation
    436  // This is set to mLastActivationTimestamp every time ConsumeHistoryActivation
    437  // is called.
    438  TimeStamp mHistoryActivation;
    439 };
    440 
    441 using WindowContextTransaction = WindowContext::BaseTransaction;
    442 using WindowContextInitializer = WindowContext::IPCInitializer;
    443 using MaybeDiscardedWindowContext = MaybeDiscarded<WindowContext>;
    444 
    445 // Don't specialize the `Transaction` object for every translation unit it's
    446 // used in. This should help keep code size down.
    447 extern template class syncedcontext::Transaction<WindowContext>;
    448 
    449 }  // namespace dom
    450 }  // namespace mozilla
    451 
    452 namespace IPC {
    453 template <>
    454 struct ParamTraits<mozilla::dom::MaybeDiscarded<mozilla::dom::WindowContext>> {
    455  using paramType = mozilla::dom::MaybeDiscarded<mozilla::dom::WindowContext>;
    456  static void Write(MessageWriter* aWriter, const paramType& aParam);
    457  static bool Read(MessageReader* aReader, paramType* aResult);
    458 };
    459 
    460 template <>
    461 struct ParamTraits<mozilla::dom::WindowContext::IPCInitializer> {
    462  using paramType = mozilla::dom::WindowContext::IPCInitializer;
    463  static void Write(MessageWriter* aWriter, const paramType& aInitializer);
    464  static bool Read(MessageReader* aReader, paramType* aInitializer);
    465 };
    466 }  // namespace IPC
    467 
    468 #endif  // !defined(mozilla_dom_WindowContext_h)