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