[tbb-commits] [Git][tpo/applications/mullvad-browser][mullvad-browser-115.4.0esr-13.0-1] 7 commits: Bug 1738426 - Ignoring status 206 and vary header checking for opaque response...

richard (@richard) git at gitlab.torproject.org
Mon Oct 23 12:19:41 UTC 2023



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:${server.identity.primaryPort}/`;
+
   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/7898b29ae230f55339ce4db8d2e4b60585fc6c3e...d366918b618cea847ced7b253e2195f5b6390b60

-- 
View it on GitLab: https://gitlab.torproject.org/tpo/applications/mullvad-browser/-/compare/7898b29ae230f55339ce4db8d2e4b60585fc6c3e...d366918b618cea847ced7b253e2195f5b6390b60
You're receiving this email because of your account on gitlab.torproject.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.torproject.org/pipermail/tbb-commits/attachments/20231023/9412638b/attachment-0001.htm>


More information about the tbb-commits mailing list