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