mirror of
https://github.com/HeyPuter/firefox.git
synced 2026-11-13 20:14:57 -10:00
This is a preparation for the later patches. ScriptFetchOptions and URI fields are duplicated between ScriptLoadRequest and LoadedScript, and this patch stack is going to remove them from ScriptLoadRequest. At the point of ScriptLoader::TryUseCache, LoadedScript is not yet created, and ScriptHashKey needs to receive ScriptFetchOptions and URI in addition to ScriptLoadRequest. In order to avoid misuse, ScriptHashKey constructor is split into two variants. One receives ScriptLoadRequest+ScriptFetchOptions+nsIURI, which is for the case LoadedScript is not yet created, and the other receives ScriptLoadRequest+LoadedScript, which is for the case LoadedScript is already created. Differential Revision: https://phabricator.services.mozilla.com/D267349
169 lines
5.9 KiB
C++
169 lines
5.9 KiB
C++
/* -*- 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/. */
|
|
|
|
#include "SharedScriptCache.h"
|
|
|
|
#include "ScriptLoadHandler.h" // ScriptLoadHandler
|
|
#include "ScriptLoader.h" // ScriptLoader
|
|
#include "mozilla/Maybe.h" // Maybe, Some, Nothing
|
|
#include "mozilla/dom/ContentParent.h" // dom::ContentParent
|
|
#include "nsIMemoryReporter.h" // nsIMemoryReporter, MOZ_DEFINE_MALLOC_SIZE_OF, RegisterWeakMemoryReporter, UnregisterWeakMemoryReporter, MOZ_COLLECT_REPORT, KIND_HEAP, UNITS_BYTES
|
|
#include "nsIPrefBranch.h" // nsIPrefBranch, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID
|
|
#include "nsIPrefService.h" // NS_PREFSERVICE_CONTRACTID
|
|
#include "nsIPrincipal.h" // nsIPrincipal
|
|
#include "nsISupportsImpl.h" // NS_IMPL_ISUPPORTS
|
|
#include "nsStringFwd.h" // nsACString
|
|
|
|
namespace mozilla::dom {
|
|
|
|
ScriptHashKey::ScriptHashKey(
|
|
ScriptLoader* aLoader, const JS::loader::ScriptLoadRequest* aRequest,
|
|
const JS::loader::ScriptFetchOptions* aFetchOptions,
|
|
const nsCOMPtr<nsIURI> aURI)
|
|
: PLDHashEntryHdr(),
|
|
mURI(aURI),
|
|
mLoaderPrincipal(aLoader->LoaderPrincipal()),
|
|
mPartitionPrincipal(aLoader->PartitionedPrincipal()),
|
|
mCORSMode(aFetchOptions->mCORSMode),
|
|
mSRIMetadata(aRequest->mIntegrity),
|
|
mKind(aRequest->mKind),
|
|
mNonce(aFetchOptions->mNonce),
|
|
mIsLinkRelPreload(aRequest->GetScriptLoadContext()->IsPreload()) {
|
|
if (mKind == JS::loader::ScriptKind::eClassic) {
|
|
if (aRequest->GetScriptLoadContext()->HasScriptElement()) {
|
|
aRequest->GetScriptLoadContext()->GetHintCharset(mHintCharset);
|
|
}
|
|
}
|
|
|
|
MOZ_COUNT_CTOR(ScriptHashKey);
|
|
}
|
|
|
|
ScriptHashKey::ScriptHashKey(ScriptLoader* aLoader,
|
|
const JS::loader::ScriptLoadRequest* aRequest,
|
|
const JS::loader::LoadedScript* aLoadedScript)
|
|
: ScriptHashKey(aLoader, aRequest, aRequest->mFetchOptions,
|
|
aRequest->mURI) {}
|
|
|
|
ScriptHashKey::ScriptHashKey(const ScriptLoadData& aLoadData)
|
|
: ScriptHashKey(aLoadData.CacheKey()) {}
|
|
|
|
bool ScriptHashKey::KeyEquals(const ScriptHashKey& aKey) const {
|
|
if (mKind != aKey.mKind) {
|
|
return false;
|
|
}
|
|
|
|
{
|
|
bool eq;
|
|
if (NS_FAILED(mURI->Equals(aKey.mURI, &eq)) || !eq) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (!mPartitionPrincipal->Equals(aKey.mPartitionPrincipal)) {
|
|
return false;
|
|
}
|
|
|
|
if (mCORSMode != aKey.mCORSMode) {
|
|
return false;
|
|
}
|
|
|
|
if (mNonce != aKey.mNonce) {
|
|
return false;
|
|
}
|
|
|
|
// NOTE: module always use UTF-8.
|
|
if (mKind == JS::loader::ScriptKind::eClassic) {
|
|
if (mHintCharset != aKey.mHintCharset) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (!mSRIMetadata.CanTrustBeDelegatedTo(aKey.mSRIMetadata) ||
|
|
!aKey.mSRIMetadata.CanTrustBeDelegatedTo(mSRIMetadata)) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
NS_IMPL_ISUPPORTS(ScriptLoadData, nsISupports)
|
|
|
|
ScriptLoadData::ScriptLoadData(ScriptLoader* aLoader,
|
|
JS::loader::ScriptLoadRequest* aRequest,
|
|
JS::loader::LoadedScript* aLoadedScript)
|
|
: mExpirationTime(aRequest->ExpirationTime()),
|
|
mLoader(aLoader),
|
|
mKey(aLoader, aRequest, aLoadedScript),
|
|
mLoadedScript(aLoadedScript),
|
|
mNetworkMetadata(aRequest->mNetworkMetadata) {}
|
|
|
|
NS_IMPL_ISUPPORTS(SharedScriptCache, nsIMemoryReporter)
|
|
|
|
MOZ_DEFINE_MALLOC_SIZE_OF(SharedScriptCacheMallocSizeOf)
|
|
|
|
SharedScriptCache::SharedScriptCache() = default;
|
|
|
|
void SharedScriptCache::Init() {
|
|
RegisterWeakMemoryReporter(this);
|
|
|
|
// URL classification (tracking protection etc) are handled inside
|
|
// nsHttpChannel.
|
|
// The cache reflects the policy for whether to block or not, and once
|
|
// the policy is modified, we should discard the cache, to avoid running
|
|
// a cached script which is supposed to be blocked.
|
|
auto ClearCache = [](const char*, void*) { Clear(); };
|
|
Preferences::RegisterPrefixCallback(ClearCache, "urlclassifier.");
|
|
Preferences::RegisterCallback(ClearCache,
|
|
"privacy.trackingprotection.enabled");
|
|
}
|
|
|
|
SharedScriptCache::~SharedScriptCache() { UnregisterWeakMemoryReporter(this); }
|
|
|
|
void SharedScriptCache::LoadCompleted(SharedScriptCache* aCache,
|
|
ScriptLoadData& aData) {}
|
|
|
|
NS_IMETHODIMP
|
|
SharedScriptCache::CollectReports(nsIHandleReportCallback* aHandleReport,
|
|
nsISupports* aData, bool aAnonymize) {
|
|
MOZ_COLLECT_REPORT("explicit/js-non-window/cache", KIND_HEAP, UNITS_BYTES,
|
|
SharedScriptCacheMallocSizeOf(this) +
|
|
SizeOfExcludingThis(SharedScriptCacheMallocSizeOf),
|
|
"Memory used for SharedScriptCache to share script "
|
|
"across documents");
|
|
return NS_OK;
|
|
}
|
|
|
|
void SharedScriptCache::Clear(const Maybe<bool>& aChrome,
|
|
const Maybe<nsCOMPtr<nsIPrincipal>>& aPrincipal,
|
|
const Maybe<nsCString>& aSchemelessSite,
|
|
const Maybe<OriginAttributesPattern>& aPattern,
|
|
const Maybe<nsCString>& aURL) {
|
|
using ContentParent = dom::ContentParent;
|
|
|
|
if (XRE_IsParentProcess()) {
|
|
for (auto* cp : ContentParent::AllProcesses(ContentParent::eLive)) {
|
|
(void)cp->SendClearScriptCache(aChrome, aPrincipal, aSchemelessSite,
|
|
aPattern, aURL);
|
|
}
|
|
}
|
|
|
|
if (sSingleton) {
|
|
sSingleton->ClearInProcess(aChrome, aPrincipal, aSchemelessSite, aPattern,
|
|
aURL);
|
|
}
|
|
}
|
|
|
|
/* static */
|
|
void SharedScriptCache::PrepareForLastCC() {
|
|
if (sSingleton) {
|
|
sSingleton->mComplete.Clear();
|
|
sSingleton->mPending.Clear();
|
|
sSingleton->mLoading.Clear();
|
|
}
|
|
}
|
|
|
|
} // namespace mozilla::dom
|