Merge remote-tracking branch 'origin/tracking' into custom

This commit is contained in:
roytam1 2025-08-18 09:49:01 +08:00
commit 75997f1917
12 changed files with 110 additions and 10 deletions

View file

@ -295,6 +295,7 @@ LoadInfoToLoadInfoArgs(nsILoadInfo *aLoadInfo,
aLoadInfo->GetForcePreflight(),
aLoadInfo->GetIsPreflight(),
aLoadInfo->GetLoadTriggeredFromExternal(),
aLoadInfo->GetSkipContentSniffing(),
aLoadInfo->GetIsFromProcessingFrameAttributes()
);
@ -372,7 +373,8 @@ LoadInfoArgsToLoadInfo(const OptionalLoadInfoArgs& aOptionalLoadInfoArgs,
loadInfoArgs.corsUnsafeHeaders(),
loadInfoArgs.forcePreflight(),
loadInfoArgs.isPreflight(),
loadInfoArgs.loadTriggeredFromExternal()
loadInfoArgs.loadTriggeredFromExternal(),
loadInfoArgs.skipContentSniffing()
);
if (loadInfoArgs.isFromProcessingFrameAttributes()) {

View file

@ -171,6 +171,7 @@ CSS_STATE_PSEUDO_CLASS(disabled, ":disabled", 0, "", NS_EVENT_STATE_DISABLED)
CSS_STATE_PSEUDO_CLASS(enabled, ":enabled", 0, "", NS_EVENT_STATE_ENABLED)
CSS_STATE_PSEUDO_CLASS(focus, ":focus", 0, "", NS_EVENT_STATE_FOCUS)
CSS_STATE_PSEUDO_CLASS(focusWithin, ":focus-within", 0, "", NS_EVENT_STATE_FOCUS_WITHIN)
CSS_STATE_PSEUDO_CLASS(focusVisible, ":focus-visible", 0, "", NS_EVENT_STATE_FOCUSRING)
CSS_STATE_PSEUDO_CLASS(hover, ":hover", 0, "", NS_EVENT_STATE_HOVER)
CSS_STATE_PSEUDO_CLASS(mozDragOver, ":-moz-drag-over", 0, "", NS_EVENT_STATE_DRAGOVER)
CSS_STATE_PSEUDO_CLASS(target, ":target", 0, "", NS_EVENT_STATE_URLTARGET)

View file

@ -66,6 +66,7 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
, mForcePreflight(false)
, mIsPreflight(false)
, mLoadTriggeredFromExternal(false)
, mSkipContentSniffing(false)
, mIsFromProcessingFrameAttributes(false)
{
MOZ_ASSERT(mLoadingPrincipal);
@ -241,6 +242,7 @@ LoadInfo::LoadInfo(nsPIDOMWindowOuter* aOuterWindow,
, mForcePreflight(false)
, mIsPreflight(false)
, mLoadTriggeredFromExternal(false)
, mSkipContentSniffing(false)
, mIsFromProcessingFrameAttributes(false)
{
// Top-level loads are never third-party
@ -305,6 +307,7 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
, mForcePreflight(rhs.mForcePreflight)
, mIsPreflight(rhs.mIsPreflight)
, mLoadTriggeredFromExternal(rhs.mLoadTriggeredFromExternal)
, mSkipContentSniffing(rhs.mSkipContentSniffing)
, mIsFromProcessingFrameAttributes(rhs.mIsFromProcessingFrameAttributes)
{
}
@ -333,7 +336,8 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
const nsTArray<nsCString>& aCorsUnsafeHeaders,
bool aForcePreflight,
bool aIsPreflight,
bool aLoadTriggeredFromExternal)
bool aLoadTriggeredFromExternal,
bool aSkipContentSniffing)
: mLoadingPrincipal(aLoadingPrincipal)
, mTriggeringPrincipal(aTriggeringPrincipal)
, mPrincipalToInherit(aPrincipalToInherit)
@ -357,6 +361,7 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
, mForcePreflight(aForcePreflight)
, mIsPreflight(aIsPreflight)
, mLoadTriggeredFromExternal(aLoadTriggeredFromExternal)
, mSkipContentSniffing(aSkipContentSniffing)
, mIsFromProcessingFrameAttributes(false)
{
// Only top level TYPE_DOCUMENT loads can have a null loadingPrincipal
@ -965,6 +970,17 @@ LoadInfo::MaybeIncreaseTainting(uint32_t aTainting)
return NS_OK;
}
NS_IMETHODIMP
LoadInfo::GetSkipContentSniffing(bool* aSkipContentSniffing) {
*aSkipContentSniffing = mSkipContentSniffing;
return NS_OK;
}
NS_IMETHODIMP
LoadInfo::SetSkipContentSniffing(bool aSkipContentSniffing) {
mSkipContentSniffing = aSkipContentSniffing;
return NS_OK;
}
NS_IMETHODIMP
LoadInfo::GetIsTopLevelLoad(bool *aResult)
{

View file

@ -111,7 +111,8 @@ private:
const nsTArray<nsCString>& aUnsafeHeaders,
bool aForcePreflight,
bool aIsPreflight,
bool aLoadTriggeredFromExternal);
bool aLoadTriggeredFromExternal,
bool aSkipContentSniffing);
LoadInfo(const LoadInfo& rhs);
friend nsresult
@ -157,6 +158,7 @@ private:
bool mForcePreflight;
bool mIsPreflight;
bool mLoadTriggeredFromExternal;
bool mSkipContentSniffing;
// Is true if this load was triggered by processing the attributes of the
// browsing context container.

View file

@ -367,6 +367,15 @@ interface nsILoadInfo : nsISupports
*/
[infallible] readonly attribute unsigned long securityMode;
/**
* This flag is used for any browsing context where we should not sniff
* the content type. E.g if an iframe has the XCTO nosniff header, then
* that flag is set to true so we skip content sniffing for that browsing
* context.
*/
[infallible] attribute boolean skipContentSniffing;
/**
* True if this request is embedded in a context that can't be third-party
* (i.e. an iframe embedded in a cross-origin parent window). If this is

View file

@ -16,6 +16,7 @@
#include "nsContentUtils.h"
#include "nsHashKeys.h"
#include "nsHttp.h"
#include "nsMimeTypes.h"
#include "nsIAsyncStreamCopier.h"
#include "nsIAuthPrompt.h"
#include "nsIAuthPrompt2.h"
@ -2149,6 +2150,33 @@ NS_SniffContent(const char *aSnifferType, nsIRequest *aRequest,
return;
}
aSniffedType.Truncate();
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
if (channel) {
nsCOMPtr<nsILoadInfo> 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<nsIContentSniffer> sniffers;
cache->GetEntries(sniffers);
for (int32_t i = 0; i < sniffers.Count(); ++i) {
@ -2157,8 +2185,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

View file

@ -55,6 +55,7 @@ struct LoadInfoArgs
bool forcePreflight;
bool isPreflight;
bool loadTriggeredFromExternal;
bool skipContentSniffing;
bool isFromProcessingFrameAttributes;
};

View file

@ -14,6 +14,7 @@
#include "nsHttp.h"
#include "nsHttpChannel.h"
#include "nsHttpHandler.h"
#include "nsString.h"
#include "nsIApplicationCacheService.h"
#include "nsIApplicationCacheContainer.h"
#include "nsICacheStorageService.h"
@ -1100,6 +1101,16 @@ ProcessXCTO(nsIURI* aURI, nsHttpResponseHead* aResponseHead, nsILoadInfo* aLoadI
ReportTypeBlocking(aURI, aLoadInfo, "MimeTypeMismatch");
return NS_ERROR_CORRUPTED_CONTENT;
}
auto policyType = aLoadInfo->GetExternalContentPolicyType();
if (policyType == nsIContentPolicy::TYPE_DOCUMENT ||
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
// NS_SniffContent we then bail early and do not do any sniffing.
aLoadInfo->SetSkipContentSniffing(true);
return NS_OK;
}
return NS_OK;
}

View file

@ -315,6 +315,7 @@ nsUnknownDecoder::GetMIMETypeFromContent(nsIRequest* aRequest,
uint32_t aLength,
nsACString& type)
{
// Note: This is only used by sniffer, therefore we do not need to lock anything here.
mBuffer = const_cast<char*>(reinterpret_cast<const char*>(aData));
mBufferLen = aLength;
DetermineContentType(aRequest);
@ -391,10 +392,10 @@ void nsUnknownDecoder::DetermineContentType(nsIRequest* aRequest)
NS_ASSERTION(mContentType.IsEmpty(), "Content type is already known.");
if (!mContentType.IsEmpty()) return;
nsCOMPtr<nsIHttpChannel> channel(do_QueryInterface(aRequest));
const char* testData = mBuffer;
uint32_t testDataLen = mBufferLen;
// Check if data are compressed.
nsCOMPtr<nsIHttpChannel> channel(do_QueryInterface(aRequest));
if (channel) {
nsresult rv = ConvertEncodedData(aRequest, mBuffer, mBufferLen);
if (NS_SUCCEEDED(rv)) {
@ -592,6 +593,12 @@ bool nsUnknownDecoder::LastDitchSniff(nsIRequest* aRequest)
// All we can do now is try to guess whether this is text/plain or
// application/octet-stream
nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
nsCOMPtr<nsILoadInfo> loadInfo = channel->GetLoadInfo();
if (loadInfo->GetSkipContentSniffing()) {
return false;
}
const char* testData;
uint32_t testDataLen;
if (mDecodedData.IsEmpty()) {
@ -791,6 +798,11 @@ nsBinaryDetector::DetermineContentType(nsIRequest* aRequest)
return;
}
nsCOMPtr<nsILoadInfo> loadInfo = httpChannel->GetLoadInfo();
if (loadInfo->GetSkipContentSniffing()) {
return;
}
// It's an HTTP channel. Check for the text/plain mess
nsAutoCString contentTypeHdr;
httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("Content-Type"),

View file

@ -166,6 +166,7 @@ nsHtml5StreamParser::nsHtml5StreamParser(nsHtml5TreeOpExecutor* aExecutor,
, mLoadFlusher(new nsHtml5LoadFlusher(aExecutor))
, mFlushTimer(do_CreateInstance("@mozilla.org/timer;1"))
, mMode(aMode)
, mSkipContentSniffing(false)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
mFlushTimer->SetTarget(mThread);
@ -549,7 +550,7 @@ nsHtml5StreamParser::FinalizeSniffing(const uint8_t* aFromSegment, // can be nul
}
// meta scan failed.
if (mCharsetSource >= kCharsetFromHintPrevDoc) {
if (!mSkipContentSniffing && mCharsetSource >= kCharsetFromHintPrevDoc) {
mFeedChardet = false;
return SetupDecodingAndWriteSniffingBufferAndCurrentSegment(aFromSegment, aCount, aWriteCount);
}
@ -874,6 +875,13 @@ nsHtml5StreamParser::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
mObserver->OnStartRequest(aRequest, aContext);
}
mRequest = aRequest;
nsCOMPtr<nsIChannel> myChannel(do_QueryInterface(aRequest));
nsCOMPtr<nsILoadInfo> loadInfo = myChannel->GetLoadInfo();
mSkipContentSniffing = loadInfo->GetSkipContentSniffing();
if (mSkipContentSniffing) {
mFeedChardet = false;
}
mStreamState = STREAM_BEING_READ;

View file

@ -561,6 +561,11 @@ class nsHtml5StreamParser : public nsICharsetDetectionObserver {
*/
eParserMode mMode;
/**
* Whether the parser should not sniff the content type.
*/
bool mSkipContentSniffing;
/**
* The pref html5.flushtimer.initialdelay: Time in milliseconds between
* the time a network buffer is seen and the timer firing when the

View file

@ -97,17 +97,21 @@ NS_IMETHODIMP
nsScreenGtk :: GetPixelDepth(int32_t *aPixelDepth)
{
GdkVisual * visual = gdk_screen_get_system_visual(gdk_screen_get_default());
*aPixelDepth = gdk_visual_get_depth(visual);
uint32_t pixelDepth = gdk_visual_get_depth(visual);
if (pixelDepth == 32) {
// If a device reports 32 bits per pixel, it's still only using 8 bits
// per color component, which is what our callers want to know.
// (Some devices report 32 and some devices report 24, because Linux)
pixelDepth = 24;
}
*aPixelDepth = pixelDepth;
return NS_OK;
} // GetPixelDepth
NS_IMETHODIMP
nsScreenGtk :: GetColorDepth(int32_t *aColorDepth)
{
return GetPixelDepth ( aColorDepth );
} // GetColorDepth
NS_IMETHODIMP