tor-browser

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

nsHtml5TreeOpExecutor.h (9132B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #ifndef nsHtml5TreeOpExecutor_h
      6 #define nsHtml5TreeOpExecutor_h
      7 
      8 #include "nsAtom.h"
      9 #include "nsTraceRefcnt.h"
     10 #include "nsHtml5TreeOperation.h"
     11 #include "nsHtml5SpeculativeLoad.h"
     12 #include "nsTArray.h"
     13 #include "nsContentSink.h"
     14 #include "nsNodeInfoManager.h"
     15 #include "nsHtml5DocumentMode.h"
     16 #include "nsIScriptElement.h"
     17 #include "nsIParser.h"
     18 #include "nsAHtml5TreeOpSink.h"
     19 #include "nsHtml5TreeOpStage.h"
     20 #include "nsIURI.h"
     21 #include "nsTHashSet.h"
     22 #include "nsHashKeys.h"
     23 #include "mozilla/LinkedList.h"
     24 #include "nsHtml5DocumentBuilder.h"
     25 #include "nsCharsetSource.h"
     26 
     27 class nsHtml5Parser;
     28 class nsHtml5StreamParser;
     29 class nsIContent;
     30 namespace mozilla {
     31 namespace dom {
     32 class Document;
     33 }
     34 }  // namespace mozilla
     35 
     36 class nsHtml5TreeOpExecutor final
     37    : public nsHtml5DocumentBuilder,
     38      public nsIContentSink,
     39      public nsAHtml5TreeOpSink,
     40      public mozilla::LinkedListElement<nsHtml5TreeOpExecutor> {
     41  friend class nsHtml5FlushLoopGuard;
     42  typedef mozilla::dom::ReferrerPolicy ReferrerPolicy;
     43  using Encoding = mozilla::Encoding;
     44  template <typename T>
     45  using NotNull = mozilla::NotNull<T>;
     46 
     47 public:
     48  NS_DECL_ISUPPORTS_INHERITED
     49 
     50 private:
     51 #ifdef DEBUG
     52  static uint32_t sAppendBatchMaxSize;
     53  static uint32_t sAppendBatchSlotsExamined;
     54  static uint32_t sAppendBatchExaminations;
     55  static uint32_t sLongestTimeOffTheEventLoop;
     56  static uint32_t sTimesFlushLoopInterrupted;
     57 #endif
     58 
     59  /**
     60   * Whether EOF needs to be suppressed
     61   */
     62  bool mSuppressEOF;
     63 
     64  bool mReadingFromStage;
     65  nsTArray<nsHtml5TreeOperation> mOpQueue;
     66  nsHtml5StreamParser* mStreamParser;
     67 
     68  /**
     69   * URLs already preloaded/preloading.
     70   */
     71  nsTHashSet<nsCString> mPreloadedURLs;
     72 
     73  nsCOMPtr<nsIURI> mSpeculationBaseURI;
     74 
     75  nsCOMPtr<nsIURI> mViewSourceBaseURI;
     76 
     77  /**
     78   * Whether the parser has started
     79   */
     80  bool mStarted;
     81 
     82  nsHtml5TreeOpStage mStage;
     83 
     84  bool mRunFlushLoopOnStack;
     85 
     86  bool mCallContinueInterruptedParsingIfEnabled;
     87 
     88  /**
     89   * Whether this executor has already complained about matters related
     90   * to character encoding declarations.
     91   */
     92  bool mAlreadyComplainedAboutCharset;
     93 
     94  /**
     95   * Whether this executor has already complained about the tree being too
     96   * deep.
     97   */
     98  bool mAlreadyComplainedAboutDeepTree;
     99 
    100 public:
    101  nsHtml5TreeOpExecutor();
    102 
    103 protected:
    104  virtual ~nsHtml5TreeOpExecutor();
    105 
    106 public:
    107  // nsIContentSink
    108 
    109  /**
    110   * Unimplemented. For interface compat only.
    111   */
    112  NS_IMETHOD WillParse() override;
    113 
    114  NS_IMETHOD WillBuildModel() override;
    115 
    116  /**
    117   * Emits EOF.
    118   */
    119  NS_IMETHOD DidBuildModel(bool aTerminated) override;
    120 
    121  /**
    122   * Forwards to nsContentSink
    123   */
    124  NS_IMETHOD WillInterrupt() override;
    125 
    126  /**
    127   * Unimplemented. For interface compat only.
    128   */
    129  void WillResume() override;
    130 
    131  virtual nsIContentSink* AsExecutor() override { return this; }
    132 
    133  virtual void InitialTranslationCompleted() override;
    134 
    135  /**
    136   * Sets the parser.
    137   */
    138  NS_IMETHOD SetParser(nsParserBase* aParser) override;
    139 
    140  /**
    141   * No-op for backwards compat.
    142   */
    143  virtual void FlushPendingNotifications(mozilla::FlushType aType) override;
    144 
    145  /**
    146   * Don't call. For interface compat only.
    147   */
    148  virtual void SetDocumentCharset(NotNull<const Encoding*> aEncoding) override {
    149    MOZ_ASSERT_UNREACHABLE("No one should call this.");
    150  }
    151 
    152  /**
    153   * Returns the document.
    154   */
    155  virtual nsISupports* GetTarget() override;
    156 
    157  virtual void ContinueInterruptedParsingAsync() override;
    158 
    159  bool IsScriptExecuting() override { return IsScriptExecutingImpl(); }
    160 
    161  void ContinueParsingDocumentAfterCurrentScript() override {
    162    ContinueParsingDocumentAfterCurrentScriptImpl();
    163  }
    164 
    165  // Not from interface
    166 
    167  void SetStreamParser(nsHtml5StreamParser* aStreamParser) {
    168    mStreamParser = aStreamParser;
    169  }
    170 
    171  void InitializeDocWriteParserState(nsAHtml5TreeBuilderState* aState,
    172                                     int32_t aLine);
    173 
    174  bool IsScriptEnabled();
    175 
    176  virtual nsresult MarkAsBroken(nsresult aReason) override;
    177 
    178  void StartLayout(bool* aInterrupted);
    179 
    180  void PauseDocUpdate(bool* aInterrupted);
    181 
    182  void FlushSpeculativeLoads();
    183 
    184  void RunFlushLoop();
    185 
    186  nsresult FlushDocumentWrite();
    187 
    188  void CommitToInternalEncoding();
    189 
    190  [[nodiscard]] bool TakeOpsFromStage();
    191 
    192  void MaybeSuspend();
    193 
    194  void Start();
    195 
    196  void SetDocumentCharsetAndSource(NotNull<const Encoding*> aEncoding,
    197                                   nsCharsetSource aCharsetSource);
    198 
    199  void UpdateCharsetSource(nsCharsetSource aCharsetSource);
    200 
    201  void NeedsCharsetSwitchTo(NotNull<const Encoding*> aEncoding, int32_t aSource,
    202                            uint32_t aLineNumber);
    203 
    204  void MaybeComplainAboutCharset(const char* aMsgId, bool aError,
    205                                 uint32_t aLineNumber);
    206 
    207  void ComplainAboutBogusProtocolCharset(mozilla::dom::Document* aDoc,
    208                                         bool aUnrecognized);
    209 
    210  void MaybeComplainAboutDeepTree(uint32_t aLineNumber);
    211 
    212  bool HasStarted() { return mStarted; }
    213 
    214  bool IsFlushing() { return mFlushState >= eInFlush; }
    215 
    216 #ifdef DEBUG
    217  bool IsInFlushLoop() { return mRunFlushLoopOnStack; }
    218 #endif
    219 
    220  void RunScript(nsIContent* aScriptElement, bool aMayDocumentWriteOrBlock);
    221 
    222  /**
    223   * Flush the operations from the tree operations from the argument
    224   * queue unconditionally. (This is for the main thread case.)
    225   */
    226  [[nodiscard]] virtual bool MoveOpsFrom(
    227      nsTArray<nsHtml5TreeOperation>& aOpQueue) override;
    228 
    229  void ClearOpQueue();
    230 
    231  void RemoveFromStartOfOpQueue(size_t aNumberOfOpsToRemove);
    232 
    233  inline size_t OpQueueLength() { return mOpQueue.Length(); }
    234 
    235  nsHtml5TreeOpStage* GetStage() { return &mStage; }
    236 
    237  void StartReadingFromStage() { mReadingFromStage = true; }
    238 
    239  void StreamEnded();
    240 
    241 #ifdef DEBUG
    242  void AssertStageEmpty() { mStage.AssertEmpty(); }
    243 #endif
    244 
    245  nsIURI* GetViewSourceBaseURI();
    246 
    247  void PreloadScript(const nsAString& aURL, const nsAString& aCharset,
    248                     const nsAString& aType, const nsAString& aCrossOrigin,
    249                     const nsAString& aMedia, const nsAString& aNonce,
    250                     const nsAString& aFetchPriority,
    251                     const nsAString& aIntegrity,
    252                     ReferrerPolicy aReferrerPolicy, bool aScriptFromHead,
    253                     bool aAsync, bool aDefer, bool aLinkPreload);
    254 
    255  void PreloadStyle(const nsAString& aURL, const nsAString& aCharset,
    256                    const nsAString& aCrossOrigin, const nsAString& aMedia,
    257                    const nsAString& aReferrerPolicy, const nsAString& aNonce,
    258                    const nsAString& aIntegrity, bool aLinkPreload,
    259                    const nsAString& aFetchPriority);
    260 
    261  void PreloadImage(const nsAString& aURL, const nsAString& aCrossOrigin,
    262                    const nsAString& aMedia, const nsAString& aSrcset,
    263                    const nsAString& aSizes,
    264                    const nsAString& aImageReferrerPolicy, bool aLinkPreload,
    265                    const nsAString& aFetchPriority, const nsAString& aType);
    266 
    267  void PreloadOpenPicture();
    268 
    269  void PreloadEndPicture();
    270 
    271  void PreloadPictureSource(const nsAString& aSrcset, const nsAString& aSizes,
    272                            const nsAString& aType, const nsAString& aMedia);
    273 
    274  void PreloadFont(const nsAString& aURL, const nsAString& aCrossOrigin,
    275                   const nsAString& aMedia, const nsAString& aReferrerPolicy,
    276                   const nsAString& aFetchPriority);
    277 
    278  void PreloadFetch(const nsAString& aURL, const nsAString& aCrossOrigin,
    279                    const nsAString& aMedia, const nsAString& aReferrerPolicy,
    280                    const nsAString& aFetchPriority);
    281 
    282  void SetSpeculationBase(const nsAString& aURL);
    283 
    284  void UpdateReferrerInfoFromMeta(const nsAString& aMetaReferrer);
    285 
    286  void AddSpeculationCSP(const nsAString& aCSP);
    287 
    288  void AddBase(const nsAString& aURL);
    289 
    290 private:
    291  nsHtml5Parser* GetParser();
    292 
    293  bool IsExternalViewSource();
    294 
    295  /**
    296   * Get a nsIURI for an nsString if the URL hasn't been preloaded yet.
    297   */
    298  already_AddRefed<nsIURI> ConvertIfNotPreloadedYet(const nsAString& aURL);
    299 
    300  /**
    301   * The above, plus also checks that the media attribute applies.
    302   */
    303  already_AddRefed<nsIURI> ConvertIfNotPreloadedYetAndMediaApplies(
    304      const nsAString& aURL, const nsAString& aMedia);
    305 
    306  /** Returns whether the given media attribute applies to mDocument */
    307  bool MediaApplies(const nsAString& aMedia);
    308 
    309  /**
    310   * The base URI we would use for current preload operations
    311   */
    312  nsIURI* BaseURIForPreload();
    313 
    314  /**
    315   * Returns true if we haven't preloaded this URI yet, and adds it to the
    316   * list of preloaded URIs
    317   */
    318  bool ShouldPreloadURI(nsIURI* aURI);
    319 
    320  /**
    321   * Returns true if the image type is supported.
    322   */
    323  bool ImageTypeSupports(const nsAString& aType);
    324 
    325  ReferrerPolicy GetPreloadReferrerPolicy(const nsAString& aReferrerPolicy);
    326 
    327  ReferrerPolicy GetPreloadReferrerPolicy(ReferrerPolicy aReferrerPolicy);
    328 };
    329 
    330 #endif  // nsHtml5TreeOpExecutor_h