From d1fd2e3b393ba56e5d79ea97dca824d795cb033a Mon Sep 17 00:00:00 2001 From: roytam1 Date: Mon, 18 Aug 2025 10:28:00 +0800 Subject: [PATCH] import from UXP: Issue #2258 - Part 3: Allow sniffing with XCTO:nosniff + empty MIME type. (707c3e3f) --- image/imgLoader.cpp | 7 ----- netwerk/base/nsNetUtil.cpp | 31 ++++++++++++++++++- netwerk/protocol/http/nsHttpChannel.cpp | 2 +- .../converters/nsUnknownDecoder.cpp | 22 ------------- .../mediasniffer/nsMediaSniffer.cpp | 4 --- 5 files changed, 31 insertions(+), 35 deletions(-) diff --git a/image/imgLoader.cpp b/image/imgLoader.cpp index e3f918d9d..4aabf834f 100644 --- a/image/imgLoader.cpp +++ b/image/imgLoader.cpp @@ -2502,13 +2502,6 @@ imgLoader::GetMIMETypeFromContent(nsIRequest* aRequest, uint32_t aLength, nsACString& aContentType) { - nsCOMPtr channel(do_QueryInterface(aRequest)); - if (channel) { - nsCOMPtr loadInfo = channel->GetLoadInfo(); - if (loadInfo->GetSkipContentSniffing()) { - return NS_ERROR_NOT_AVAILABLE; - } - } return GetMimeTypeFromContent((const char*)aContents, aLength, aContentType); } diff --git a/netwerk/base/nsNetUtil.cpp b/netwerk/base/nsNetUtil.cpp index 90bcc2d4d..ec5f81eef 100644 --- a/netwerk/base/nsNetUtil.cpp +++ b/netwerk/base/nsNetUtil.cpp @@ -18,6 +18,7 @@ #include "nsContentUtils.h" #include "nsHashKeys.h" #include "nsHttp.h" +#include "nsMimeTypes.h" #include "nsIAsyncStreamCopier.h" #include "nsIAuthPrompt.h" #include "nsIAuthPrompt2.h" @@ -2150,6 +2151,33 @@ NS_SniffContent(const char *aSnifferType, nsIRequest *aRequest, return; } + aSniffedType.Truncate(); + + nsCOMPtr channel = do_QueryInterface(aRequest); + if (channel) { + nsCOMPtr loadInfo = channel->GetLoadInfo(); + if (loadInfo->GetSkipContentSniffing()) { + // In case XCTO nosniff was present, we should skip sniffing here, but... + nsAutoCString currentContentType; + channel->GetContentType(currentContentType); + // We cannot skip sniffing if the current MIME type is a JSON file. + // The JSON-Viewer relies on its own sniffer to determine if it can render + // the page, so we need to make an exception if the Server provides a valid + // JSON MIME type (application/json, application/web-manifest or text/json). + // We also don't skip sniffing if the currently-known content type is empty, + // to deal with webmaster errors (nosniff is set but no content-type supplied) + // See Issue #2258. + if (!currentContentType.Equals(APPLICATION_JSON) && + !currentContentType.Equals(APPLICATION_WEB_MANIFEST) && + !currentContentType.Equals(TEXT_JSON) && + !currentContentType.IsEmpty()) { + // Content type supplied and it's not a JSON type; honor XCTO:nosniff. + return; + } + } + } + + // Iterate through the sniffers... nsCOMArray sniffers; cache->GetEntries(sniffers); for (int32_t i = 0; i < sniffers.Count(); ++i) { @@ -2158,8 +2186,9 @@ NS_SniffContent(const char *aSnifferType, nsIRequest *aRequest, return; } } + + // If we get here, there's nothing more to be done, return with a truncated aSniffedType. - aSniffedType.Truncate(); } bool diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index 5ffec8da2..4cc0c8221 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -1181,7 +1181,7 @@ ProcessXCTO(nsIURI* aURI, nsHttpResponseHead* aResponseHead, nsILoadInfo* aLoadI policyType == nsIContentPolicy::TYPE_SUBDOCUMENT) { // If the header XCTO nosniff is set for any browsing context, then // we set the skipContentSniffing flag on the Loadinfo. Within - // GetMIMETypeFromContent we then bail early and do not do any sniffing. + // NS_SniffContent we then bail early and do not do any sniffing. aLoadInfo->SetSkipContentSniffing(true); return NS_OK; } diff --git a/netwerk/streamconv/converters/nsUnknownDecoder.cpp b/netwerk/streamconv/converters/nsUnknownDecoder.cpp index bab9b84c9..d4aa09f2b 100644 --- a/netwerk/streamconv/converters/nsUnknownDecoder.cpp +++ b/netwerk/streamconv/converters/nsUnknownDecoder.cpp @@ -316,13 +316,6 @@ nsUnknownDecoder::GetMIMETypeFromContent(nsIRequest* aRequest, nsACString& type) { // Note: This is only used by sniffer, therefore we do not need to lock anything here. - nsCOMPtr channel(do_QueryInterface(aRequest)); - if (channel) { - nsCOMPtr loadInfo = channel->GetLoadInfo(); - if (loadInfo->GetSkipContentSniffing()) { - return NS_ERROR_NOT_AVAILABLE; - } - } mBuffer = const_cast(reinterpret_cast(aData)); mBufferLen = aLength; DetermineContentType(aRequest); @@ -353,11 +346,6 @@ bool nsUnknownDecoder::AllowSniffing(nsIRequest* aRequest) return false; } - nsCOMPtr loadInfo = channel->GetLoadInfo(); - if (loadInfo->GetSkipContentSniffing()) { - return false; - } - bool isLocalFile = false; if (NS_FAILED(uri->SchemeIs("file", &isLocalFile)) || isLocalFile) { return false; @@ -405,13 +393,6 @@ void nsUnknownDecoder::DetermineContentType(nsIRequest* aRequest) if (!mContentType.IsEmpty()) return; nsCOMPtr channel(do_QueryInterface(aRequest)); - if (channel) { - nsCOMPtr loadInfo = channel->GetLoadInfo(); - if (loadInfo->GetSkipContentSniffing()) { - return; - } - } - const char* testData = mBuffer; uint32_t testDataLen = mBufferLen; // Check if data are compressed. @@ -583,9 +564,6 @@ bool nsUnknownDecoder::SniffURI(nsIRequest* aRequest) { nsCOMPtr channel(do_QueryInterface(aRequest)); nsCOMPtr loadInfo = channel->GetLoadInfo(); - if (loadInfo->GetSkipContentSniffing()) { - return false; - } nsCOMPtr mimeService(do_GetService("@mozilla.org/mime;1")); if (mimeService) { nsCOMPtr channel = do_QueryInterface(aRequest); diff --git a/toolkit/components/mediasniffer/nsMediaSniffer.cpp b/toolkit/components/mediasniffer/nsMediaSniffer.cpp index 5c6fee065..d00dea894 100644 --- a/toolkit/components/mediasniffer/nsMediaSniffer.cpp +++ b/toolkit/components/mediasniffer/nsMediaSniffer.cpp @@ -138,10 +138,6 @@ nsMediaSniffer::GetMIMETypeFromContent(nsIRequest* aRequest, nsACString& aSniffedType) { nsCOMPtr channel = do_QueryInterface(aRequest); if (channel) { - nsCOMPtr loadInfo = channel->GetLoadInfo(); - if (loadInfo->GetSkipContentSniffing()) { - return NS_ERROR_NOT_AVAILABLE; - } nsLoadFlags loadFlags = 0; channel->GetLoadFlags(&loadFlags); if (!(loadFlags & nsIChannel::LOAD_MEDIA_SNIFFER_OVERRIDES_CONTENT_TYPE)) {