Bug 1444956 - Support BinAST decoding in the script loader r=baku
This commit is contained in:
@@ -9,6 +9,9 @@
|
||||
#include "ScriptTrace.h"
|
||||
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIEncodedChannel.h"
|
||||
#include "nsIStringEnumerator.h"
|
||||
#include "nsMimeTypes.h"
|
||||
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
||||
@@ -59,7 +62,7 @@ ScriptLoadHandler::OnIncrementalData(nsIIncrementalStreamLoader* aLoader,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
if (mRequest->IsSource()) {
|
||||
if (mRequest->IsTextSource()) {
|
||||
if (!EnsureDecoder(aLoader, aData, aDataLength,
|
||||
/* aEndOfStream = */ false)) {
|
||||
return NS_OK;
|
||||
@@ -72,6 +75,18 @@ ScriptLoadHandler::OnIncrementalData(nsIIncrementalStreamLoader* aLoader,
|
||||
rv = DecodeRawData(aData, aDataLength, /* aEndOfStream = */ false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// If SRI is required for this load, appending new bytes to the hash.
|
||||
if (mSRIDataVerifier && NS_SUCCEEDED(mSRIStatus)) {
|
||||
mSRIStatus = mSRIDataVerifier->Update(aDataLength, aData);
|
||||
}
|
||||
} else if (mRequest->IsBinASTSource()) {
|
||||
if (!mRequest->ScriptBinASTData().append(aData, aDataLength)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// Below we will/shall consume entire data chunk.
|
||||
*aConsumedLength = aDataLength;
|
||||
|
||||
// If SRI is required for this load, appending new bytes to the hash.
|
||||
if (mSRIDataVerifier && NS_SUCCEEDED(mSRIStatus)) {
|
||||
mSRIStatus = mSRIDataVerifier->Update(aDataLength, aData);
|
||||
@@ -104,12 +119,12 @@ ScriptLoadHandler::DecodeRawData(const uint8_t* aData,
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
uint32_t haveRead = mRequest->mScriptText.length();
|
||||
uint32_t haveRead = mRequest->ScriptText().length();
|
||||
|
||||
CheckedInt<uint32_t> capacity = haveRead;
|
||||
capacity += needed.value();
|
||||
|
||||
if (!capacity.isValid() || !mRequest->mScriptText.reserve(capacity.value())) {
|
||||
if (!capacity.isValid() || !mRequest->ScriptText().reserve(capacity.value())) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
@@ -119,7 +134,7 @@ ScriptLoadHandler::DecodeRawData(const uint8_t* aData,
|
||||
bool hadErrors;
|
||||
Tie(result, read, written, hadErrors) = mDecoder->DecodeToUTF16(
|
||||
MakeSpan(aData, aDataLength),
|
||||
MakeSpan(mRequest->mScriptText.begin() + haveRead, needed.value()),
|
||||
MakeSpan(mRequest->ScriptText().begin() + haveRead, needed.value()),
|
||||
aEndOfStream);
|
||||
MOZ_ASSERT(result == kInputEmpty);
|
||||
MOZ_ASSERT(read == aDataLength);
|
||||
@@ -128,7 +143,7 @@ ScriptLoadHandler::DecodeRawData(const uint8_t* aData,
|
||||
|
||||
haveRead += written;
|
||||
MOZ_ASSERT(haveRead <= capacity.value(), "mDecoder produced more data than expected");
|
||||
MOZ_ALWAYS_TRUE(mRequest->mScriptText.resizeUninitialized(haveRead));
|
||||
MOZ_ALWAYS_TRUE(mRequest->ScriptText().resizeUninitialized(haveRead));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -273,33 +288,52 @@ ScriptLoadHandler::EnsureKnownDataType(nsIIncrementalStreamLoader* aLoader)
|
||||
{
|
||||
MOZ_ASSERT(mRequest->IsUnknownDataType());
|
||||
MOZ_ASSERT(mRequest->IsLoading());
|
||||
if (mRequest->IsLoadingSource()) {
|
||||
mRequest->mDataType = ScriptLoadRequest::DataType::eSource;
|
||||
TRACE_FOR_TEST(mRequest->mElement, "scriptloader_load_source");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRequest> req;
|
||||
nsresult rv = aLoader->GetRequest(getter_AddRefs(req));
|
||||
MOZ_ASSERT(req, "StreamLoader's request went away prematurely");
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (ScriptLoader::BinASTEncodingEnabled()) {
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(req);
|
||||
if (httpChannel) {
|
||||
nsAutoCString mimeType;
|
||||
httpChannel->GetContentType(mimeType);
|
||||
if (mimeType.LowerCaseEqualsASCII(APPLICATION_JAVASCRIPT_BINAST)) {
|
||||
if (mRequest->ShouldAcceptBinASTEncoding()) {
|
||||
mRequest->SetBinASTSource();
|
||||
TRACE_FOR_TEST(mRequest->mElement, "scriptloader_load_source");
|
||||
return NS_OK;
|
||||
} else {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mRequest->IsLoadingSource()) {
|
||||
mRequest->SetTextSource();
|
||||
TRACE_FOR_TEST(mRequest->mElement, "scriptloader_load_source");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsICacheInfoChannel> cic(do_QueryInterface(req));
|
||||
if (cic) {
|
||||
nsAutoCString altDataType;
|
||||
cic->GetAlternativeDataType(altDataType);
|
||||
if (altDataType.Equals(nsContentUtils::JSBytecodeMimeType())) {
|
||||
mRequest->mDataType = ScriptLoadRequest::DataType::eBytecode;
|
||||
mRequest->SetBytecode();
|
||||
TRACE_FOR_TEST(mRequest->mElement, "scriptloader_load_bytecode");
|
||||
} else {
|
||||
MOZ_ASSERT(altDataType.IsEmpty());
|
||||
mRequest->mDataType = ScriptLoadRequest::DataType::eSource;
|
||||
mRequest->SetTextSource();
|
||||
TRACE_FOR_TEST(mRequest->mElement, "scriptloader_load_source");
|
||||
}
|
||||
} else {
|
||||
mRequest->mDataType = ScriptLoadRequest::DataType::eSource;
|
||||
mRequest->SetTextSource();
|
||||
TRACE_FOR_TEST(mRequest->mElement, "scriptloader_load_source");
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!mRequest->IsUnknownDataType());
|
||||
MOZ_ASSERT(mRequest->IsLoading());
|
||||
return NS_OK;
|
||||
@@ -329,7 +363,7 @@ ScriptLoadHandler::OnStreamComplete(nsIIncrementalStreamLoader* aLoader,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
if (mRequest->IsSource()) {
|
||||
if (mRequest->IsTextSource()) {
|
||||
DebugOnly<bool> encoderSet =
|
||||
EnsureDecoder(aLoader, aData, aDataLength, /* aEndOfStream = */ true);
|
||||
MOZ_ASSERT(encoderSet);
|
||||
@@ -337,7 +371,16 @@ ScriptLoadHandler::OnStreamComplete(nsIIncrementalStreamLoader* aLoader,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
LOG(("ScriptLoadRequest (%p): Source length = %u",
|
||||
mRequest.get(), unsigned(mRequest->mScriptText.length())));
|
||||
mRequest.get(), unsigned(mRequest->ScriptText().length())));
|
||||
|
||||
// If SRI is required for this load, appending new bytes to the hash.
|
||||
if (mSRIDataVerifier && NS_SUCCEEDED(mSRIStatus)) {
|
||||
mSRIStatus = mSRIDataVerifier->Update(aDataLength, aData);
|
||||
}
|
||||
} else if (mRequest->IsBinASTSource()) {
|
||||
if (!mRequest->ScriptBinASTData().append(aData, aDataLength)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// If SRI is required for this load, appending new bytes to the hash.
|
||||
if (mSRIDataVerifier && NS_SUCCEEDED(mSRIStatus)) {
|
||||
|
||||
Reference in New Issue
Block a user