richard pushed to branch mullvad-browser-115.4.0esr-13.0-1 at The Tor Project / Applications / Mullvad Browser
Commits: 00e0b1d4 by Eden Chuang at 2023-10-23T12:18:47+00:00 Bug 1738426 - Ignoring status 206 and vary header checking for opaque response in Cache API. r=asuth
Differential Revision: https://phabricator.services.mozilla.com/D186431 - - - - - 19e02723 by edgul at 2023-10-23T12:18:48+00:00 Bug 1802057 - Block the following characters from use in the cookie name in the cookie string: 0x3B (semi-colon), 0x3D (equals), and 0x7F (del) r=dveditz,cookie-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D182373
- - - - - 18e737f2 by Kelsey Gilbert at 2023-10-23T12:18:48+00:00 Bug 1819497 - Don't race on static bool for initialization. r=gfx-reviewers,aosmond
We could do non-racy static init here (e.g. with a static initializer self-calling-closure), but there doesn't seem to be a strong reason for this. Let's just use a switch and get robustness from -Werror=switch.
Differential Revision: https://phabricator.services.mozilla.com/D188054 - - - - - 57c1d25a by Mark Banner at 2023-10-23T12:18:48+00:00 Bug 1845752. r=ckerschb
Differential Revision: https://phabricator.services.mozilla.com/D186676 - - - - - cc34ac65 by Bob Owen at 2023-10-23T12:18:49+00:00 Bug 1850072: Initialize RecordedDrawTargetCreation::mHasExistingData. r=jrmuizel
This also specializes ElementStreamFormat for bool.
Differential Revision: https://phabricator.services.mozilla.com/D187794 - - - - - 75377f78 by Malte Juergens at 2023-10-23T12:18:49+00:00 Bug 1850200 - Add delay to HTTPS-Only "Continue to HTTPS Site" button r=freddyb
Differential Revision: https://phabricator.services.mozilla.com/D187887 - - - - - d366918b by Andreas Pehrson at 2023-10-23T12:18:49+00:00 Bug 1851803 - Introduce SourceMediaTrack::mDirectDisabledMode. r=karlt
Similar to MediaTrack::mDisabledMode, but this is for uses on the SourceMediaTrack producer thread. It is still signaled via a control message from the control thread to maintain order of operations, and is protected by the SourceMediaTrack mutex.
Differential Revision: https://phabricator.services.mozilla.com/D187554 - - - - -
18 changed files:
- dom/cache/TypeUtils.cpp - dom/canvas/WebGLContextExtensions.cpp - dom/media/MediaTrackGraph.cpp - dom/media/MediaTrackGraph.h - gfx/2d/RecordedEventImpl.h - gfx/2d/RecordingTypes.h - netwerk/cookie/CookieCommons.cpp - testing/web-platform/meta/cookies/name/name-ctl.html.ini - − testing/web-platform/meta/service-workers/cache-storage/cache-put.https.any.js.ini - toolkit/components/httpsonlyerror/content/errorpage.html - toolkit/components/httpsonlyerror/content/errorpage.js - toolkit/components/search/OpenSearchEngine.sys.mjs - toolkit/components/search/SearchEngine.sys.mjs - toolkit/components/search/SearchUtils.sys.mjs - toolkit/components/search/tests/xpcshell/data/iconsRedirect.sjs - toolkit/components/search/tests/xpcshell/test_opensearch_icons_invalid.js - toolkit/components/search/tests/xpcshell/test_webextensions_install.js - toolkit/modules/RemotePageAccessManager.sys.mjs
Changes:
===================================== dom/cache/TypeUtils.cpp ===================================== @@ -184,7 +184,7 @@ void TypeUtils::ToCacheResponseWithoutBody(CacheResponse& aOut, aOut.statusText() = aIn.GetUnfilteredStatusText(); RefPtr<InternalHeaders> headers = aIn.UnfilteredHeaders(); MOZ_DIAGNOSTIC_ASSERT(headers); - if (HasVaryStar(headers)) { + if (aIn.Type() != ResponseType::Opaque && HasVaryStar(headers)) { aRv.ThrowTypeError("Invalid Response object with a 'Vary: *' header."); return; }
===================================== dom/canvas/WebGLContextExtensions.cpp ===================================== @@ -17,15 +17,10 @@ namespace mozilla {
const char* GetExtensionName(const WebGLExtensionID ext) { - static EnumeratedArray<WebGLExtensionID, WebGLExtensionID::Max, const char*> - sExtensionNamesEnumeratedArray; - static bool initialized = false; - - if (!initialized) { - initialized = true; - + switch (ext) { #define WEBGL_EXTENSION_IDENTIFIER(x) \ - sExtensionNamesEnumeratedArray[WebGLExtensionID::x] = #x; + case WebGLExtensionID::x: \ + return #x;
WEBGL_EXTENSION_IDENTIFIER(ANGLE_instanced_arrays) WEBGL_EXTENSION_IDENTIFIER(EXT_blend_minmax) @@ -67,9 +62,11 @@ const char* GetExtensionName(const WebGLExtensionID ext) { WEBGL_EXTENSION_IDENTIFIER(WEBGL_provoking_vertex)
#undef WEBGL_EXTENSION_IDENTIFIER - }
- return sExtensionNamesEnumeratedArray[ext]; + case WebGLExtensionID::Max: + break; + } + MOZ_CRASH("bad WebGLExtensionID"); }
// ----------------------------
===================================== dom/media/MediaTrackGraph.cpp ===================================== @@ -145,6 +145,27 @@ class GraphKey final { nsTHashMap<nsGenericHashKey<GraphKey>, MediaTrackGraphImpl*> gGraphs; } // anonymous namespace
+static void ApplyTrackDisabling(DisabledTrackMode aDisabledMode, + MediaSegment* aSegment, + MediaSegment* aRawSegment) { + if (aDisabledMode == DisabledTrackMode::ENABLED) { + return; + } + if (aDisabledMode == DisabledTrackMode::SILENCE_BLACK) { + aSegment->ReplaceWithDisabled(); + if (aRawSegment) { + aRawSegment->ReplaceWithDisabled(); + } + } else if (aDisabledMode == DisabledTrackMode::SILENCE_FREEZE) { + aSegment->ReplaceWithNull(); + if (aRawSegment) { + aRawSegment->ReplaceWithNull(); + } + } else { + MOZ_CRASH("Unsupported mode"); + } +} + MediaTrackGraphImpl::~MediaTrackGraphImpl() { MOZ_ASSERT(mTracks.IsEmpty() && mSuspendedTracks.IsEmpty(), "All tracks should have been destroyed by messages from the main " @@ -2421,6 +2442,7 @@ RefPtr<GenericPromise> MediaTrack::RemoveListener(
void MediaTrack::AddDirectListenerImpl( already_AddRefed<DirectMediaTrackListener> aListener) { + MOZ_ASSERT(mGraph->OnGraphThread()); // Base implementation, for tracks that don't support direct track listeners. RefPtr<DirectMediaTrackListener> listener = aListener; listener->NotifyDirectListenerInstalled( @@ -2503,6 +2525,7 @@ void MediaTrack::RunAfterPendingUpdates( }
void MediaTrack::SetDisabledTrackModeImpl(DisabledTrackMode aMode) { + MOZ_ASSERT(mGraph->OnGraphThread()); MOZ_DIAGNOSTIC_ASSERT( aMode == DisabledTrackMode::ENABLED || mDisabledMode == DisabledTrackMode::ENABLED, @@ -2531,22 +2554,8 @@ void MediaTrack::SetDisabledTrackMode(DisabledTrackMode aMode) {
void MediaTrack::ApplyTrackDisabling(MediaSegment* aSegment, MediaSegment* aRawSegment) { - if (mDisabledMode == DisabledTrackMode::ENABLED) { - return; - } - if (mDisabledMode == DisabledTrackMode::SILENCE_BLACK) { - aSegment->ReplaceWithDisabled(); - if (aRawSegment) { - aRawSegment->ReplaceWithDisabled(); - } - } else if (mDisabledMode == DisabledTrackMode::SILENCE_FREEZE) { - aSegment->ReplaceWithNull(); - if (aRawSegment) { - aRawSegment->ReplaceWithNull(); - } - } else { - MOZ_CRASH("Unsupported mode"); - } + MOZ_ASSERT(mGraph->OnGraphThread()); + mozilla::ApplyTrackDisabling(mDisabledMode, aSegment, aRawSegment); }
void MediaTrack::AddMainThreadListener( @@ -2866,7 +2875,7 @@ TrackTime SourceMediaTrack::AppendData(MediaSegment* aSegment,
// Apply track disabling before notifying any consumers directly // or inserting into the graph - ApplyTrackDisabling(aSegment, aRawSegment); + mozilla::ApplyTrackDisabling(mDirectDisabledMode, aSegment, aRawSegment);
ResampleAudioToGraphSampleRate(aSegment);
@@ -2910,6 +2919,7 @@ void SourceMediaTrack::NotifyDirectConsumers(MediaSegment* aSegment) {
void SourceMediaTrack::AddDirectListenerImpl( already_AddRefed<DirectMediaTrackListener> aListener) { + MOZ_ASSERT(mGraph->OnGraphThread()); MutexAutoLock lock(mMutex);
RefPtr<DirectMediaTrackListener> listener = aListener; @@ -2979,6 +2989,7 @@ void SourceMediaTrack::AddDirectListenerImpl(
void SourceMediaTrack::RemoveDirectListenerImpl( DirectMediaTrackListener* aListener) { + mGraph->AssertOnGraphThreadOrNotRunning(); MutexAutoLock lock(mMutex); for (int32_t i = mDirectTrackListeners.Length() - 1; i >= 0; --i) { const RefPtr<DirectMediaTrackListener>& l = mDirectTrackListeners[i]; @@ -3008,17 +3019,20 @@ void SourceMediaTrack::End() { }
void SourceMediaTrack::SetDisabledTrackModeImpl(DisabledTrackMode aMode) { + MOZ_ASSERT(mGraph->OnGraphThread()); { MutexAutoLock lock(mMutex); + const DisabledTrackMode oldMode = mDirectDisabledMode; + const bool oldEnabled = oldMode == DisabledTrackMode::ENABLED; + const bool enabled = aMode == DisabledTrackMode::ENABLED; + mDirectDisabledMode = aMode; for (const auto& l : mDirectTrackListeners) { - DisabledTrackMode oldMode = mDisabledMode; - bool oldEnabled = oldMode == DisabledTrackMode::ENABLED; - if (!oldEnabled && aMode == DisabledTrackMode::ENABLED) { + if (!oldEnabled && enabled) { LOG(LogLevel::Debug, ("%p: SourceMediaTrack %p setting " "direct listener enabled", GraphImpl(), this)); l->DecreaseDisabled(oldMode); - } else if (oldEnabled && aMode != DisabledTrackMode::ENABLED) { + } else if (oldEnabled && !enabled) { LOG(LogLevel::Debug, ("%p: SourceMediaTrack %p setting " "direct listener disabled", GraphImpl(), this));
===================================== dom/media/MediaTrackGraph.h ===================================== @@ -652,18 +652,8 @@ class SourceMediaTrack : public MediaTrack { */ void End();
- // Overriding allows us to hold the mMutex lock while changing the track - // enable status void SetDisabledTrackModeImpl(DisabledTrackMode aMode) override;
- // Overriding allows us to ensure mMutex is locked while changing the track - // enable status - void ApplyTrackDisabling(MediaSegment* aSegment, - MediaSegment* aRawSegment = nullptr) override { - mMutex.AssertCurrentThreadOwns(); - MediaTrack::ApplyTrackDisabling(aSegment, aRawSegment); - } - uint32_t NumberOfChannels() const override;
void RemoveAllDirectListenersImpl() override; @@ -742,6 +732,11 @@ class SourceMediaTrack : public MediaTrack { // protected by mMutex float mVolume MOZ_GUARDED_BY(mMutex) = 1.0; UniquePtr<TrackData> mUpdateTrack MOZ_GUARDED_BY(mMutex); + // This track's associated disabled mode for uses on the producing thread. + // It can either by disabled by frames being replaced by black, or by + // retaining the previous frame. + DisabledTrackMode mDirectDisabledMode MOZ_GUARDED_BY(mMutex) = + DisabledTrackMode::ENABLED; nsTArray<RefPtr<DirectMediaTrackListener>> mDirectTrackListeners MOZ_GUARDED_BY(mMutex); };
===================================== gfx/2d/RecordedEventImpl.h ===================================== @@ -65,7 +65,7 @@ class RecordedDrawTargetCreation BackendType mBackendType; IntRect mRect; SurfaceFormat mFormat; - bool mHasExistingData; + bool mHasExistingData = false; RefPtr<SourceSurface> mExistingData;
private:
===================================== gfx/2d/RecordingTypes.h ===================================== @@ -24,6 +24,28 @@ struct ElementStreamFormat { aStream.read(reinterpret_cast<char*>(&aElement), sizeof(T)); } }; +template <class S> +struct ElementStreamFormat<S, bool> { + static void Write(S& aStream, const bool& aElement) { + char boolChar = aElement ? '\x01' : '\x00'; + aStream.write(&boolChar, sizeof(boolChar)); + } + static void Read(S& aStream, bool& aElement) { + char boolChar; + aStream.read(&boolChar, sizeof(boolChar)); + switch (boolChar) { + case '\x00': + aElement = false; + break; + case '\x01': + aElement = true; + break; + default: + aStream.SetIsBad(); + break; + } + } +};
template <class S, class T> void WriteElement(S& aStream, const T& aElement) {
===================================== netwerk/cookie/CookieCommons.cpp ===================================== @@ -200,9 +200,9 @@ bool CookieCommons::CheckNameAndValueSize(const CookieStruct& aCookieData) {
bool CookieCommons::CheckName(const CookieStruct& aCookieData) { const char illegalNameCharacters[] = { - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, - 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, - 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x00}; + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x3B, 0x3D, 0x7F, 0x00};
const auto* start = aCookieData.name().BeginReading(); const auto* end = aCookieData.name().EndReading();
===================================== testing/web-platform/meta/cookies/name/name-ctl.html.ini ===================================== @@ -11,36 +11,6 @@ [Cookie with %xd in name is rejected (DOM).] expected: FAIL
- [Cookie with %x7f in name is rejected (DOM).] - expected: FAIL - - [Cookie with %x0 in name is rejected or modified (HTTP).] - expected: FAIL - - [Cookie with %x1 in name is rejected (HTTP).] - expected: FAIL - - [Cookie with %x2 in name is rejected (HTTP).] - expected: FAIL - - [Cookie with %x3 in name is rejected (HTTP).] - expected: FAIL - - [Cookie with %x4 in name is rejected (HTTP).] - expected: FAIL - - [Cookie with %x5 in name is rejected (HTTP).] - expected: FAIL - - [Cookie with %x6 in name is rejected (HTTP).] - expected: FAIL - - [Cookie with %x7 in name is rejected (HTTP).] - expected: FAIL - - [Cookie with %x8 in name is rejected (HTTP).] - expected: FAIL - [Cookie with %x9 in name is accepted (HTTP).] expected: FAIL
===================================== testing/web-platform/meta/service-workers/cache-storage/cache-put.https.any.js.ini deleted ===================================== @@ -1,26 +0,0 @@ -[cache-put.https.any.serviceworker.html] - expected: - if (os == "android") and fission: [OK, TIMEOUT] - [Cache.put with a VARY:* opaque response should not reject] - expected: FAIL - - -[cache-put.https.any.sharedworker.html] - expected: - if (os == "android") and fission: [OK, TIMEOUT] - [Cache.put with a VARY:* opaque response should not reject] - expected: FAIL - - -[cache-put.https.any.html] - expected: - if (os == "android") and fission: [OK, TIMEOUT] - [Cache.put with a VARY:* opaque response should not reject] - expected: FAIL - - -[cache-put.https.any.worker.html] - expected: - if (os == "android") and fission: [OK, TIMEOUT] - [Cache.put with a VARY:* opaque response should not reject] - expected: FAIL
===================================== toolkit/components/httpsonlyerror/content/errorpage.html ===================================== @@ -67,6 +67,7 @@ <button id="openInsecure" data-l10n-id="about-httpsonly-button-continue-to-site" + inert ></button> </div> <div class="suggestion-box" hidden>
===================================== toolkit/components/httpsonlyerror/content/errorpage.js ===================================== @@ -34,6 +34,11 @@ function initPage() { .getElementById("openInsecure") .addEventListener("click", onOpenInsecureButtonClick);
+ const delay = RPMGetIntPref("security.dialog_enable_delay", 1000); + setTimeout(() => { + document.getElementById("openInsecure").removeAttribute("inert"); + }, delay); + if (window.top == window) { document .getElementById("goBack")
===================================== toolkit/components/search/OpenSearchEngine.sys.mjs ===================================== @@ -144,7 +144,12 @@ export class OpenSearchEngine extends SearchEngine {
lazy.logConsole.debug("_install: Downloading engine from:", loadURI.spec);
- var chan = lazy.SearchUtils.makeChannel(loadURI); + var chan = lazy.SearchUtils.makeChannel( + loadURI, + // OpenSearchEngine is loading a definition file for a search engine, + // TYPE_DOCUMENT captures that load best + Ci.nsIContentPolicy.TYPE_DOCUMENT + );
if (this._engineToUpdate && chan instanceof Ci.nsIHttpChannel) { var lastModified = this._engineToUpdate.getAttr("updatelastmodified");
===================================== toolkit/components/search/SearchEngine.sys.mjs ===================================== @@ -821,7 +821,10 @@ export class SearchEngine { this._hasPreferredIcon = isPreferred; };
- let chan = lazy.SearchUtils.makeChannel(uri); + let chan = lazy.SearchUtils.makeChannel( + uri, + Ci.nsIContentPolicy.TYPE_IMAGE + ); let listener = new lazy.SearchUtils.LoadListener( chan, /^image//,
===================================== toolkit/components/search/SearchUtils.sys.mjs ===================================== @@ -248,19 +248,24 @@ export var SearchUtils = { * * @param {string|nsIURI} url * The URL string from which to create an nsIChannel. + * @param {nsIContentPolicy} contentPolicyType + * The type of document being loaded. * @returns {nsIChannel} * an nsIChannel object, or null if the url is invalid. */ - makeChannel(url) { + makeChannel(url, contentPolicyType) { + if (!contentPolicyType) { + throw new Error("makeChannel called with invalid content policy type"); + } try { let uri = typeof url == "string" ? Services.io.newURI(url) : url; return Services.io.newChannelFromURI( uri, null /* loadingNode */, - Services.scriptSecurityManager.getSystemPrincipal(), + Services.scriptSecurityManager.createNullPrincipal({}), null /* triggeringPrincipal */, Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL, - Ci.nsIContentPolicy.TYPE_OTHER + contentPolicyType ); } catch (ex) {}
===================================== toolkit/components/search/tests/xpcshell/data/iconsRedirect.sjs ===================================== @@ -10,7 +10,7 @@ function handleRequest(request, response) { response.setStatusLine("1.1", 302, "Moved"); if (request.queryString == "type=invalid") { response.setHeader("Content-Type", "image/png", false); - response.setHeader("Location", "engine.xml", false); + response.setHeader("Location", "/head_search.js", false); } else { response.setHeader("Content-Type", "text/html", false); response.setHeader("Location", "remoteIcon.ico", false);
===================================== toolkit/components/search/tests/xpcshell/test_opensearch_icons_invalid.js ===================================== @@ -12,9 +12,11 @@ add_task(async function setup() { });
add_task(async function test_installedresourceicon() { + // Attempts to load a resource:// url as an icon. let engine1 = await SearchTestUtils.promiseNewSearchEngine({ url: `${gDataUrl}opensearch/resourceicon.xml`, }); + // Attempts to load a chrome:// url as an icon. let engine2 = await SearchTestUtils.promiseNewSearchEngine({ url: `${gDataUrl}opensearch/chromeicon.xml`, }); @@ -32,12 +34,13 @@ add_task(async function test_installedhttpplace() {
// The easiest way to test adding the icon is via a generated xml, otherwise // we have to somehow insert the address of the server into it. + // Attempts to load a non-image page into an image icon. let engine = await SearchTestUtils.promiseNewSearchEngine({ url: `${gDataUrl}data/engineMaker.sjs?` + JSON.stringify({ baseURL: gDataUrl, - image: "opensearch/resourceicon.xml", + image: "head_search.js", name: "invalidicon", method: "GET", }),
===================================== toolkit/components/search/tests/xpcshell/test_webextensions_install.js ===================================== @@ -5,6 +5,8 @@
const { promiseShutdownManager, promiseStartupManager } = AddonTestUtils;
+let gBaseUrl; + async function getEngineNames() { let engines = await Services.search.getEngines(); return engines.map(engine => engine._name); @@ -13,6 +15,8 @@ async function getEngineNames() { add_task(async function setup() { let server = useHttpServer(); server.registerContentType("sjs", "sjs"); + gBaseUrl = `http://localhost:$%7Bserver.identity.primaryPort%7D/%60; + await SearchTestUtils.useTestEngines("test-extensions"); await promiseStartupManager();
@@ -132,7 +136,7 @@ add_task(async function test_load_favicon_invalid() { // User installs a new search engine let extension = await SearchTestUtils.installSearchExtension( { - favicon_url: `${gDataUrl}engine.xml`, + favicon_url: `${gBaseUrl}/head_search.js`, }, { skipUnload: true } );
===================================== toolkit/modules/RemotePageAccessManager.sys.mjs ===================================== @@ -66,6 +66,7 @@ export let RemotePageAccessManager = { }, "about:httpsonlyerror": { RPMGetFormatURLPref: ["app.support.baseURL"], + RPMGetIntPref: ["security.dialog_enable_delay"], RPMSendAsyncMessage: ["goBack", "openInsecure"], RPMAddMessageListener: ["WWWReachable"], RPMTryPingSecureWWWLink: ["*"],
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/compare/789...
tor-commits@lists.torproject.org