tor-browser

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

ScriptLoadHandler.h (4508B)


      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 /*
      8 * A class that handles loading and evaluation of <script> elements.
      9 */
     10 
     11 #ifndef mozilla_dom_ScriptLoadHandler_h
     12 #define mozilla_dom_ScriptLoadHandler_h
     13 
     14 #include "mozilla/Encoding.h"
     15 #include "mozilla/RefPtr.h"
     16 #include "mozilla/UniquePtr.h"
     17 #include "nsIChannelEventSink.h"
     18 #include "nsIIncrementalStreamLoader.h"
     19 #include "nsIInterfaceRequestor.h"
     20 #include "nsISupports.h"
     21 
     22 namespace JS::loader {
     23 class ScriptLoadRequest;
     24 }
     25 
     26 namespace mozilla {
     27 
     28 class Decoder;
     29 
     30 namespace dom {
     31 
     32 class ScriptLoader;
     33 class SRICheckDataVerifier;
     34 
     35 class ScriptDecoder {
     36 public:
     37  enum BOMHandling { Ignore, Remove };
     38 
     39  ScriptDecoder(const Encoding* aEncoding,
     40                ScriptDecoder::BOMHandling handleBOM);
     41 
     42  ~ScriptDecoder() = default;
     43 
     44  /*
     45   * Once the charset is found by the EnsureDecoder function, we can
     46   * incrementally convert the charset to the one expected by the JS Parser.
     47   */
     48  nsresult DecodeRawData(JS::loader::ScriptLoadRequest* aRequest,
     49                         const uint8_t* aData, uint32_t aDataLength,
     50                         bool aEndOfStream);
     51 
     52 private:
     53  /*
     54   * Decode the given data into the already-allocated internal
     55   * |ScriptTextBuffer<Unit>|.
     56   *
     57   * This function is intended to be called only by |DecodeRawData| after
     58   * determining which sort of |ScriptTextBuffer<Unit>| has been allocated.
     59   */
     60  template <typename Unit>
     61  nsresult DecodeRawDataHelper(JS::loader::ScriptLoadRequest* aRequest,
     62                               const uint8_t* aData, uint32_t aDataLength,
     63                               bool aEndOfStream);
     64 
     65  // Unicode decoder for charset.
     66  mozilla::UniquePtr<mozilla::Decoder> mDecoder;
     67 };
     68 
     69 class ScriptLoadHandler final : public nsIIncrementalStreamLoaderObserver,
     70                                public nsIChannelEventSink,
     71                                public nsIInterfaceRequestor {
     72 public:
     73  explicit ScriptLoadHandler(
     74      ScriptLoader* aScriptLoader, JS::loader::ScriptLoadRequest* aRequest,
     75      UniquePtr<SRICheckDataVerifier>&& aSRIDataVerifier);
     76 
     77  NS_DECL_ISUPPORTS
     78  NS_DECL_NSIINCREMENTALSTREAMLOADEROBSERVER
     79  NS_DECL_NSICHANNELEVENTSINK
     80  NS_DECL_NSIINTERFACEREQUESTOR
     81 
     82 private:
     83  virtual ~ScriptLoadHandler();
     84 
     85  /*
     86   * Discover the charset by looking at the stream data, the script tag, and
     87   * other indicators.  Returns true if charset has been discovered.
     88   */
     89  bool EnsureDecoder(nsIIncrementalStreamLoader* aLoader, const uint8_t* aData,
     90                     uint32_t aDataLength, bool aEndOfStream) {
     91    // Check if the decoder has already been created.
     92    if (mDecoder) {
     93      return true;
     94    }
     95 
     96    return TrySetDecoder(aLoader, aData, aDataLength, aEndOfStream);
     97  }
     98 
     99  /*
    100   * Attempt to determine how script data will be decoded, when such
    101   * determination hasn't already been made.  (If you don't know whether it's
    102   * been made yet, use |EnsureDecoder| above instead.)  Return false if there
    103   * isn't enough information yet to make the determination, or true if a
    104   * determination was made.
    105   */
    106  bool TrySetDecoder(nsIIncrementalStreamLoader* aLoader, const uint8_t* aData,
    107                     uint32_t aDataLength, bool aEndOfStream);
    108 
    109  /*
    110   * When streaming serialized Stencil, we have the opportunity to fallback
    111   * early if SRI does not match the expectation of the document.
    112   *
    113   * If SRI hash is decoded, `sriLength` is set to the length of the hash.
    114   */
    115  nsresult MaybeDecodeSRI(uint32_t* sriLength);
    116 
    117  // Query the channel to find the data type associated with the input stream.
    118  nsresult EnsureKnownDataType(nsIIncrementalStreamLoader* aLoader);
    119 
    120  // ScriptLoader which will handle the parsed script.
    121  RefPtr<ScriptLoader> mScriptLoader;
    122 
    123  // The ScriptLoadRequest for this load. Decoded data are accumulated on it.
    124  RefPtr<JS::loader::ScriptLoadRequest> mRequest;
    125 
    126  // SRI data verifier.
    127  UniquePtr<SRICheckDataVerifier> mSRIDataVerifier;
    128 
    129  // Status of SRI data operations.
    130  nsresult mSRIStatus;
    131 
    132  UniquePtr<ScriptDecoder> mDecoder;
    133 
    134  // Flipped to true after calling NotifyStart the first time
    135  bool mPreloadStartNotified = false;
    136 };
    137 
    138 }  // namespace dom
    139 }  // namespace mozilla
    140 
    141 #endif  // mozilla_dom_ScriptLoadHandler_h