From 2a3f5af3182555c2637de76bd1b25bb7e3346491 Mon Sep 17 00:00:00 2001 From: Timothy Nikkel Date: Thu, 12 Dec 2024 08:11:14 +0000 Subject: [PATCH 001/196] Bug 1936288. Avoid getting the display port another time in ScrollContainerFrame::BuildDisplayList. r=hiro This sometimes shows up in profiles, so avoid getting the displayport when we have that info already. Differential Revision: https://phabricator.services.mozilla.com/D231686 --- layout/base/DisplayPortUtils.cpp | 8 ++++---- layout/generic/ScrollContainerFrame.cpp | 10 +++++++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/layout/base/DisplayPortUtils.cpp b/layout/base/DisplayPortUtils.cpp index f63a334a59181..36f54daa65d9c 100644 --- a/layout/base/DisplayPortUtils.cpp +++ b/layout/base/DisplayPortUtils.cpp @@ -464,15 +464,15 @@ void DisplayPortUtils::MarkDisplayPortAsPainted(nsIContent* aContent) { } bool DisplayPortUtils::HasNonMinimalDisplayPort(nsIContent* aContent) { - return HasDisplayPort(aContent) && - !aContent->GetProperty(nsGkAtoms::MinimalDisplayPort); + return !aContent->GetProperty(nsGkAtoms::MinimalDisplayPort) && + HasDisplayPort(aContent); } bool DisplayPortUtils::HasNonMinimalNonZeroDisplayPort(nsIContent* aContent) { - if (!HasDisplayPort(aContent)) { + if (aContent->GetProperty(nsGkAtoms::MinimalDisplayPort)) { return false; } - if (aContent->GetProperty(nsGkAtoms::MinimalDisplayPort)) { + if (!HasDisplayPort(aContent)) { return false; } diff --git a/layout/generic/ScrollContainerFrame.cpp b/layout/generic/ScrollContainerFrame.cpp index 6017c7e4f860a..132504f526bac 100644 --- a/layout/generic/ScrollContainerFrame.cpp +++ b/layout/generic/ScrollContainerFrame.cpp @@ -4203,9 +4203,13 @@ void ScrollContainerFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, // We want to call SetContainsNonMinimalDisplayPort if // mWillBuildScrollableLayer is true for any reason other than having a // minimal display port. - if (aBuilder->IsPaintingToWindow()) { - if (DisplayPortUtils::HasNonMinimalDisplayPort(GetContent()) || - mZoomableByAPZ) { + if (mWillBuildScrollableLayer && aBuilder->IsPaintingToWindow()) { + // Since mWillBuildScrollableLayer = HasDisplayPort || mZoomableByAPZ we can + // simplify this check to avoid getting the display port again. + if (mZoomableByAPZ || + !GetContent()->GetProperty(nsGkAtoms::MinimalDisplayPort)) { + MOZ_ASSERT(DisplayPortUtils::HasNonMinimalDisplayPort(GetContent()) || + mZoomableByAPZ); aBuilder->SetContainsNonMinimalDisplayPort(); } } From efcf56d4864bc4fb33dbe885b8bc398b06730e3c Mon Sep 17 00:00:00 2001 From: Daniel Holbert Date: Thu, 12 Dec 2024 08:38:32 +0000 Subject: [PATCH 002/196] Bug 1929147: Make VectorImage::GetWidth/GetHeight gracefully fail (rather than crashing) if internal doc's root element is nullptr. r=tnikkel Based on intermittent crashes in automation, it seems like during shutdown, two things may happen independently: (A) we gather a memory report that asks our SVG images for their width/height. (B) we tear down the internal SVG document for our SVG images. If they happen in that order (A before B), then everything's fine; but if B happens *before* A, then the width/height queries in A will find an SVG document with a null pointer for the root element. So we need to handle that case gracefully. Differential Revision: https://phabricator.services.mozilla.com/D231825 --- image/VectorImage.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/image/VectorImage.cpp b/image/VectorImage.cpp index dd9d17a4fa9ed..ec41114fb8cdd 100644 --- a/image/VectorImage.cpp +++ b/image/VectorImage.cpp @@ -450,9 +450,14 @@ VectorImage::GetWidth(int32_t* aWidth) { } SVGSVGElement* rootElem = mSVGDocumentWrapper->GetRootSVGElem(); - MOZ_ASSERT(rootElem, - "Should have a root SVG elem, since we finished " - "loading without errors"); + if (MOZ_UNLIKELY(!rootElem)) { + // Unlikely to reach this code; we should have a root SVG elem, since we + // finished loading without errors. But we can sometimes get here during + // shutdown (as part of gathering a memory report) if the internal SVG + // document has already been torn down by a shutdown listener. + *aWidth = 0; + return NS_ERROR_FAILURE; + } LengthPercentage rootElemWidth = rootElem->GetIntrinsicWidth(); if (!rootElemWidth.IsLength()) { @@ -542,9 +547,14 @@ VectorImage::GetHeight(int32_t* aHeight) { } SVGSVGElement* rootElem = mSVGDocumentWrapper->GetRootSVGElem(); - MOZ_ASSERT(rootElem, - "Should have a root SVG elem, since we finished " - "loading without errors"); + if (MOZ_UNLIKELY(!rootElem)) { + // Unlikely to reach this code; we should have a root SVG elem, since we + // finished loading without errors. But we can sometimes get here during + // shutdown (as part of gathering a memory report) if the internal SVG + // document has already been torn down by a shutdown listener. + *aHeight = 0; + return NS_ERROR_FAILURE; + } LengthPercentage rootElemHeight = rootElem->GetIntrinsicHeight(); if (!rootElemHeight.IsLength()) { From af0bc28514e25de15588770589661a44e9ded3fd Mon Sep 17 00:00:00 2001 From: smayya Date: Thu, 12 Dec 2024 08:55:31 +0000 Subject: [PATCH 003/196] Bug 1830022 - add Idempotency-Key header to post request. r=necko-reviewers,valentin Differential Revision: https://phabricator.services.mozilla.com/D227801 --- dom/base/nsContentUtils.cpp | 4 ++- modules/libpref/init/StaticPrefList.yaml | 6 ++++ netwerk/protocol/http/nsHttpAtomList.h | 1 + netwerk/protocol/http/nsHttpChannel.cpp | 31 ++++++++++++++++----- netwerk/protocol/http/nsHttpHandler.cpp | 30 ++++++++++++++++++++ netwerk/protocol/http/nsHttpHandler.h | 6 ++++ netwerk/protocol/http/nsHttpRequestHead.cpp | 2 ++ netwerk/protocol/http/nsHttpRequestHead.h | 2 ++ 8 files changed, 74 insertions(+), 8 deletions(-) diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 5381b76c96ae0..e89a42d374a88 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -7868,7 +7868,9 @@ bool nsContentUtils::IsCORSSafelistedRequestHeader(const nsACString& aName, (aName.LowerCaseEqualsLiteral("content-type") && nsContentUtils::IsAllowedNonCorsContentType(aValue)) || (aName.LowerCaseEqualsLiteral("range") && - nsContentUtils::IsAllowedNonCorsRange(aValue)); + nsContentUtils::IsAllowedNonCorsRange(aValue)) || + (StaticPrefs::network_http_idempotencyKey_enabled() && + aName.LowerCaseEqualsLiteral("idempotency-key")); } mozilla::LogModule* nsContentUtils::ResistFingerprintingLog() { diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml index e4e2cad99e672..82ffb8f189d44 100644 --- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -12652,6 +12652,12 @@ value: 2 mirror: always +# Include an idempotency-key header for POST requests +- name: network.http.idempotencyKey.enabled + type: RelaxedAtomicBool + value: @IS_NIGHTLY_BUILD@ + mirror: always + # Whether to respect the redirected-tainted origin flag # https://fetch.spec.whatwg.org/#concept-request-tainted-origin - name: network.http.origin.redirectTainted diff --git a/netwerk/protocol/http/nsHttpAtomList.h b/netwerk/protocol/http/nsHttpAtomList.h index 0799519a7b611..458c2fda78b2b 100644 --- a/netwerk/protocol/http/nsHttpAtomList.h +++ b/netwerk/protocol/http/nsHttpAtomList.h @@ -55,6 +55,7 @@ HTTP_ATOM(Expires, "Expires") HTTP_ATOM(From, "From") HTTP_ATOM(GlobalPrivacyControl, "Sec-GPC") HTTP_ATOM(Host, "Host") +HTTP_ATOM(Idempotency_Key, "Idempotency-Key") HTTP_ATOM(If, "If") HTTP_ATOM(If_Match, "If-Match") HTTP_ATOM(If_Modified_Since, "If-Modified-Since") diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index 237fb6444283e..f9803fd6b4628 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -4118,17 +4118,14 @@ nsresult nsHttpChannel::OpenCacheEntry(bool isHttps) { // make sure we're not abusing this function MOZ_ASSERT(!mCacheEntry, "cache entry already open"); - - if (mRequestHead.IsPost()) { - // If the post id is already set then this is an attempt to replay - // a post transaction via the cache. Otherwise, we need a unique - // post id for this transaction. - if (mPostID == 0) mPostID = gHttpHandler->GenerateUniqueID(); - } else if (!mRequestHead.IsGet() && !mRequestHead.IsHead()) { + if (!mRequestHead.IsGet() && !mRequestHead.IsHead() && + !mRequestHead.IsPost() && !mRequestHead.IsPatch()) { // don't use the cache for other types of requests return NS_OK; } + MOZ_ASSERT_IF(mRequestHead.IsPost() || mRequestHead.IsPatch(), mPostID > 0); + return OpenCacheEntryInternal(isHttps); } @@ -7057,6 +7054,26 @@ nsresult nsHttpChannel::BeginConnect() { static_cast(rv))); } + if (mRequestHead.IsPost() || mRequestHead.IsPatch()) { + // If the post id is already set then this is an attempt to replay + // a post/patch transaction via the cache. Otherwise, we need a unique + // post id for this transaction. + if (mPostID == 0) { + mPostID = gHttpHandler->GenerateUniqueID(); + } + + if (StaticPrefs::network_http_idempotencyKey_enabled() && + !mRequestHead.HasHeader(nsHttp::Idempotency_Key)) { + // check if we need to add + // idempotency-key header + // See Bug 1830022 for more details + nsAutoCString key; + gHttpHandler->GenerateIdempotencyKeyForPost(mPostID, mLoadInfo, key); + MOZ_ALWAYS_SUCCEEDS( + mRequestHead.SetHeader(nsHttp::Idempotency_Key, key, false)); + } + } + // if this somehow fails we can go on without it Unused << gHttpHandler->AddConnectionHeader(&mRequestHead, mCaps); diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp index 95b5382f49c2c..0220119107aeb 100644 --- a/netwerk/protocol/http/nsHttpHandler.cpp +++ b/netwerk/protocol/http/nsHttpHandler.cpp @@ -30,6 +30,8 @@ #include "mozilla/ClearOnShutdown.h" #include "mozilla/Components.h" #include "mozilla/Printf.h" +#include "mozilla/RandomNum.h" +#include "mozilla/SHA1.h" #include "mozilla/Sprintf.h" #include "mozilla/StaticPrefs_network.h" #include "mozilla/StaticPrefs_privacy.h" @@ -75,6 +77,7 @@ #include "mozilla/DynamicFpiRedirectHeuristic.h" #include "mozilla/BasePrincipal.h" #include "mozilla/LazyIdleThread.h" +#include "mozilla/OriginAttributesHashKey.h" #include "mozilla/StaticPrefs_image.h" #include "mozilla/SyncRunnable.h" @@ -260,6 +263,8 @@ nsHttpHandler::nsHttpHandler() mImageAcceptHeader(ImageAcceptHeader()), mDocumentAcceptHeader(DocumentAcceptHeader()), mLastUniqueID(NowInSeconds()), + mIdempotencyKeySeed(mozilla::RandomUint64OrDie()), + mPrivateBrowsingIdempotencyKeySeed(mozilla::RandomUint64OrDie()), mDebugObservations(false), mEnableAltSvc(false), mEnableAltSvcOE(false), @@ -558,6 +563,31 @@ void nsHttpHandler::UpdateParentalControlsEnabled(bool waitForCompletion) { } } +void nsHttpHandler::GenerateIdempotencyKeyForPost(const uint32_t aPostId, + nsILoadInfo* aLoadInfo, + nsACString& aOutKey) { + MOZ_ASSERT(aLoadInfo); + OriginAttributes attrs = aLoadInfo->GetOriginAttributes(); + + // Create a SHA1 string using the origin attributes, session seed and the post + // id. + nsAutoCString sha1Input; + attrs.CreateSuffix(sha1Input); + sha1Input.AppendInt(aPostId); + sha1Input.AppendInt(attrs.IsPrivateBrowsing() + ? mPrivateBrowsingIdempotencyKeySeed + : mIdempotencyKeySeed); + SHA1Sum sha1; + SHA1Sum::Hash hash; + sha1.update((sha1Input.get()), sha1Input.Length()); + sha1.finish(hash); + uint64_t hashValue = BigEndian::readUint64(&hash); + + aOutKey.Append("\""); + aOutKey.AppendInt(hashValue); + aOutKey.Append("\""); +} + const nsCString& nsHttpHandler::Http3QlogDir() { if (StaticPrefs::network_http_http3_enable_qlog()) { return mHttp3QlogDir; diff --git a/netwerk/protocol/http/nsHttpHandler.h b/netwerk/protocol/http/nsHttpHandler.h index d8ef1358734fd..79a176ba98e0d 100644 --- a/netwerk/protocol/http/nsHttpHandler.h +++ b/netwerk/protocol/http/nsHttpHandler.h @@ -242,6 +242,10 @@ class nsHttpHandler final : public nsIHttpProtocolHandler, uint32_t GenerateUniqueID() { return ++mLastUniqueID; } uint32_t SessionStartTime() { return mSessionStartTime; } + void GenerateIdempotencyKeyForPost(const uint32_t aPostId, + nsILoadInfo* aLoadInfo, + nsACString& aOutKey); + // // Connection management methods: // @@ -636,6 +640,8 @@ class nsHttpHandler final : public nsIHttpProtocolHandler, // useragent components nsCString mLegacyAppName{"Mozilla"}; nsCString mLegacyAppVersion{"5.0"}; + uint64_t mIdempotencyKeySeed; + uint64_t mPrivateBrowsingIdempotencyKeySeed; nsCString mPlatform; nsCString mOscpu; nsCString mMisc; diff --git a/netwerk/protocol/http/nsHttpRequestHead.cpp b/netwerk/protocol/http/nsHttpRequestHead.cpp index 0ce7a14f8aa21..9044068eb9431 100644 --- a/netwerk/protocol/http/nsHttpRequestHead.cpp +++ b/netwerk/protocol/http/nsHttpRequestHead.cpp @@ -296,6 +296,8 @@ void nsHttpRequestHead::ParseMethod(const nsCString& aRawMethod, aParsedMethod = kMethod_Get; } else if (!strcmp(aRawMethod.get(), "POST")) { aParsedMethod = kMethod_Post; + } else if (!strcmp(aRawMethod.get(), "PATCH")) { + aParsedMethod = kMethod_Patch; } else if (!strcmp(aRawMethod.get(), "OPTIONS")) { aParsedMethod = kMethod_Options; } else if (!strcmp(aRawMethod.get(), "CONNECT")) { diff --git a/netwerk/protocol/http/nsHttpRequestHead.h b/netwerk/protocol/http/nsHttpRequestHead.h index e308790bd4d4e..02eba42876992 100644 --- a/netwerk/protocol/http/nsHttpRequestHead.h +++ b/netwerk/protocol/http/nsHttpRequestHead.h @@ -101,6 +101,7 @@ class nsHttpRequestHead { kMethod_Custom, kMethod_Get, kMethod_Post, + kMethod_Patch, kMethod_Options, kMethod_Connect, kMethod_Head, @@ -115,6 +116,7 @@ class nsHttpRequestHead { bool EqualsMethod(ParsedMethodType aType); bool IsGet() { return EqualsMethod(kMethod_Get); } bool IsPost() { return EqualsMethod(kMethod_Post); } + bool IsPatch() { return EqualsMethod(kMethod_Patch); } bool IsOptions() { return EqualsMethod(kMethod_Options); } bool IsConnect() { return EqualsMethod(kMethod_Connect); } bool IsHead() { return EqualsMethod(kMethod_Head); } From d8f434756502d50c4deb2124cad7dc2404ba2222 Mon Sep 17 00:00:00 2001 From: smayya Date: Thu, 12 Dec 2024 08:55:31 +0000 Subject: [PATCH 004/196] Bug 1830022 - add test to verify Idempotency-Key header settings. r=necko-reviewers,valentin Depends on D227801 Differential Revision: https://phabricator.services.mozilla.com/D227802 --- netwerk/test/unit/test_bug1830022.js | 128 +++++++++++++++++++++++++++ netwerk/test/unit/xpcshell.toml | 2 + 2 files changed, 130 insertions(+) create mode 100644 netwerk/test/unit/test_bug1830022.js diff --git a/netwerk/test/unit/test_bug1830022.js b/netwerk/test/unit/test_bug1830022.js new file mode 100644 index 0000000000000..ddc881dd74660 --- /dev/null +++ b/netwerk/test/unit/test_bug1830022.js @@ -0,0 +1,128 @@ +"use strict"; + +const { HttpServer } = ChromeUtils.importESModule( + "resource://testing-common/httpd.sys.mjs" +); + +function makeChannel(url) { + return NetUtil.newChannel({ + uri: url, + loadUsingSystemPrincipal: true, + }).QueryInterface(Ci.nsIHttpChannel); +} + +ChromeUtils.defineLazyGetter(this, "URL", function () { + return "http://localhost:" + httpServer.identity.primaryPort; +}); + +let httpServer = null; + +function pathHandler(metadata, response) { + var body; + if (metadata.hasHeader("Idempotency-Key")) { + response.setStatusLine(metadata.httpVersion, 200, "OK"); + // echo back the header for further validation + let IDK = metadata.getHeader("Idempotency-Key"); + response.setHeader("Idempotency-Key", IDK, false); + body = "success"; + } else { + response.setStatusLine( + metadata.httpVersion, + 500, + "missing Idempotency-Key" + ); + body = "failed"; + } + response.bodyOutputStream.write(body, body.length); +} + +add_setup(async () => { + httpServer = new HttpServer(); + httpServer.registerPathHandler("/test_bug1830022", pathHandler); + httpServer.start(-1); + registerCleanupFunction(async () => await httpServer.stop()); +}); + +// tests if we add the header for the POST request +add_task(async function idempotency_key_addition_for_post() { + let chan = makeChannel(URL + "/test_bug1830022"); + chan.requestMethod = "POST"; + await new Promise(resolve => { + chan.asyncOpen(new ChannelListener(resolve)); + }); + Assert.notEqual(chan.getResponseHeader("Idempotency-Key"), ""); + Assert.notEqual(chan.getRequestHeader("Idempotency-Key"), ""); + Assert.equal( + chan.getResponseHeader("Idempotency-Key"), + chan.getRequestHeader("Idempotency-Key") + ); +}); + +// tests if we add the header for the PATCH request +add_task(async function idempotency_key_addition_for_patch() { + let chan = makeChannel(URL + "/test_bug1830022"); + chan.requestMethod = "PATCH"; + await new Promise(resolve => { + chan.asyncOpen(new ChannelListener(resolve)); + }); + Assert.notEqual(chan.getResponseHeader("Idempotency-Key"), ""); + Assert.notEqual(chan.getRequestHeader("Idempotency-Key"), ""); + Assert.equal( + chan.getResponseHeader("Idempotency-Key"), + chan.getRequestHeader("Idempotency-Key") + ); +}); + +// tests Idempotency key's uniqueness +add_task(async function idempotency_key_uniqueness() { + let chan = makeChannel(URL + "/test_bug1830022"); + chan.requestMethod = "POST"; + await new Promise(resolve => { + chan.asyncOpen(new ChannelListener(resolve)); + }); + + let chan2 = makeChannel(URL + "/test_bug1830022"); + chan2.requestMethod = "POST"; + await new Promise(resolve => { + chan2.asyncOpen(new ChannelListener(resolve)); + }); + + Assert.notEqual( + chan.getRequestHeader("Idempotency-Key"), + chan2.getRequestHeader("Idempotency-Key") + ); + + // tests if the Idempotency key is same for reposts + let chan3 = makeChannel(URL + "/test_bug1830022"); + chan3.requestMethod = "POST"; + await new Promise(resolve => { + chan3.asyncOpen(new ChannelListener(resolve)); + }); + + let cachekey = chan3.QueryInterface(Ci.nsICacheInfoChannel).cacheKey; + + let chan4 = makeChannel(URL + "/test_bug1830022"); + chan4.requestMethod = "POST"; + chan4.QueryInterface(Ci.nsICacheInfoChannel).cacheKey = cachekey; + await new Promise(resolve => { + chan4.asyncOpen(new ChannelListener(resolve)); + }); + + Assert.equal( + chan3.getRequestHeader("Idempotency-Key"), + chan4.getRequestHeader("Idempotency-Key") + ); +}); + +// tests if we do not overwrite the header that is set before opening the channel +add_task(async function idempotency_key_addition_for_post() { + // construct the channel + let chan = makeChannel(URL + "/test_bug1830022"); + chan.setRequestHeader("Idempotency-Key", "U-V-W-X-Y-Z", false); + chan.requestMethod = "POST"; + await new Promise(resolve => { + chan.asyncOpen(new ChannelListener(resolve)); + }); + Assert.equal(chan.getRequestHeader("Idempotency-Key"), "U-V-W-X-Y-Z"); + Assert.equal(chan.getResponseHeader("Idempotency-Key"), "U-V-W-X-Y-Z"); +}); diff --git a/netwerk/test/unit/xpcshell.toml b/netwerk/test/unit/xpcshell.toml index f752a9e1eca65..6524a4b63d7c8 100644 --- a/netwerk/test/unit/xpcshell.toml +++ b/netwerk/test/unit/xpcshell.toml @@ -811,6 +811,8 @@ skip-if = ["os == 'win' && socketprocess_networking"] ["test_httpcancel.js"] +["test_bug1830022.js"] + ["test_https_rr_ech_prefs.js"] skip-if = ["os == 'android'"] run-sequentially = "node server exceptions dont replay well" From f67b4c2e4e2a2a225d00168f91daff2651c0ebd0 Mon Sep 17 00:00:00 2001 From: smayya Date: Thu, 12 Dec 2024 08:55:32 +0000 Subject: [PATCH 005/196] Bug 1830022 - update POST tests for idempotency-key. r=necko-reviewers,devtools-reviewers,kershaw,jdescottes Differential Revision: https://phabricator.services.mozilla.com/D230749 --- devtools/client/netmonitor/test/browser_net_copy_as_curl.js | 1 + 1 file changed, 1 insertion(+) diff --git a/devtools/client/netmonitor/test/browser_net_copy_as_curl.js b/devtools/client/netmonitor/test/browser_net_copy_as_curl.js index 4cce679fe9e4e..4717611a818a3 100644 --- a/devtools/client/netmonitor/test/browser_net_copy_as_curl.js +++ b/devtools/client/netmonitor/test/browser_net_copy_as_curl.js @@ -81,6 +81,7 @@ function buildTestData(QUOTE) { "POST", "--data-raw " + quote(POST_PAYLOAD), header("Content-Type: text/plain;charset=UTF-8"), + header("idempotency-key: 123456"), ]; const ORIGIN_RESULT = [header("Origin: https://example.com")]; From 02c3ffc9215ecf748482c931733c04564b522a62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Wang?= Date: Thu, 12 Dec 2024 09:04:47 +0000 Subject: [PATCH 006/196] Bug 1936219 - Only call GetTrustedTypesCompliantString from worker's constructor in a Window/WorkerGlobalScope context. r=smaug The spec only mentions Window/WorkerGlobalScope contexts [1] but we also call the worker constructor for other nsIGlobalObject such as BackstagePass. See [2] for details. [1] https://html.spec.whatwg.org/multipage/workers.html#dedicated-workers-and-the-worker-interface [2] https://bugzilla.mozilla.org/show_bug.cgi?id=1936219#c6 Differential Revision: https://phabricator.services.mozilla.com/D231774 --- dom/workers/Worker.cpp | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/dom/workers/Worker.cpp b/dom/workers/Worker.cpp index 154042689f02a..4c2d73d7a2aed 100644 --- a/dom/workers/Worker.cpp +++ b/dom/workers/Worker.cpp @@ -39,22 +39,39 @@ already_AddRefed Worker::Constructor( nsCOMPtr globalObject = do_QueryInterface(aGlobal.GetAsSupports()); - if (globalObject->GetAsInnerWindow() && - !globalObject->GetAsInnerWindow()->IsCurrentInnerWindow()) { + nsPIDOMWindowInner* innerWindow = globalObject->GetAsInnerWindow(); + if (innerWindow && !innerWindow->IsCurrentInnerWindow()) { aRv.ThrowInvalidStateError( "Cannot create worker for a going to be discarded document"); return nullptr; } - constexpr nsLiteralString sink = u"Worker constructor"_ns; - Maybe compliantStringHolder; - const nsAString* compliantString = - TrustedTypeUtils::GetTrustedTypesCompliantString( - aScriptURL, sink, kTrustedTypesOnlySinkGroup, *globalObject, - compliantStringHolder, aRv); - if (aRv.Failed()) { - return nullptr; + // The spec only mentions Window and WorkerGlobalScope global objects, but + // Gecko can actually call the constructor with other ones, so we just skip + // trusted types handling in that case. + // https://html.spec.whatwg.org/multipage/workers.html#dedicated-workers-and-the-worker-interface + const nsAString* compliantString = nullptr; + bool performTrustedTypeConversion = innerWindow; + if (!performTrustedTypeConversion) { + if (JSObject* globalJSObject = globalObject->GetGlobalJSObject()) { + performTrustedTypeConversion = IsWorkerGlobal(globalJSObject); + } + } + if (performTrustedTypeConversion) { + constexpr nsLiteralString sink = u"Worker constructor"_ns; + Maybe compliantStringHolder; + compliantString = TrustedTypeUtils::GetTrustedTypesCompliantString( + aScriptURL, sink, kTrustedTypesOnlySinkGroup, *globalObject, + compliantStringHolder, aRv); + if (aRv.Failed()) { + return nullptr; + } + } else { + compliantString = aScriptURL.IsUSVString() + ? &aScriptURL.GetAsUSVString() + : &aScriptURL.GetAsTrustedScriptURL().mData; } + MOZ_ASSERT(compliantString); RefPtr workerPrivate = WorkerPrivate::Constructor( cx, *compliantString, false /* aIsChromeWorker */, WorkerKindDedicated, From dab5d7d140c7e44068643e8950ac8cd2d3324086 Mon Sep 17 00:00:00 2001 From: Andreas Farre Date: Thu, 12 Dec 2024 09:07:36 +0000 Subject: [PATCH 007/196] Bug 1921733 - Test case. r=dom-core,peterv Differential Revision: https://phabricator.services.mozilla.com/D224957 --- dom/security/featurepolicy/moz.build | 1 + .../featurepolicy/test/browser/browser.toml | 8 ++ .../browser/browser_cross_origin_embed.js | 101 ++++++++++++++++++ .../featurepolicy/test/browser/empty.html | 2 + 4 files changed, 112 insertions(+) create mode 100644 dom/security/featurepolicy/test/browser/browser.toml create mode 100644 dom/security/featurepolicy/test/browser/browser_cross_origin_embed.js create mode 100644 dom/security/featurepolicy/test/browser/empty.html diff --git a/dom/security/featurepolicy/moz.build b/dom/security/featurepolicy/moz.build index b39cdd9c7f366..a1882999366ba 100644 --- a/dom/security/featurepolicy/moz.build +++ b/dom/security/featurepolicy/moz.build @@ -9,6 +9,7 @@ with Files("**"): TEST_DIRS += ["test/gtest"] MOCHITEST_MANIFESTS += ["test/mochitest/mochitest.toml"] +BROWSER_CHROME_MANIFESTS += ["test/browser/browser.toml"] EXPORTS.mozilla.dom += [ "Feature.h", diff --git a/dom/security/featurepolicy/test/browser/browser.toml b/dom/security/featurepolicy/test/browser/browser.toml new file mode 100644 index 0000000000000..d806bd68beab9 --- /dev/null +++ b/dom/security/featurepolicy/test/browser/browser.toml @@ -0,0 +1,8 @@ +[DEFAULT] +support-files = [ + "empty.html", + "!/dom/tests/mochitest/geolocation/network_geolocation.sjs", +] +tags = "feature-policy" + +["browser_cross_origin_embed.js"] diff --git a/dom/security/featurepolicy/test/browser/browser_cross_origin_embed.js b/dom/security/featurepolicy/test/browser/browser_cross_origin_embed.js new file mode 100644 index 0000000000000..d119e919971ef --- /dev/null +++ b/dom/security/featurepolicy/test/browser/browser_cross_origin_embed.js @@ -0,0 +1,101 @@ +"use strict"; + +const TEST_PATH_COM = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "https://example.com" +); +const TEST_PATH_ORG = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content", + "https://example.org" +); + +const GEO_URL = + "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs"; + +add_task(async () => { + await SpecialPowers.pushPrefEnv({ + set: [ + ["geo.provider.network.url", GEO_URL], + ["geo.timeout", 4000], + ], + }); + + await BrowserTestUtils.withNewTab( + TEST_PATH_COM + "empty.html", + async browser => { + let notificationPopup = document.getElementById("notification-popup"); + let notificationShown = BrowserTestUtils.waitForPopupEvent( + notificationPopup, + "shown" + ); + + const notificationHidden = BrowserTestUtils.waitForPopupEvent( + notificationPopup, + "hidden" + ); + + let res = SpecialPowers.spawn(browser, [], () => { + return new Promise(resolve => + content.navigator.geolocation.getCurrentPosition( + () => resolve("allowed"), + () => resolve("disallowed") + ) + ); + }); + + await notificationShown; + notificationPopup + .querySelector("button.popup-notification-primary-button") + .click(); + + await notificationHidden; + + let result = await res; + is(result, "allowed", "Geolocation allowed"); + + BrowserTestUtils.startLoadingURIString( + browser, + TEST_PATH_COM + "empty.html" + ); + await BrowserTestUtils.browserLoaded(browser); + + const bc = await SpecialPowers.spawn( + browser, + [TEST_PATH_ORG + "empty.html"], + async url => { + const { document } = content; + const embed = document.createElement("embed"); + embed.src = url; + const promise = new Promise(resolve => { + embed.addEventListener("load", resolve, { once: true }); + }); + document.body.appendChild(embed); + await promise; + return embed.browsingContext; + } + ); + + notificationShown = BrowserTestUtils.waitForPopupEvent( + notificationPopup, + "shown" + ); + + res = SpecialPowers.spawn(bc, [], () => { + return new Promise(resolve => + content.navigator.geolocation.getCurrentPosition( + () => resolve("allowed"), + () => resolve("disallowed") + ) + ); + }); + + result = await Promise.race([ + res, + notificationShown.then(_ => { + return "notification shown"; + }), + ]); + is(result, "disallowed", "Geolocation disallowed"); + } + ); +}); diff --git a/dom/security/featurepolicy/test/browser/empty.html b/dom/security/featurepolicy/test/browser/empty.html new file mode 100644 index 0000000000000..0f4eccf30bd77 --- /dev/null +++ b/dom/security/featurepolicy/test/browser/empty.html @@ -0,0 +1,2 @@ + +Nothing here From 53197925e1f8e69d570826eb311bcf9a79b90a47 Mon Sep 17 00:00:00 2001 From: karanBRAVO Date: Thu, 12 Dec 2024 09:19:00 +0000 Subject: [PATCH 008/196] Bug 1932455 - [devtools] Ensure tooltip content is scrollable by adding max-height and overflow properties, directly targetting the RDM using the HTML element id attribute. r=devtools-reviewers,nchevobbe Differential Revision: https://phabricator.services.mozilla.com/D230559 --- devtools/client/themes/tooltips.css | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/devtools/client/themes/tooltips.css b/devtools/client/themes/tooltips.css index 7880567dc3504..0125d6131f2ec 100644 --- a/devtools/client/themes/tooltips.css +++ b/devtools/client/themes/tooltips.css @@ -339,6 +339,16 @@ strong { flex-grow: 1; } +/* Adding the scrollbar in the RDM tooltip */ +#device-selector-menu .tooltip-panel { + max-height: 500px; +} + +#device-selector-menu .tooltip-panel > .checkbox-container { + height: 100%; + overflow-y: auto; +} + .tooltip-visible { display: flex; } From 5676f8ee7c2f5364fbb78104e5985aad20eef828 Mon Sep 17 00:00:00 2001 From: Tom Schuster Date: Thu, 12 Dec 2024 09:30:12 +0000 Subject: [PATCH 009/196] Bug 1935959 - Remove inline event handlers from bookmarksHistoryTooltip. r=Gijs Differential Revision: https://phabricator.services.mozilla.com/D231548 --- browser/base/content/browser-places.js | 10 ++++++---- browser/base/content/main-popupset.js | 4 ++++ .../places/content/bookmarksHistoryTooltip.inc.xhtml | 4 +--- browser/components/places/content/bookmarksSidebar.js | 8 ++++++++ browser/components/places/content/historySidebar.js | 8 ++++++++ 5 files changed, 27 insertions(+), 7 deletions(-) diff --git a/browser/base/content/browser-places.js b/browser/base/content/browser-places.js index 2dda58ef49de0..6281c2d6bdc5e 100644 --- a/browser/base/content/browser-places.js +++ b/browser/base/content/browser-places.js @@ -843,7 +843,8 @@ var BookmarksEventHandler = { var tree = aTooltip.triggerNode.parentNode; var cell = tree.getCellAt(aEvent.clientX, aEvent.clientY); if (cell.row == -1) { - return false; + aEvent.preventDefault(); + return; } node = tree.view.nodeForTreeIndex(cell.row); cropped = tree.isCellCropped(cell.row, cell.col); @@ -860,7 +861,8 @@ var BookmarksEventHandler = { } if (!node && !targetURI) { - return false; + aEvent.preventDefault(); + return; } // Show node.label as tooltip's title for non-Places nodes. @@ -874,7 +876,8 @@ var BookmarksEventHandler = { // Show tooltip for containers only if their title is cropped. if (!cropped && !url) { - return false; + aEvent.preventDefault(); + return; } let tooltipTitle = aEvent.target.querySelector(".places-tooltip-title"); @@ -891,7 +894,6 @@ var BookmarksEventHandler = { } // Show tooltip. - return true; }, }; diff --git a/browser/base/content/main-popupset.js b/browser/base/content/main-popupset.js index 30e95bac0c4e2..13bd8f7bc3eff 100644 --- a/browser/base/content/main-popupset.js +++ b/browser/base/content/main-popupset.js @@ -408,6 +408,9 @@ document.addEventListener( gCustomizeMode.onPanelContextMenuShowing(event); ToolbarContextMenu.updateExtension(event.target); break; + case "bhTooltip": + BookmarksEventHandler.fillInBHTooltip(event.target, event); + break; } }); @@ -433,6 +436,7 @@ document.addEventListener( mainPopupSet.addEventListener("popuphiding", event => { switch (event.target.id) { case "tabbrowser-tab-tooltip": + case "bhTooltip": event.target.removeAttribute("position"); break; } diff --git a/browser/components/places/content/bookmarksHistoryTooltip.inc.xhtml b/browser/components/places/content/bookmarksHistoryTooltip.inc.xhtml index 445f2cdcb4ffc..d5192f922d9ae 100644 --- a/browser/components/places/content/bookmarksHistoryTooltip.inc.xhtml +++ b/browser/components/places/content/bookmarksHistoryTooltip.inc.xhtml @@ -4,9 +4,7 @@ + class="places-tooltip"> diff --git a/browser/components/places/content/bookmarksSidebar.js b/browser/components/places/content/bookmarksSidebar.js index 60cc7eb067416..25ce145c95254 100644 --- a/browser/components/places/content/bookmarksSidebar.js +++ b/browser/components/places/content/bookmarksSidebar.js @@ -36,6 +36,14 @@ function init() { document.getElementById("bookmarks-view").place = "place:type=" + Ci.nsINavHistoryQueryOptions.RESULTS_AS_ROOTS_QUERY; + + let bhTooltip = document.getElementById("bhTooltip"); + bhTooltip.addEventListener("popupshowing", event => { + window.top.BookmarksEventHandler.fillInBHTooltip(bhTooltip, event); + }); + bhTooltip.addEventListener("popuphiding", () => + bhTooltip.removeAttribute("position") + ); } function searchBookmarks(aSearchString) { diff --git a/browser/components/places/content/historySidebar.js b/browser/components/places/content/historySidebar.js index 4c910bd47dc77..84e21ef877ee4 100644 --- a/browser/components/places/content/historySidebar.js +++ b/browser/components/places/content/historySidebar.js @@ -63,6 +63,14 @@ function HistorySidebarInit() { document.getElementById("byday").setAttribute("checked", "true"); } + let bhTooltip = document.getElementById("bhTooltip"); + bhTooltip.addEventListener("popupshowing", event => { + window.top.BookmarksEventHandler.fillInBHTooltip(bhTooltip, event); + }); + bhTooltip.addEventListener("popuphiding", () => + bhTooltip.removeAttribute("position") + ); + searchHistory(""); } From 3a9b267f49e3cd7c988d783e86b3ed689518a00a Mon Sep 17 00:00:00 2001 From: RebecaTudor Date: Thu, 12 Dec 2024 09:34:40 +0000 Subject: [PATCH 010/196] Bug 1936514 - Change strings for "Customize in onboarding" r=android-reviewers,twhite Changed strings of buttons for customize theme and toolbar from onboarding according to Figma. Differential Revision: https://phabricator.services.mozilla.com/D231790 --- .../fenix/onboarding/view/ThemeOnboardingPage.kt | 4 ++-- .../fenix/onboarding/view/ToolbarOnboardingPage.kt | 2 +- .../android/fenix/app/src/main/res/values/strings.xml | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/onboarding/view/ThemeOnboardingPage.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/onboarding/view/ThemeOnboardingPage.kt index 9cc6058877c1e..01810b700d2e3 100644 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/onboarding/view/ThemeOnboardingPage.kt +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/onboarding/view/ThemeOnboardingPage.kt @@ -60,7 +60,7 @@ fun ThemeOnboardingPage( pageState: OnboardingPageState, onThemeSelectionClicked: (ThemeOptionType) -> Unit, ) { - // Base + // Base Column( modifier = Modifier .background(FirefoxTheme.colors.layer1) @@ -278,7 +278,7 @@ private fun OnboardingPagePreview() { description = stringResource(id = R.string.onboarding_customize_theme_description), primaryButton = Action( text = stringResource( - id = R.string.onboarding_customize_theme_save_and_continue_button, + id = R.string.onboarding_save_and_continue_button, ), onClick = {}, ), diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/onboarding/view/ToolbarOnboardingPage.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/onboarding/view/ToolbarOnboardingPage.kt index b76073297be4e..64bae79999dc9 100644 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/onboarding/view/ToolbarOnboardingPage.kt +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/onboarding/view/ToolbarOnboardingPage.kt @@ -251,7 +251,7 @@ private fun OnboardingPagePreview() { description = stringResource(id = R.string.onboarding_customize_toolbar_description), primaryButton = Action( text = stringResource( - id = R.string.onboarding_customize_toolbar_save_and_continue_button, + id = R.string.onboarding_save_and_start_button, ), onClick = {}, ), diff --git a/mobile/android/fenix/app/src/main/res/values/strings.xml b/mobile/android/fenix/app/src/main/res/values/strings.xml index a44631609627e..21eb11b0f8f5b 100644 --- a/mobile/android/fenix/app/src/main/res/values/strings.xml +++ b/mobile/android/fenix/app/src/main/res/values/strings.xml @@ -574,8 +574,8 @@ Pick a toolbar placement Keep searches within reach. - - Save and continue + + Save and continue Skip @@ -591,15 +591,15 @@ Pick a theme See the web in the best light. - - Save and start browsing + + Save and start browsing Skip Dark Light - + System auto Large header image of the theme selection view showing illustrated artist and builder tools. From 6b44ffd5b31c55ce843df973fa081c7ec839459f Mon Sep 17 00:00:00 2001 From: Jan Varga Date: Thu, 12 Dec 2024 09:49:43 +0000 Subject: [PATCH 011/196] Bug 1933868 - Extend the expiration of localstorage.database.request_allow_to_close_response_time; r=dom-storage-reviewers,jstutte Differential Revision: https://phabricator.services.mozilla.com/D231907 --- dom/localstorage/metrics.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dom/localstorage/metrics.yaml b/dom/localstorage/metrics.yaml index 81e325ad346fc..426423947cf34 100644 --- a/dom/localstorage/metrics.yaml +++ b/dom/localstorage/metrics.yaml @@ -106,4 +106,4 @@ localstorage.database: notification_emails: - jvarga@mozilla.com - storage-telemetry@mozilla.com - expires: 136 + expires: 139 From d456d049bbd95b7728a49443a56e4ac36627a080 Mon Sep 17 00:00:00 2001 From: Stanca Serban Date: Thu, 12 Dec 2024 12:36:12 +0200 Subject: [PATCH 012/196] Backed out 3 changesets (bug 1830022) for causing multiple failures. CLOSED TREE Backed out changeset e3b4f68850a3 (bug 1830022) Backed out changeset 1418de170250 (bug 1830022) Backed out changeset 046fbeb93400 (bug 1830022) --- .../test/browser_net_copy_as_curl.js | 1 - dom/base/nsContentUtils.cpp | 4 +- modules/libpref/init/StaticPrefList.yaml | 6 - netwerk/protocol/http/nsHttpAtomList.h | 1 - netwerk/protocol/http/nsHttpChannel.cpp | 31 +---- netwerk/protocol/http/nsHttpHandler.cpp | 30 ---- netwerk/protocol/http/nsHttpHandler.h | 6 - netwerk/protocol/http/nsHttpRequestHead.cpp | 2 - netwerk/protocol/http/nsHttpRequestHead.h | 2 - netwerk/test/unit/test_bug1830022.js | 128 ------------------ netwerk/test/unit/xpcshell.toml | 2 - 11 files changed, 8 insertions(+), 205 deletions(-) delete mode 100644 netwerk/test/unit/test_bug1830022.js diff --git a/devtools/client/netmonitor/test/browser_net_copy_as_curl.js b/devtools/client/netmonitor/test/browser_net_copy_as_curl.js index 4717611a818a3..4cce679fe9e4e 100644 --- a/devtools/client/netmonitor/test/browser_net_copy_as_curl.js +++ b/devtools/client/netmonitor/test/browser_net_copy_as_curl.js @@ -81,7 +81,6 @@ function buildTestData(QUOTE) { "POST", "--data-raw " + quote(POST_PAYLOAD), header("Content-Type: text/plain;charset=UTF-8"), - header("idempotency-key: 123456"), ]; const ORIGIN_RESULT = [header("Origin: https://example.com")]; diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index e89a42d374a88..5381b76c96ae0 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -7868,9 +7868,7 @@ bool nsContentUtils::IsCORSSafelistedRequestHeader(const nsACString& aName, (aName.LowerCaseEqualsLiteral("content-type") && nsContentUtils::IsAllowedNonCorsContentType(aValue)) || (aName.LowerCaseEqualsLiteral("range") && - nsContentUtils::IsAllowedNonCorsRange(aValue)) || - (StaticPrefs::network_http_idempotencyKey_enabled() && - aName.LowerCaseEqualsLiteral("idempotency-key")); + nsContentUtils::IsAllowedNonCorsRange(aValue)); } mozilla::LogModule* nsContentUtils::ResistFingerprintingLog() { diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml index 82ffb8f189d44..e4e2cad99e672 100644 --- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -12652,12 +12652,6 @@ value: 2 mirror: always -# Include an idempotency-key header for POST requests -- name: network.http.idempotencyKey.enabled - type: RelaxedAtomicBool - value: @IS_NIGHTLY_BUILD@ - mirror: always - # Whether to respect the redirected-tainted origin flag # https://fetch.spec.whatwg.org/#concept-request-tainted-origin - name: network.http.origin.redirectTainted diff --git a/netwerk/protocol/http/nsHttpAtomList.h b/netwerk/protocol/http/nsHttpAtomList.h index 458c2fda78b2b..0799519a7b611 100644 --- a/netwerk/protocol/http/nsHttpAtomList.h +++ b/netwerk/protocol/http/nsHttpAtomList.h @@ -55,7 +55,6 @@ HTTP_ATOM(Expires, "Expires") HTTP_ATOM(From, "From") HTTP_ATOM(GlobalPrivacyControl, "Sec-GPC") HTTP_ATOM(Host, "Host") -HTTP_ATOM(Idempotency_Key, "Idempotency-Key") HTTP_ATOM(If, "If") HTTP_ATOM(If_Match, "If-Match") HTTP_ATOM(If_Modified_Since, "If-Modified-Since") diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index f9803fd6b4628..237fb6444283e 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -4118,14 +4118,17 @@ nsresult nsHttpChannel::OpenCacheEntry(bool isHttps) { // make sure we're not abusing this function MOZ_ASSERT(!mCacheEntry, "cache entry already open"); - if (!mRequestHead.IsGet() && !mRequestHead.IsHead() && - !mRequestHead.IsPost() && !mRequestHead.IsPatch()) { + + if (mRequestHead.IsPost()) { + // If the post id is already set then this is an attempt to replay + // a post transaction via the cache. Otherwise, we need a unique + // post id for this transaction. + if (mPostID == 0) mPostID = gHttpHandler->GenerateUniqueID(); + } else if (!mRequestHead.IsGet() && !mRequestHead.IsHead()) { // don't use the cache for other types of requests return NS_OK; } - MOZ_ASSERT_IF(mRequestHead.IsPost() || mRequestHead.IsPatch(), mPostID > 0); - return OpenCacheEntryInternal(isHttps); } @@ -7054,26 +7057,6 @@ nsresult nsHttpChannel::BeginConnect() { static_cast(rv))); } - if (mRequestHead.IsPost() || mRequestHead.IsPatch()) { - // If the post id is already set then this is an attempt to replay - // a post/patch transaction via the cache. Otherwise, we need a unique - // post id for this transaction. - if (mPostID == 0) { - mPostID = gHttpHandler->GenerateUniqueID(); - } - - if (StaticPrefs::network_http_idempotencyKey_enabled() && - !mRequestHead.HasHeader(nsHttp::Idempotency_Key)) { - // check if we need to add - // idempotency-key header - // See Bug 1830022 for more details - nsAutoCString key; - gHttpHandler->GenerateIdempotencyKeyForPost(mPostID, mLoadInfo, key); - MOZ_ALWAYS_SUCCEEDS( - mRequestHead.SetHeader(nsHttp::Idempotency_Key, key, false)); - } - } - // if this somehow fails we can go on without it Unused << gHttpHandler->AddConnectionHeader(&mRequestHead, mCaps); diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp index 0220119107aeb..95b5382f49c2c 100644 --- a/netwerk/protocol/http/nsHttpHandler.cpp +++ b/netwerk/protocol/http/nsHttpHandler.cpp @@ -30,8 +30,6 @@ #include "mozilla/ClearOnShutdown.h" #include "mozilla/Components.h" #include "mozilla/Printf.h" -#include "mozilla/RandomNum.h" -#include "mozilla/SHA1.h" #include "mozilla/Sprintf.h" #include "mozilla/StaticPrefs_network.h" #include "mozilla/StaticPrefs_privacy.h" @@ -77,7 +75,6 @@ #include "mozilla/DynamicFpiRedirectHeuristic.h" #include "mozilla/BasePrincipal.h" #include "mozilla/LazyIdleThread.h" -#include "mozilla/OriginAttributesHashKey.h" #include "mozilla/StaticPrefs_image.h" #include "mozilla/SyncRunnable.h" @@ -263,8 +260,6 @@ nsHttpHandler::nsHttpHandler() mImageAcceptHeader(ImageAcceptHeader()), mDocumentAcceptHeader(DocumentAcceptHeader()), mLastUniqueID(NowInSeconds()), - mIdempotencyKeySeed(mozilla::RandomUint64OrDie()), - mPrivateBrowsingIdempotencyKeySeed(mozilla::RandomUint64OrDie()), mDebugObservations(false), mEnableAltSvc(false), mEnableAltSvcOE(false), @@ -563,31 +558,6 @@ void nsHttpHandler::UpdateParentalControlsEnabled(bool waitForCompletion) { } } -void nsHttpHandler::GenerateIdempotencyKeyForPost(const uint32_t aPostId, - nsILoadInfo* aLoadInfo, - nsACString& aOutKey) { - MOZ_ASSERT(aLoadInfo); - OriginAttributes attrs = aLoadInfo->GetOriginAttributes(); - - // Create a SHA1 string using the origin attributes, session seed and the post - // id. - nsAutoCString sha1Input; - attrs.CreateSuffix(sha1Input); - sha1Input.AppendInt(aPostId); - sha1Input.AppendInt(attrs.IsPrivateBrowsing() - ? mPrivateBrowsingIdempotencyKeySeed - : mIdempotencyKeySeed); - SHA1Sum sha1; - SHA1Sum::Hash hash; - sha1.update((sha1Input.get()), sha1Input.Length()); - sha1.finish(hash); - uint64_t hashValue = BigEndian::readUint64(&hash); - - aOutKey.Append("\""); - aOutKey.AppendInt(hashValue); - aOutKey.Append("\""); -} - const nsCString& nsHttpHandler::Http3QlogDir() { if (StaticPrefs::network_http_http3_enable_qlog()) { return mHttp3QlogDir; diff --git a/netwerk/protocol/http/nsHttpHandler.h b/netwerk/protocol/http/nsHttpHandler.h index 79a176ba98e0d..d8ef1358734fd 100644 --- a/netwerk/protocol/http/nsHttpHandler.h +++ b/netwerk/protocol/http/nsHttpHandler.h @@ -242,10 +242,6 @@ class nsHttpHandler final : public nsIHttpProtocolHandler, uint32_t GenerateUniqueID() { return ++mLastUniqueID; } uint32_t SessionStartTime() { return mSessionStartTime; } - void GenerateIdempotencyKeyForPost(const uint32_t aPostId, - nsILoadInfo* aLoadInfo, - nsACString& aOutKey); - // // Connection management methods: // @@ -640,8 +636,6 @@ class nsHttpHandler final : public nsIHttpProtocolHandler, // useragent components nsCString mLegacyAppName{"Mozilla"}; nsCString mLegacyAppVersion{"5.0"}; - uint64_t mIdempotencyKeySeed; - uint64_t mPrivateBrowsingIdempotencyKeySeed; nsCString mPlatform; nsCString mOscpu; nsCString mMisc; diff --git a/netwerk/protocol/http/nsHttpRequestHead.cpp b/netwerk/protocol/http/nsHttpRequestHead.cpp index 9044068eb9431..0ce7a14f8aa21 100644 --- a/netwerk/protocol/http/nsHttpRequestHead.cpp +++ b/netwerk/protocol/http/nsHttpRequestHead.cpp @@ -296,8 +296,6 @@ void nsHttpRequestHead::ParseMethod(const nsCString& aRawMethod, aParsedMethod = kMethod_Get; } else if (!strcmp(aRawMethod.get(), "POST")) { aParsedMethod = kMethod_Post; - } else if (!strcmp(aRawMethod.get(), "PATCH")) { - aParsedMethod = kMethod_Patch; } else if (!strcmp(aRawMethod.get(), "OPTIONS")) { aParsedMethod = kMethod_Options; } else if (!strcmp(aRawMethod.get(), "CONNECT")) { diff --git a/netwerk/protocol/http/nsHttpRequestHead.h b/netwerk/protocol/http/nsHttpRequestHead.h index 02eba42876992..e308790bd4d4e 100644 --- a/netwerk/protocol/http/nsHttpRequestHead.h +++ b/netwerk/protocol/http/nsHttpRequestHead.h @@ -101,7 +101,6 @@ class nsHttpRequestHead { kMethod_Custom, kMethod_Get, kMethod_Post, - kMethod_Patch, kMethod_Options, kMethod_Connect, kMethod_Head, @@ -116,7 +115,6 @@ class nsHttpRequestHead { bool EqualsMethod(ParsedMethodType aType); bool IsGet() { return EqualsMethod(kMethod_Get); } bool IsPost() { return EqualsMethod(kMethod_Post); } - bool IsPatch() { return EqualsMethod(kMethod_Patch); } bool IsOptions() { return EqualsMethod(kMethod_Options); } bool IsConnect() { return EqualsMethod(kMethod_Connect); } bool IsHead() { return EqualsMethod(kMethod_Head); } diff --git a/netwerk/test/unit/test_bug1830022.js b/netwerk/test/unit/test_bug1830022.js deleted file mode 100644 index ddc881dd74660..0000000000000 --- a/netwerk/test/unit/test_bug1830022.js +++ /dev/null @@ -1,128 +0,0 @@ -"use strict"; - -const { HttpServer } = ChromeUtils.importESModule( - "resource://testing-common/httpd.sys.mjs" -); - -function makeChannel(url) { - return NetUtil.newChannel({ - uri: url, - loadUsingSystemPrincipal: true, - }).QueryInterface(Ci.nsIHttpChannel); -} - -ChromeUtils.defineLazyGetter(this, "URL", function () { - return "http://localhost:" + httpServer.identity.primaryPort; -}); - -let httpServer = null; - -function pathHandler(metadata, response) { - var body; - if (metadata.hasHeader("Idempotency-Key")) { - response.setStatusLine(metadata.httpVersion, 200, "OK"); - // echo back the header for further validation - let IDK = metadata.getHeader("Idempotency-Key"); - response.setHeader("Idempotency-Key", IDK, false); - body = "success"; - } else { - response.setStatusLine( - metadata.httpVersion, - 500, - "missing Idempotency-Key" - ); - body = "failed"; - } - response.bodyOutputStream.write(body, body.length); -} - -add_setup(async () => { - httpServer = new HttpServer(); - httpServer.registerPathHandler("/test_bug1830022", pathHandler); - httpServer.start(-1); - registerCleanupFunction(async () => await httpServer.stop()); -}); - -// tests if we add the header for the POST request -add_task(async function idempotency_key_addition_for_post() { - let chan = makeChannel(URL + "/test_bug1830022"); - chan.requestMethod = "POST"; - await new Promise(resolve => { - chan.asyncOpen(new ChannelListener(resolve)); - }); - Assert.notEqual(chan.getResponseHeader("Idempotency-Key"), ""); - Assert.notEqual(chan.getRequestHeader("Idempotency-Key"), ""); - Assert.equal( - chan.getResponseHeader("Idempotency-Key"), - chan.getRequestHeader("Idempotency-Key") - ); -}); - -// tests if we add the header for the PATCH request -add_task(async function idempotency_key_addition_for_patch() { - let chan = makeChannel(URL + "/test_bug1830022"); - chan.requestMethod = "PATCH"; - await new Promise(resolve => { - chan.asyncOpen(new ChannelListener(resolve)); - }); - Assert.notEqual(chan.getResponseHeader("Idempotency-Key"), ""); - Assert.notEqual(chan.getRequestHeader("Idempotency-Key"), ""); - Assert.equal( - chan.getResponseHeader("Idempotency-Key"), - chan.getRequestHeader("Idempotency-Key") - ); -}); - -// tests Idempotency key's uniqueness -add_task(async function idempotency_key_uniqueness() { - let chan = makeChannel(URL + "/test_bug1830022"); - chan.requestMethod = "POST"; - await new Promise(resolve => { - chan.asyncOpen(new ChannelListener(resolve)); - }); - - let chan2 = makeChannel(URL + "/test_bug1830022"); - chan2.requestMethod = "POST"; - await new Promise(resolve => { - chan2.asyncOpen(new ChannelListener(resolve)); - }); - - Assert.notEqual( - chan.getRequestHeader("Idempotency-Key"), - chan2.getRequestHeader("Idempotency-Key") - ); - - // tests if the Idempotency key is same for reposts - let chan3 = makeChannel(URL + "/test_bug1830022"); - chan3.requestMethod = "POST"; - await new Promise(resolve => { - chan3.asyncOpen(new ChannelListener(resolve)); - }); - - let cachekey = chan3.QueryInterface(Ci.nsICacheInfoChannel).cacheKey; - - let chan4 = makeChannel(URL + "/test_bug1830022"); - chan4.requestMethod = "POST"; - chan4.QueryInterface(Ci.nsICacheInfoChannel).cacheKey = cachekey; - await new Promise(resolve => { - chan4.asyncOpen(new ChannelListener(resolve)); - }); - - Assert.equal( - chan3.getRequestHeader("Idempotency-Key"), - chan4.getRequestHeader("Idempotency-Key") - ); -}); - -// tests if we do not overwrite the header that is set before opening the channel -add_task(async function idempotency_key_addition_for_post() { - // construct the channel - let chan = makeChannel(URL + "/test_bug1830022"); - chan.setRequestHeader("Idempotency-Key", "U-V-W-X-Y-Z", false); - chan.requestMethod = "POST"; - await new Promise(resolve => { - chan.asyncOpen(new ChannelListener(resolve)); - }); - Assert.equal(chan.getRequestHeader("Idempotency-Key"), "U-V-W-X-Y-Z"); - Assert.equal(chan.getResponseHeader("Idempotency-Key"), "U-V-W-X-Y-Z"); -}); diff --git a/netwerk/test/unit/xpcshell.toml b/netwerk/test/unit/xpcshell.toml index 6524a4b63d7c8..f752a9e1eca65 100644 --- a/netwerk/test/unit/xpcshell.toml +++ b/netwerk/test/unit/xpcshell.toml @@ -811,8 +811,6 @@ skip-if = ["os == 'win' && socketprocess_networking"] ["test_httpcancel.js"] -["test_bug1830022.js"] - ["test_https_rr_ech_prefs.js"] skip-if = ["os == 'android'"] run-sequentially = "node server exceptions dont replay well" From 76c592e5b4c7df2c11cde8a21478eef4d23f34a0 Mon Sep 17 00:00:00 2001 From: Hubert Boma Manilla Date: Thu, 12 Dec 2024 10:20:53 +0000 Subject: [PATCH 013/196] Bug 1936510 - [devtools] Remove a11y checks flag for browser_dbg-debug-line.js and browser_dbg-inspector-integration.js r=devtools-reviewers,nchevobbe Differential Revision: https://phabricator.services.mozilla.com/D231785 --- devtools/client/debugger/test/mochitest/browser_aj.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/devtools/client/debugger/test/mochitest/browser_aj.toml b/devtools/client/debugger/test/mochitest/browser_aj.toml index 29695c3a70c45..7e57c03cebbf0 100644 --- a/devtools/client/debugger/test/mochitest/browser_aj.toml +++ b/devtools/client/debugger/test/mochitest/browser_aj.toml @@ -142,7 +142,6 @@ fail-if = ["a11y_checks"] # Bug 1849028 clicked element may not be focusable and fail-if = ["a11y_checks"] # Bug 1849028 clicked element may not be focusable and/or labeled ["browser_dbg-debug-line.js"] -fail-if = ["a11y_checks"] # Bug 1849028 clicked element may not be focusable and/or labeled ["browser_dbg-debugger-buttons.js"] @@ -270,7 +269,6 @@ skip-if = ["true"] # bug 1607636 ["browser_dbg-inline-script-offset.js"] ["browser_dbg-inspector-integration.js"] -fail-if = ["a11y_checks"] # Bug 1849028 clicked element may not be focusable and/or labeled ["browser_dbg-integration-reloading-compressed-sourcemaps.js"] From 1358b28c43a460b1610d484aabc26bd8025c5e40 Mon Sep 17 00:00:00 2001 From: Marco Bonardo Date: Thu, 12 Dec 2024 10:48:14 +0000 Subject: [PATCH 014/196] Bug 1936072 - Allow loading SQLite extensions from Sqlite.sys.mjs. r=lina Differential Revision: https://phabricator.services.mozilla.com/D231676 --- toolkit/modules/Sqlite.sys.mjs | 53 ++++++++++++++----- toolkit/modules/tests/xpcshell/test_sqlite.js | 11 ++++ 2 files changed, 51 insertions(+), 13 deletions(-) diff --git a/toolkit/modules/Sqlite.sys.mjs b/toolkit/modules/Sqlite.sys.mjs index 691aab483a015..447ce5577b6ae 100644 --- a/toolkit/modules/Sqlite.sys.mjs +++ b/toolkit/modules/Sqlite.sys.mjs @@ -958,7 +958,9 @@ ConnectionData.prototype = Object.freeze({ function bindParam(obj, key, val) { let isBlob = - val && typeof val == "object" && val.constructor.name == "Uint8Array"; + val && + typeof val == "object" && + ["Uint8Array", "Uint8ClampedArray"].includes(val.constructor.name); let args = [key, val]; if (isBlob) { args.push(val.length); @@ -1080,14 +1082,14 @@ ConnectionData.prototype = Object.freeze({ switch (reason) { case Ci.mozIStorageStatementCallback.REASON_FINISHED: - case Ci.mozIStorageStatementCallback.REASON_CANCELED: + case Ci.mozIStorageStatementCallback.REASON_CANCELED: { // If there is an onRow handler, we always instead resolve to a // boolean indicating whether the onRow handler was called or not. let result = onRow ? handledRow : rows; deferred.resolve(result); break; - - case Ci.mozIStorageStatementCallback.REASON_ERROR: + } + case Ci.mozIStorageStatementCallback.REASON_ERROR: { let error = new Error( "Error(s) encountered during statement execution: " + errors.map(e => e.message).join(", ") @@ -1105,7 +1107,7 @@ ConnectionData.prototype = Object.freeze({ deferred.reject(error); break; - + } default: deferred.reject( new Error("Unknown completion reason code: " + reason) @@ -1267,6 +1269,10 @@ ConnectionData.prototype = Object.freeze({ * testDelayedOpenPromise -- (promise) Used by tests to delay the open * callback handling and execute code between asyncOpen and its callback. * + * extensions -- (array) Array of SQLite extension names that should be + * loaded for the connection. List of approved extensions is hardcoded in + * `mozStorageConnection`, no other extensions can be loaded. + * * FUTURE options to control: * * special named databases @@ -1404,14 +1410,41 @@ function openConnection(options) { reject(error); return; } + logger.debug("Connection opened"); + connection.QueryInterface(Ci.mozIStorageAsyncConnection); if (options.testDelayedOpenPromise) { await options.testDelayedOpenPromise; } + if (options.extensions) { + for (let extension of options.extensions) { + try { + await new Promise((resolve2, reject2) => + connection.loadExtension(extension, rv => { + if (Components.isSuccessCode(rv)) { + resolve2(); + } else { + reject2(rv); + } + }) + ); + } catch (ex) { + logger.error(`Could not load extension '${extension}'`, ex); + connection.asyncClose(); + reject( + new Error(`Could not load extension '${extension}'`, { + cause: ex, + }) + ); + return; + } + } + } + if (isClosed()) { - connection.QueryInterface(Ci.mozIStorageAsyncConnection).asyncClose(); + connection.asyncClose(); reject( new Error( "Sqlite.sys.mjs has been shutdown. Cannot open connection to: " + @@ -1422,13 +1455,7 @@ function openConnection(options) { } try { - resolve( - new OpenedConnection( - connection.QueryInterface(Ci.mozIStorageAsyncConnection), - identifier, - openedOptions - ) - ); + resolve(new OpenedConnection(connection, identifier, openedOptions)); } catch (ex) { logger.error("Could not open database", ex); connection.asyncClose(); diff --git a/toolkit/modules/tests/xpcshell/test_sqlite.js b/toolkit/modules/tests/xpcshell/test_sqlite.js index bea349ded4f64..eb808949dbe4c 100644 --- a/toolkit/modules/tests/xpcshell/test_sqlite.js +++ b/toolkit/modules/tests/xpcshell/test_sqlite.js @@ -1392,3 +1392,14 @@ add_task(async function test_pageSize() { ); await c.close(); }); + +add_task(async function test_loadExtension() { + await Assert.rejects( + getDummyDatabase("dummy", { extensions: ["dummy"] }), + /Could not load extension/, + "Check unsupported extension" + ); + let c = await getDummyDatabase("fts", { extensions: ["fts5"] }); + await c.execute("CREATE VIRTUAL TABLE test_fts USING fts5(body)"); + await c.close(); +}); From c360c991af124dc9ed510eec81ebff38e7df76c8 Mon Sep 17 00:00:00 2001 From: Tom Schuster Date: Thu, 12 Dec 2024 11:07:24 +0000 Subject: [PATCH 015/196] Bug 1936525 - Remove inline event handler from PageStyleMenu. r=Gijs Differential Revision: https://phabricator.services.mozilla.com/D231791 --- browser/base/content/browser-pagestyle.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/browser/base/content/browser-pagestyle.js b/browser/base/content/browser-pagestyle.js index 4266ffd69edb2..40234c659f1c5 100644 --- a/browser/base/content/browser-pagestyle.js +++ b/browser/base/content/browser-pagestyle.js @@ -61,9 +61,8 @@ var gPageStyleMenu = { "checked", !currentStyleSheet.disabled && !styleDisabled ); - menuItem.setAttribute( - "oncommand", - "gPageStyleMenu.switchStyleSheet(this.getAttribute('data'));" + menuItem.addEventListener("command", event => + this.switchStyleSheet(event.currentTarget.getAttribute("data")) ); menuPopup.appendChild(menuItem); currentStyleSheets[currentStyleSheet.title] = menuItem; From e07fd8ce22cf1f1c57164e989e9bcd384e66c527 Mon Sep 17 00:00:00 2001 From: sotaro Date: Thu, 12 Dec 2024 11:09:42 +0000 Subject: [PATCH 016/196] Bug 1936723 - Add max MacIOSurface size check in ExternalTextureMacIOSurface::Create() r=gfx-reviewers,lsalzman There was a case that ExternalTextureMacIOSurface::Create() received a size that is larger than max MacIOSurface size. Differential Revision: https://phabricator.services.mozilla.com/D231895 --- dom/webgpu/ExternalTextureMacIOSurface.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dom/webgpu/ExternalTextureMacIOSurface.cpp b/dom/webgpu/ExternalTextureMacIOSurface.cpp index 76bf751394537..d91c80f715146 100644 --- a/dom/webgpu/ExternalTextureMacIOSurface.cpp +++ b/dom/webgpu/ExternalTextureMacIOSurface.cpp @@ -24,6 +24,13 @@ UniquePtr ExternalTextureMacIOSurface::Create( return nullptr; } + if (aWidth > MacIOSurface::GetMaxWidth() || + aHeight > MacIOSurface::GetMaxHeight()) { + gfxCriticalNoteOnce << "Requested MacIOSurface is too large: (" << aWidth + << ", " << aHeight << ")"; + return nullptr; + } + RefPtr surface = MacIOSurface::CreateIOSurface(aWidth, aHeight, true); if (!surface) { From 0b23d368946c88e40b4d36720716e38892d87859 Mon Sep 17 00:00:00 2001 From: Mugurell Date: Thu, 12 Dec 2024 11:19:27 +0000 Subject: [PATCH 017/196] Bug 1936040 - Avoid setting dependencies through LoginSelectBarBehavior r=android-reviewers,avirvara Speculative fix for a crash from cycling dependencies in the layout. Differential Revision: https://phabricator.services.mozilla.com/D231911 --- .../org/mozilla/fenix/browser/LoginSelectBarBehavior.kt | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/LoginSelectBarBehavior.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/LoginSelectBarBehavior.kt index a6287094a7e45..a88ee00616b90 100644 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/LoginSelectBarBehavior.kt +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/LoginSelectBarBehavior.kt @@ -41,15 +41,12 @@ class LoginSelectBarBehavior( .firstOrNull() // It is possible that previous anchor's visibility is changed. - // The layout is updated and layoutDependsOn is called but onDependentViewChanged not. // We have to check here if a new anchor is available and reparent the logins bar. - // This check also ensures we are not positioning the login bar multiple times for the same anchor. - return if (anchorId != currentAnchorId) { + if (anchorId != currentAnchorId) { positionLoginBar(child, parent.children.firstOrNull { it.id == anchorId }) - true - } else { - false } + + return false } private fun positionLoginBar(loginBar: V, dependency: View?) { From f97c867a567770672694b9fbb0e13edb6218f982 Mon Sep 17 00:00:00 2001 From: Stanca Serban Date: Thu, 12 Dec 2024 14:12:08 +0200 Subject: [PATCH 018/196] Backed out changeset 5dc607c18a73 (bug 1936219) for causing bp-nu build bustages in Worker.cpp. CLOSED TREE --- dom/workers/Worker.cpp | 37 ++++++++++--------------------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/dom/workers/Worker.cpp b/dom/workers/Worker.cpp index 4c2d73d7a2aed..154042689f02a 100644 --- a/dom/workers/Worker.cpp +++ b/dom/workers/Worker.cpp @@ -39,39 +39,22 @@ already_AddRefed Worker::Constructor( nsCOMPtr globalObject = do_QueryInterface(aGlobal.GetAsSupports()); - nsPIDOMWindowInner* innerWindow = globalObject->GetAsInnerWindow(); - if (innerWindow && !innerWindow->IsCurrentInnerWindow()) { + if (globalObject->GetAsInnerWindow() && + !globalObject->GetAsInnerWindow()->IsCurrentInnerWindow()) { aRv.ThrowInvalidStateError( "Cannot create worker for a going to be discarded document"); return nullptr; } - // The spec only mentions Window and WorkerGlobalScope global objects, but - // Gecko can actually call the constructor with other ones, so we just skip - // trusted types handling in that case. - // https://html.spec.whatwg.org/multipage/workers.html#dedicated-workers-and-the-worker-interface - const nsAString* compliantString = nullptr; - bool performTrustedTypeConversion = innerWindow; - if (!performTrustedTypeConversion) { - if (JSObject* globalJSObject = globalObject->GetGlobalJSObject()) { - performTrustedTypeConversion = IsWorkerGlobal(globalJSObject); - } - } - if (performTrustedTypeConversion) { - constexpr nsLiteralString sink = u"Worker constructor"_ns; - Maybe compliantStringHolder; - compliantString = TrustedTypeUtils::GetTrustedTypesCompliantString( - aScriptURL, sink, kTrustedTypesOnlySinkGroup, *globalObject, - compliantStringHolder, aRv); - if (aRv.Failed()) { - return nullptr; - } - } else { - compliantString = aScriptURL.IsUSVString() - ? &aScriptURL.GetAsUSVString() - : &aScriptURL.GetAsTrustedScriptURL().mData; + constexpr nsLiteralString sink = u"Worker constructor"_ns; + Maybe compliantStringHolder; + const nsAString* compliantString = + TrustedTypeUtils::GetTrustedTypesCompliantString( + aScriptURL, sink, kTrustedTypesOnlySinkGroup, *globalObject, + compliantStringHolder, aRv); + if (aRv.Failed()) { + return nullptr; } - MOZ_ASSERT(compliantString); RefPtr workerPrivate = WorkerPrivate::Constructor( cx, *compliantString, false /* aIsChromeWorker */, WorkerKindDedicated, From 4e5f5c11e7658d74d6f5b79d466ad7897b183e5f Mon Sep 17 00:00:00 2001 From: Jan Varga Date: Thu, 12 Dec 2024 11:34:47 +0000 Subject: [PATCH 019/196] Bug 1936762 - ContextualIdentityService should check if a file exists before attempting to read from it; r=baku The ContextualIdentityService was attempting to read the containers.json file without verifying its existence. This caused warnings to appear in the console when the file was missing. Differential Revision: https://phabricator.services.mozilla.com/D231916 --- .../ContextualIdentityService.sys.mjs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/toolkit/components/contextualidentity/ContextualIdentityService.sys.mjs b/toolkit/components/contextualidentity/ContextualIdentityService.sys.mjs index 32f3577c93709..2f71fccf2eab6 100644 --- a/toolkit/components/contextualidentity/ContextualIdentityService.sys.mjs +++ b/toolkit/components/contextualidentity/ContextualIdentityService.sys.mjs @@ -442,12 +442,20 @@ _ContextualIdentityService.prototype = { } try { + // Check if the containers.json file exists before attempting to read + // from it (to avoid a warning in the console). If the file is missing, + // reset the service to its default state and return early. + let file = new lazy.FileUtils.File(this._path); + if (!file.exists()) { + this.resetDefault(); + return; + } // This reads the file and automatically detects the UTF-8 encoding. let inputStream = Cc[ "@mozilla.org/network/file-input-stream;1" ].createInstance(Ci.nsIFileInputStream); inputStream.init( - new lazy.FileUtils.File(this._path), + file, lazy.FileUtils.MODE_RDONLY, lazy.FileUtils.PERMS_FILE, 0 From ab546b1bc3fa6fc7adc4f61cc18880a224775171 Mon Sep 17 00:00:00 2001 From: sotaro Date: Thu, 12 Dec 2024 11:47:57 +0000 Subject: [PATCH 020/196] Bug 1936734 - Fix WebGPU OffscreenCanvas handling r=gfx-reviewers,lsalzman How to push remote texture was changed several times. OffscreenCanvasDisplayData::mOwnerId is not used anymore. And OffscreenCanvasDisplayData::mOwnerId blocks WebGPU OffscreenCanvas rendering. Differential Revision: https://phabricator.services.mozilla.com/D231903 --- dom/canvas/OffscreenCanvasDisplayHelper.cpp | 6 ------ dom/canvas/OffscreenCanvasDisplayHelper.h | 1 - dom/webgpu/CanvasContext.cpp | 1 - dom/webgpu/CommandEncoder.cpp | 4 +--- 4 files changed, 1 insertion(+), 11 deletions(-) diff --git a/dom/canvas/OffscreenCanvasDisplayHelper.cpp b/dom/canvas/OffscreenCanvasDisplayHelper.cpp index 646f25da78257..cf1cf94f9b434 100644 --- a/dom/canvas/OffscreenCanvasDisplayHelper.cpp +++ b/dom/canvas/OffscreenCanvasDisplayHelper.cpp @@ -193,12 +193,6 @@ bool OffscreenCanvasDisplayHelper::CommitFrameToCompositor( MaybeQueueInvalidateElement(); } - if (mData.mOwnerId.isSome()) { - // No need to update the ImageContainer as the presentation itself is - // handled in the compositor process. - return true; - } - if (!mImageContainer) { return false; } diff --git a/dom/canvas/OffscreenCanvasDisplayHelper.h b/dom/canvas/OffscreenCanvasDisplayHelper.h index 5f1acb69fabea..fc3091c6a0e6b 100644 --- a/dom/canvas/OffscreenCanvasDisplayHelper.h +++ b/dom/canvas/OffscreenCanvasDisplayHelper.h @@ -30,7 +30,6 @@ struct OffscreenCanvasDisplayData final { bool mIsOpaque = true; bool mIsAlphaPremult = true; mozilla::gl::OriginPos mOriginPos = gl::OriginPos::TopLeft; - Maybe mOwnerId; }; class OffscreenCanvasDisplayHelper final { diff --git a/dom/webgpu/CanvasContext.cpp b/dom/webgpu/CanvasContext.cpp index f8f62933467c8..d7b4c84f9ee1a 100644 --- a/dom/webgpu/CanvasContext.cpp +++ b/dom/webgpu/CanvasContext.cpp @@ -382,7 +382,6 @@ void CanvasContext::ForceNewFrame() { dom::OffscreenCanvasDisplayData data; data.mSize = mCanvasSize; data.mIsOpaque = false; - data.mOwnerId = mRemoteTextureOwnerId; mOffscreenCanvas->UpdateDisplayData(data); } } diff --git a/dom/webgpu/CommandEncoder.cpp b/dom/webgpu/CommandEncoder.cpp index 5c429511682c7..4b499de891f2d 100644 --- a/dom/webgpu/CommandEncoder.cpp +++ b/dom/webgpu/CommandEncoder.cpp @@ -97,9 +97,7 @@ void CommandEncoder::Cleanup() { void CommandEncoder::TrackPresentationContext(CanvasContext* aTargetContext) { if (aTargetContext) { - if (!aTargetContext->IsOffscreenCanvas()) { - mPresentationContexts.AppendElement(aTargetContext); - } + mPresentationContexts.AppendElement(aTargetContext); } } From 05a694625352cbec3d4f879fa432d2dca88e818c Mon Sep 17 00:00:00 2001 From: t-p-white Date: Thu, 12 Dec 2024 12:29:02 +0000 Subject: [PATCH 021/196] Bug 1936581 - Updated the privacy preferences state to the expected defaults. r=android-reviewers,rebecatudor273 Differential Revision: https://phabricator.services.mozilla.com/D231817 --- .../onboarding/store/PrivacyPreferencesStore.kt | 2 +- .../store/PrivacyPreferencesStoreTest.kt | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/onboarding/store/PrivacyPreferencesStore.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/onboarding/store/PrivacyPreferencesStore.kt index 366f5f5dc7e0b..58e4ecdbc3d3c 100644 --- a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/onboarding/store/PrivacyPreferencesStore.kt +++ b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/onboarding/store/PrivacyPreferencesStore.kt @@ -19,7 +19,7 @@ import mozilla.components.lib.state.UiStore */ data class PrivacyPreferencesState( val crashReportingEnabled: Boolean = false, - val usageDataEnabled: Boolean = false, + val usageDataEnabled: Boolean = true, val crashReportingChecked: Boolean = crashReportingEnabled, val usageDataChecked: Boolean = usageDataEnabled, ) : State diff --git a/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/onboarding/store/PrivacyPreferencesStoreTest.kt b/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/onboarding/store/PrivacyPreferencesStoreTest.kt index 040a72230f7a0..13032427e3b11 100644 --- a/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/onboarding/store/PrivacyPreferencesStoreTest.kt +++ b/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/onboarding/store/PrivacyPreferencesStoreTest.kt @@ -22,6 +22,10 @@ class PrivacyPreferencesStoreTest { val store = PrivacyPreferencesStore(initialState = state) safeDispatch(store, PrivacyPreferencesAction.Init) assertEquals(state, store.state) + assertFalse(state.crashReportingEnabled) + assertTrue(state.usageDataEnabled) + assertFalse(state.crashReportingChecked) + assertTrue(state.usageDataChecked) } @Test @@ -39,13 +43,13 @@ class PrivacyPreferencesStoreTest { @Test fun `WHEN the usage data updated action is dispatched THEN the state is updated to match`() { val store = PrivacyPreferencesStore(initialState = PrivacyPreferencesState()) - assertFalse(store.state.usageDataEnabled) - - safeDispatch(store, PrivacyPreferencesAction.UsageDataPreferenceUpdatedTo(true)) assertTrue(store.state.usageDataEnabled) safeDispatch(store, PrivacyPreferencesAction.UsageDataPreferenceUpdatedTo(false)) assertFalse(store.state.usageDataEnabled) + + safeDispatch(store, PrivacyPreferencesAction.UsageDataPreferenceUpdatedTo(true)) + assertTrue(store.state.usageDataEnabled) } @Test @@ -63,13 +67,13 @@ class PrivacyPreferencesStoreTest { @Test fun `WHEN the usage data checked action is dispatched THEN the state is updated to match`() { val store = PrivacyPreferencesStore(initialState = PrivacyPreferencesState()) - assertFalse(store.state.usageDataChecked) - - safeDispatch(store, PrivacyPreferencesAction.UsageDataUserChecked(true)) assertTrue(store.state.usageDataChecked) safeDispatch(store, PrivacyPreferencesAction.UsageDataUserChecked(false)) assertFalse(store.state.usageDataChecked) + + safeDispatch(store, PrivacyPreferencesAction.UsageDataUserChecked(true)) + assertTrue(store.state.usageDataChecked) } } From b6895e77bc50060ce4a93d6efdbea88110e9be1a Mon Sep 17 00:00:00 2001 From: Kelly Cochrane Date: Thu, 12 Dec 2024 12:57:41 +0000 Subject: [PATCH 022/196] Bug 1921060 - Implement full mute button spec r=desktop-theme-reviewers,tabbrowser-reviewers,dao,sessionstore-reviewers,sclements Differential Revision: https://phabricator.services.mozilla.com/D231182 --- .../sessionstore/SessionStore.sys.mjs | 4 -- browser/components/tabbrowser/content/tab.js | 52 ++++++-------- .../tabbrowser/content/tabbrowser.js | 16 ++--- browser/components/tabbrowser/content/tabs.js | 47 ------------- .../browser_mute_webAudio.js | 6 +- .../test/browser/tabs/browser_audioTabIcon.js | 5 -- browser/modules/ContentCrashHandlers.sys.mjs | 2 - .../tabbrowser/tab-audio-muted-small.svg | 4 +- .../tabbrowser/tab-audio-playing-small.svg | 7 +- browser/themes/shared/tabbrowser/tabs.css | 68 +++++++------------ .../tests/browser_tabIconOverlayPiP.js | 25 ++++--- 11 files changed, 75 insertions(+), 161 deletions(-) diff --git a/browser/components/sessionstore/SessionStore.sys.mjs b/browser/components/sessionstore/SessionStore.sys.mjs index 3ff446bab12b2..b6712cce7012e 100644 --- a/browser/components/sessionstore/SessionStore.sys.mjs +++ b/browser/components/sessionstore/SessionStore.sys.mjs @@ -3110,7 +3110,6 @@ var SessionStoreInternal = { * Tab reference */ resetBrowserToLazyState(aTab) { - const gBrowser = aTab.ownerGlobal.gBrowser; let browser = aTab.linkedBrowser; // Browser is already lazy so don't do anything. if (!browser.isConnected) { @@ -3124,7 +3123,6 @@ var SessionStoreInternal = { this._lastKnownFrameLoader.delete(browser.permanentKey); this._crashedBrowsers.delete(browser.permanentKey); aTab.removeAttribute("crashed"); - gBrowser.tabContainer.updateTabIndicatorAttr(aTab); let { userTypedValue = null, userTypedClear = 0 } = browser; let hasStartedLoad = browser.didStartLoadSinceLastUserTyping(); @@ -4821,7 +4819,6 @@ var SessionStoreInternal = { ); } - const gBrowser = aTab.ownerGlobal.gBrowser; let browser = aTab.linkedBrowser; if (!this._crashedBrowsers.has(browser.permanentKey)) { return; @@ -4841,7 +4838,6 @@ var SessionStoreInternal = { // a flash of the about:tabcrashed page after selecting // the revived tab. aTab.removeAttribute("crashed"); - gBrowser.tabContainer.updateTabIndicatorAttr(aTab); browser.loadURI(lazy.blankURI, { triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({ diff --git a/browser/components/tabbrowser/content/tab.js b/browser/components/tabbrowser/content/tab.js index 0a714df75d6ed..2169dd50dc2ac 100644 --- a/browser/components/tabbrowser/content/tab.js +++ b/browser/components/tabbrowser/content/tab.js @@ -23,15 +23,13 @@ +