diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:13:33 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:13:33 +0000 |
commit | 086c044dc34dfc0f74fbe41f4ecb402b2cd34884 (patch) | |
tree | a4f824bd33cb075dd5aa3eb5a0a94af221bbe83a /layout/style/Loader.cpp | |
parent | Adding debian version 124.0.1-1. (diff) | |
download | firefox-086c044dc34dfc0f74fbe41f4ecb402b2cd34884.tar.xz firefox-086c044dc34dfc0f74fbe41f4ecb402b2cd34884.zip |
Merging upstream version 125.0.1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'layout/style/Loader.cpp')
-rw-r--r-- | layout/style/Loader.cpp | 208 |
1 files changed, 123 insertions, 85 deletions
diff --git a/layout/style/Loader.cpp b/layout/style/Loader.cpp index ebbc934466..1ea37b094f 100644 --- a/layout/style/Loader.cpp +++ b/layout/style/Loader.cpp @@ -8,7 +8,9 @@ #include "mozilla/css/Loader.h" +#include "MainThreadUtils.h" #include "mozilla/ArrayUtils.h" +#include "mozilla/css/ErrorReporter.h" #include "mozilla/dom/DocGroup.h" #include "mozilla/dom/FetchPriority.h" #include "mozilla/dom/SRILogHelper.h" @@ -22,6 +24,7 @@ #include "mozilla/SchedulerGroup.h" #include "mozilla/URLPreloader.h" #include "nsIChildChannel.h" +#include "nsIPrincipal.h" #include "nsISupportsPriority.h" #include "nsITimedChannel.h" #include "nsICachingChannel.h" @@ -34,7 +37,6 @@ #include "nsICookieJarSettings.h" #include "mozilla/dom/Document.h" #include "nsIURI.h" -#include "nsNetUtil.h" #include "nsContentUtils.h" #include "nsIScriptSecurityManager.h" #include "nsContentPolicyUtils.h" @@ -64,6 +66,7 @@ #include "mozilla/css/StreamLoader.h" #include "mozilla/SharedStyleSheetCache.h" #include "mozilla/StaticPrefs_layout.h" +#include "mozilla/StaticPrefs_network.h" #include "mozilla/StaticPrefs_dom.h" #include "mozilla/StaticPrefs_network.h" #include "mozilla/Try.h" @@ -308,7 +311,10 @@ SheetLoadData::SheetLoadData( mNonce(aNonce), mFetchPriority{aFetchPriority}, mGuessedEncoding(GetFallbackEncoding(*aLoader, aOwningNode, nullptr)), - mCompatMode(aLoader->CompatMode(aPreloadKind)) { + mCompatMode(aLoader->CompatMode(aPreloadKind)), + mRecordErrors( + aLoader && aLoader->GetDocument() && + css::ErrorReporter::ShouldReportErrors(*aLoader->GetDocument())) { MOZ_ASSERT(!aOwningNode || dom::LinkStyle::FromNode(*aOwningNode), "Must implement LinkStyle"); MOZ_ASSERT(mTriggeringPrincipal); @@ -349,7 +355,10 @@ SheetLoadData::SheetLoadData(css::Loader* aLoader, nsIURI* aURI, mFetchPriority(FetchPriority::Auto), mGuessedEncoding(GetFallbackEncoding( *aLoader, nullptr, aParentData ? aParentData->mEncoding : nullptr)), - mCompatMode(aLoader->CompatMode(mPreloadKind)) { + mCompatMode(aLoader->CompatMode(mPreloadKind)), + mRecordErrors( + aLoader && aLoader->GetDocument() && + css::ErrorReporter::ShouldReportErrors(*aLoader->GetDocument())) { MOZ_ASSERT(mLoader, "Must have a loader!"); MOZ_ASSERT(mTriggeringPrincipal); MOZ_ASSERT(!mUseSystemPrincipal || mSyncLoad, @@ -391,7 +400,10 @@ SheetLoadData::SheetLoadData( mFetchPriority(aFetchPriority), mGuessedEncoding( GetFallbackEncoding(*aLoader, nullptr, aPreloadEncoding)), - mCompatMode(aLoader->CompatMode(aPreloadKind)) { + mCompatMode(aLoader->CompatMode(aPreloadKind)), + mRecordErrors( + aLoader && aLoader->GetDocument() && + css::ErrorReporter::ShouldReportErrors(*aLoader->GetDocument())) { MOZ_ASSERT(mTriggeringPrincipal); MOZ_ASSERT(mLoader, "Must have a loader!"); MOZ_ASSERT(!mUseSystemPrincipal || mSyncLoad, @@ -639,43 +651,54 @@ static bool AllLoadsCanceled(const SheetLoadData& aData) { * page and check the mimetype on the channel to make sure we're not * loading non-text/css data in standards mode. */ -nsresult SheetLoadData::VerifySheetReadyToParse(nsresult aStatus, - const nsACString& aBytes1, - const nsACString& aBytes2, - nsIChannel* aChannel) { +nsresult SheetLoadData::VerifySheetReadyToParse( + nsresult aStatus, const nsACString& aBytes1, const nsACString& aBytes2, + nsIChannel* aChannel, nsIURI* aFinalChannelURI, + nsIPrincipal* aChannelResultPrincipal) { LOG(("SheetLoadData::VerifySheetReadyToParse")); - NS_ASSERTION(!mLoader->mSyncCallback, "Synchronous callback from necko"); + NS_ASSERTION((!NS_IsMainThread() || !mLoader->mSyncCallback), + "Synchronous callback from necko"); if (AllLoadsCanceled(*this)) { - LOG_WARN((" All loads are canceled, dropping")); - mLoader->SheetComplete(*this, NS_BINDING_ABORTED); + if (NS_IsMainThread()) { + LOG_WARN((" All loads are canceled, dropping")); + mLoader->SheetComplete(*this, NS_BINDING_ABORTED); + } + return NS_OK; + } + + if (!NS_IsMainThread() && mRecordErrors) { + // we cannot parse sheet OMT if we need to record errors return NS_OK; } if (NS_FAILED(aStatus)) { - LOG_WARN( - (" Load failed: status 0x%" PRIx32, static_cast<uint32_t>(aStatus))); - // Handle sheet not loading error because source was a tracking URL (or - // fingerprinting, cryptomining, etc). - // We make a note of this sheet node by including it in a dedicated - // array of blocked tracking nodes under its parent document. - // - // Multiple sheet load instances might be tied to this request, - // we annotate each one linked to a valid owning element (node). - if (net::UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode( - aStatus)) { - if (Document* doc = mLoader->GetDocument()) { - for (SheetLoadData* data = this; data; data = data->mNext) { - // owner node may be null but AddBlockTrackingNode can cope - doc->AddBlockedNodeByClassifier(data->mSheet->GetOwnerNode()); + if (NS_IsMainThread()) { + LOG_WARN( + (" Load failed: status 0x%" PRIx32, static_cast<uint32_t>(aStatus))); + // Handle sheet not loading error because source was a tracking URL (or + // fingerprinting, cryptomining, etc). + // We make a note of this sheet node by including it in a dedicated + // array of blocked tracking nodes under its parent document. + // + // Multiple sheet load instances might be tied to this request, + // we annotate each one linked to a valid owning element (node). + if (net::UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode( + aStatus)) { + if (Document* doc = mLoader->GetDocument()) { + for (SheetLoadData* data = this; data; data = data->mNext) { + // owner node may be null but AddBlockTrackingNode can cope + doc->AddBlockedNodeByClassifier(data->mSheet->GetOwnerNode()); + } } } + mLoader->SheetComplete(*this, aStatus); } - mLoader->SheetComplete(*this, aStatus); return NS_OK; } if (!aChannel) { + MOZ_ASSERT(NS_IsMainThread()); mLoader->SheetComplete(*this, NS_OK); return NS_OK; } @@ -688,10 +711,8 @@ nsresult SheetLoadData::VerifySheetReadyToParse(nsresult aStatus, // having a chrome URI. (Whether or not chrome stylesheets come through // this codepath seems nondeterministic.) // Otherwise we want the potentially-HTTP-redirected URI. - nsCOMPtr<nsIURI> channelURI; - NS_GetFinalChannelURI(aChannel, getter_AddRefs(channelURI)); - - if (!channelURI || !originalURI) { + if (!aFinalChannelURI || !originalURI) { + MOZ_ASSERT(NS_IsMainThread()); NS_ERROR("Someone just violated the nsIRequest contract"); LOG_WARN((" Channel without a URI. Bad!")); mLoader->SheetComplete(*this, NS_ERROR_UNEXPECTED); @@ -705,32 +726,33 @@ nsresult SheetLoadData::VerifySheetReadyToParse(nsresult aStatus, if (mUseSystemPrincipal) { result = secMan->GetSystemPrincipal(getter_AddRefs(principal)); } else { - result = secMan->GetChannelResultPrincipal(aChannel, - getter_AddRefs(principal)); + if (aChannelResultPrincipal) { + principal = aChannelResultPrincipal; + result = NS_OK; + } } } if (NS_FAILED(result)) { - LOG_WARN((" Couldn't get principal")); - mLoader->SheetComplete(*this, result); + if (NS_IsMainThread()) { + LOG_WARN((" Couldn't get principal")); + mLoader->SheetComplete(*this, result); + } return NS_OK; } mSheet->SetPrincipal(principal); - if (mSheet->GetCORSMode() == CORS_NONE && - !mTriggeringPrincipal->Subsumes(principal)) { - mIsCrossOriginNoCORS = true; - } - // If it's an HTTP channel, we want to make sure this is not an // error document we got. if (nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel)) { bool requestSucceeded; result = httpChannel->GetRequestSucceeded(&requestSucceeded); if (NS_SUCCEEDED(result) && !requestSucceeded) { - LOG((" Load returned an error page")); - mLoader->SheetComplete(*this, NS_ERROR_NOT_AVAILABLE); + if (NS_IsMainThread()) { + LOG((" Load returned an error page")); + mLoader->SheetComplete(*this, NS_ERROR_NOT_AVAILABLE); + } return NS_OK; } @@ -753,6 +775,9 @@ nsresult SheetLoadData::VerifySheetReadyToParse(nsresult aStatus, contentType.IsEmpty(); if (!validType) { + if (!NS_IsMainThread()) { + return NS_OK; + } const char* errorMessage; uint32_t errorFlag; bool sameOrigin = true; @@ -772,7 +797,8 @@ nsresult SheetLoadData::VerifySheetReadyToParse(nsresult aStatus, } AutoTArray<nsString, 2> strings; - CopyUTF8toUTF16(channelURI->GetSpecOrDefault(), *strings.AppendElement()); + CopyUTF8toUTF16(aFinalChannelURI->GetSpecOrDefault(), + *strings.AppendElement()); CopyASCIItoUTF16(contentType, *strings.AppendElement()); nsCOMPtr<nsIURI> referrer = ReferrerInfo()->GetOriginalReferrer(); @@ -791,6 +817,13 @@ nsresult SheetLoadData::VerifySheetReadyToParse(nsresult aStatus, SRIMetadata sriMetadata; mSheet->GetIntegrity(sriMetadata); if (!sriMetadata.IsEmpty()) { + if (!NS_IsMainThread()) { + // We dont process any further in OMT. + // This is because we have some main-thread only accesses below. + // We need to find a way to optimize this handling. + // See Bug 1882046. + return NS_OK; + } nsAutoCString sourceUri; if (mLoader->mDocument && mLoader->mDocument->GetDocumentURI()) { mLoader->mDocument->GetDocumentURI()->GetAsciiSpec(sourceUri); @@ -815,9 +848,13 @@ nsresult SheetLoadData::VerifySheetReadyToParse(nsresult aStatus, } } + if (mSheet->GetCORSMode() == CORS_NONE && + !mTriggeringPrincipal->Subsumes(principal)) { + mIsCrossOriginNoCORS = true; + } // Enough to set the URIs on mSheet, since any sibling datas we have share // the same mInner as mSheet and will thus get the same URI. - mSheet->SetURIs(channelURI, originalURI, channelURI); + mSheet->SetURIs(aFinalChannelURI, originalURI, aFinalChannelURI); ReferrerPolicy policy = nsContentUtils::GetReferrerPolicyFromChannel(aChannel); @@ -1353,11 +1390,11 @@ nsresult Loader::LoadSheet(SheetLoadData& aLoadData, SheetState aSheetState, void Loader::AdjustPriority(const SheetLoadData& aLoadData, nsIChannel* aChannel) { - if (!StaticPrefs::network_fetchpriority_enabled()) { - if (!aLoadData.ShouldDefer() && aLoadData.IsLinkRelPreload()) { - SheetLoadData::PrioritizeAsPreload(aChannel); - } + if (!aLoadData.ShouldDefer() && aLoadData.IsLinkRelPreload()) { + SheetLoadData::PrioritizeAsPreload(aChannel); + } + if (!StaticPrefs::network_fetchpriority_enabled()) { return; } @@ -1367,32 +1404,27 @@ void Loader::AdjustPriority(const SheetLoadData& aLoadData, return; } - // Adjusting priorites is specified as implementation-defined. To align with - // other browsers for potentially important cases, some adjustments are made - // according to - // <https://web.dev/articles/fetch-priority#browser_priority_and_fetchpriority>. - const int32_t supportsPriority = [&]() { + // Adjusting priorites is specified as implementation-defined. + // See corresponding preferences in StaticPrefList.yaml for more context. + const int32_t supportsPriorityDelta = [&]() { if (aLoadData.ShouldDefer()) { - return nsISupportsPriority::PRIORITY_LOW; + return FETCH_PRIORITY_ADJUSTMENT_FOR(deferred_style, + aLoadData.mFetchPriority); } - switch (aLoadData.mFetchPriority) { - case FetchPriority::Auto: { - return nsISupportsPriority::PRIORITY_HIGHEST; - } - case FetchPriority::High: { - return nsISupportsPriority::PRIORITY_HIGHEST; - } - case FetchPriority::Low: { - return nsISupportsPriority::PRIORITY_HIGH; - } + if (aLoadData.IsLinkRelPreload()) { + return FETCH_PRIORITY_ADJUSTMENT_FOR(link_preload_style, + aLoadData.mFetchPriority); } - - MOZ_ASSERT_UNREACHABLE(); - return nsISupportsPriority::PRIORITY_HIGHEST; + return FETCH_PRIORITY_ADJUSTMENT_FOR(non_deferred_style, + aLoadData.mFetchPriority); }(); - LogPriorityMapping(sCssLoaderLog, aLoadData.mFetchPriority, supportsPriority); - sp->SetPriority(supportsPriority); + sp->AdjustPriority(supportsPriorityDelta); +#ifdef DEBUG + int32_t adjustedPriority; + sp->GetPriority(&adjustedPriority); + LogPriorityMapping(sCssLoaderLog, aLoadData.mFetchPriority, adjustedPriority); +#endif } nsresult Loader::LoadSheetAsyncInternal(SheetLoadData& aLoadData, @@ -1582,32 +1614,35 @@ nsresult Loader::LoadSheetAsyncInternal(SheetLoadData& aLoadData, /** * ParseSheet handles parsing the data stream. */ -Loader::Completed Loader::ParseSheet(const nsACString& aBytes, - SheetLoadData& aLoadData, - AllowAsyncParse aAllowAsync) { +Loader::Completed Loader::ParseSheet( + const nsACString& aBytes, const RefPtr<SheetLoadDataHolder>& aLoadData, + AllowAsyncParse aAllowAsync) { LOG(("css::Loader::ParseSheet")); - if (aLoadData.mURI) { - LOG_URI(" Load succeeded for URI: '%s', parsing", aLoadData.mURI); + SheetLoadData* loadData = aLoadData->get(); + MOZ_ASSERT(loadData); + + if (loadData->mURI) { + LOG_URI(" Load succeeded for URI: '%s', parsing", loadData->mURI); } AUTO_PROFILER_LABEL_CATEGORY_PAIR_RELEVANT_FOR_JS(LAYOUT_CSSParsing); ++mParsedSheetCount; - aLoadData.mIsBeingParsed = true; + loadData->mIsBeingParsed = true; - StyleSheet* sheet = aLoadData.mSheet; + StyleSheet* sheet = loadData->mSheet; MOZ_ASSERT(sheet); // Some cases, like inline style and UA stylesheets, need to be parsed // synchronously. The former may trigger child loads, the latter must not. - if (aLoadData.mSyncLoad || aAllowAsync == AllowAsyncParse::No) { - sheet->ParseSheetSync(this, aBytes, &aLoadData); - aLoadData.mIsBeingParsed = false; + if (loadData->mSyncLoad || aAllowAsync == AllowAsyncParse::No) { + sheet->ParseSheetSync(this, aBytes, loadData); + loadData->mIsBeingParsed = false; - bool noPendingChildren = aLoadData.mPendingChildren == 0; - MOZ_ASSERT_IF(aLoadData.mSyncLoad, noPendingChildren); + bool noPendingChildren = loadData->mPendingChildren == 0; + MOZ_ASSERT_IF(loadData->mSyncLoad, noPendingChildren); if (noPendingChildren) { - SheetComplete(aLoadData, NS_OK); + SheetComplete(*loadData, NS_OK); return Completed::Yes; } return Completed::No; @@ -1621,9 +1656,9 @@ Loader::Completed Loader::ParseSheet(const nsACString& aBytes, sheet->ParseSheet(*this, aBytes, aLoadData) ->Then( GetMainThreadSerialEventTarget(), __func__, - [loadData = RefPtr<SheetLoadData>(&aLoadData)](bool aDummy) { + [loadData = aLoadData](bool aDummy) { MOZ_ASSERT(NS_IsMainThread()); - loadData->SheetFinishedParsingAsync(); + loadData->get()->SheetFinishedParsingAsync(); }, [] { MOZ_CRASH("rejected parse promise"); }); return Completed::No; @@ -1847,7 +1882,10 @@ Result<Loader::LoadSheetResult, nsresult> Loader::LoadInlineStyle( // effects of inline stylesheets are visible immediately (aside from // @imports). NS_ConvertUTF16toUTF8 utf8(aBuffer); - completed = ParseSheet(utf8, *data, AllowAsyncParse::No); + RefPtr<SheetLoadDataHolder> holder( + new nsMainThreadPtrHolder<css::SheetLoadData>(__func__, data.get(), + true)); + completed = ParseSheet(utf8, holder, AllowAsyncParse::No); if (completed == Completed::Yes) { if (isWorthCaching) { mInlineSheets.InsertOrUpdate(aBuffer, std::move(sheet)); |