ma1 pushed to branch base-browser-102.15.0esr-12.5-1 at The Tor Project / Applications / Tor Browser
Commits:
-
a416e80c
by Andrew Osmond at 2023-08-28T09:56:46+02:00
-
ceacede5
by Tim Huang at 2023-08-28T09:56:47+02:00
-
5b85dfb4
by Tim Huang at 2023-08-28T09:56:47+02:00
-
61b100bc
by hsingh at 2023-08-28T09:56:47+02:00
11 changed files:
- docshell/base/CanonicalBrowsingContext.cpp
- docshell/base/CanonicalBrowsingContext.h
- dom/media/gmp/GMPParent.cpp
- dom/media/gmp/GMPParent.h
- dom/media/gmp/GMPServiceParent.cpp
- dom/notification/Notification.cpp
- netwerk/protocol/http/HttpBaseChannel.cpp
- netwerk/protocol/http/HttpBaseChannel.h
- netwerk/protocol/http/HttpChannelParent.cpp
- netwerk/test/unit/test_cookiejars.js
- netwerk/test/unit_ipc/test_cookiejars_wrap.js
Changes:
... | ... | @@ -1351,6 +1351,11 @@ uint32_t CanonicalBrowsingContext::CountSiteOrigins( |
1351 | 1351 | return uniqueSiteOrigins.Count();
|
1352 | 1352 | }
|
1353 | 1353 | |
1354 | +/* static */
|
|
1355 | +bool CanonicalBrowsingContext::IsPrivateBrowsingActive() {
|
|
1356 | + return gNumberOfPrivateContexts > 0;
|
|
1357 | +}
|
|
1358 | + |
|
1354 | 1359 | void CanonicalBrowsingContext::UpdateMediaControlAction(
|
1355 | 1360 | const MediaControlAction& aAction) {
|
1356 | 1361 | if (IsDiscarded()) {
|
... | ... | @@ -201,6 +201,9 @@ class CanonicalBrowsingContext final : public BrowsingContext { |
201 | 201 | GlobalObject& aGlobal,
|
202 | 202 | const Sequence<mozilla::OwningNonNull<BrowsingContext>>& aRoots);
|
203 | 203 | |
204 | + // Return true if a private browsing session is active.
|
|
205 | + static bool IsPrivateBrowsingActive();
|
|
206 | + |
|
204 | 207 | // This function would propogate the action to its all child browsing contexts
|
205 | 208 | // in content processes.
|
206 | 209 | void UpdateMediaControlAction(const MediaControlAction& aAction);
|
... | ... | @@ -64,7 +64,7 @@ namespace mozilla::gmp { |
64 | 64 | #define __CLASS__ "GMPParent"
|
65 | 65 | |
66 | 66 | GMPParent::GMPParent()
|
67 | - : mState(GMPStateNotLoaded),
|
|
67 | + : mState(GMPState::NotLoaded),
|
|
68 | 68 | mPluginId(GeckoChildProcessHost::GetUniqueID()),
|
69 | 69 | mProcess(nullptr),
|
70 | 70 | mDeleteProcessOnlyOnUnload(false),
|
... | ... | @@ -270,7 +270,7 @@ RefPtr<GenericPromise> GMPParent::Init(GeckoMediaPluginServiceParent* aService, |
270 | 270 | }
|
271 | 271 | |
272 | 272 | void GMPParent::Crash() {
|
273 | - if (mState != GMPStateNotLoaded) {
|
|
273 | + if (mState != GMPState::NotLoaded) {
|
|
274 | 274 | Unused << SendCrashPluginNow();
|
275 | 275 | }
|
276 | 276 | }
|
... | ... | @@ -310,7 +310,7 @@ class NotifyGMPProcessLoadedTask : public Runnable { |
310 | 310 | nsresult GMPParent::LoadProcess() {
|
311 | 311 | MOZ_ASSERT(mDirectory, "Plugin directory cannot be NULL!");
|
312 | 312 | MOZ_ASSERT(GMPEventTarget()->IsOnCurrentThread());
|
313 | - MOZ_ASSERT(mState == GMPStateNotLoaded);
|
|
313 | + MOZ_ASSERT(mState == GMPState::NotLoaded);
|
|
314 | 314 | |
315 | 315 | nsAutoString path;
|
316 | 316 | if (NS_WARN_IF(NS_FAILED(mDirectory->GetPath(path)))) {
|
... | ... | @@ -388,7 +388,7 @@ nsresult GMPParent::LoadProcess() { |
388 | 388 | GMP_PARENT_LOG_DEBUG("%s: Sent StartPlugin to child process", __FUNCTION__);
|
389 | 389 | }
|
390 | 390 | |
391 | - mState = GMPStateLoaded;
|
|
391 | + mState = GMPState::Loaded;
|
|
392 | 392 | |
393 | 393 | // Hold a self ref while the child process is alive. This ensures that
|
394 | 394 | // during shutdown the GMPParent stays alive long enough to
|
... | ... | @@ -418,8 +418,8 @@ void GMPParent::CloseIfUnused() { |
418 | 418 | MOZ_ASSERT(GMPEventTarget()->IsOnCurrentThread());
|
419 | 419 | GMP_PARENT_LOG_DEBUG("%s", __FUNCTION__);
|
420 | 420 | |
421 | - if ((mDeleteProcessOnlyOnUnload || mState == GMPStateLoaded ||
|
|
422 | - mState == GMPStateUnloading) &&
|
|
421 | + if ((mDeleteProcessOnlyOnUnload || mState == GMPState::Loaded ||
|
|
422 | + mState == GMPState::Unloading) &&
|
|
423 | 423 | !IsUsed()) {
|
424 | 424 | // Ensure all timers are killed.
|
425 | 425 | for (uint32_t i = mTimers.Length(); i > 0; i--) {
|
... | ... | @@ -437,15 +437,16 @@ void GMPParent::CloseIfUnused() { |
437 | 437 | |
438 | 438 | void GMPParent::CloseActive(bool aDieWhenUnloaded) {
|
439 | 439 | MOZ_ASSERT(GMPEventTarget()->IsOnCurrentThread());
|
440 | - GMP_PARENT_LOG_DEBUG("%s: state %d", __FUNCTION__, mState);
|
|
440 | + GMP_PARENT_LOG_DEBUG("%s: state %u", __FUNCTION__,
|
|
441 | + uint32_t(GMPState(mState)));
|
|
441 | 442 | |
442 | 443 | if (aDieWhenUnloaded) {
|
443 | 444 | mDeleteProcessOnlyOnUnload = true; // don't allow this to go back...
|
444 | 445 | }
|
445 | - if (mState == GMPStateLoaded) {
|
|
446 | - mState = GMPStateUnloading;
|
|
446 | + if (mState == GMPState::Loaded) {
|
|
447 | + mState = GMPState::Unloading;
|
|
447 | 448 | }
|
448 | - if (mState != GMPStateNotLoaded && IsUsed()) {
|
|
449 | + if (mState != GMPState::NotLoaded && IsUsed()) {
|
|
449 | 450 | Unused << SendCloseActive();
|
450 | 451 | CloseIfUnused();
|
451 | 452 | }
|
... | ... | @@ -467,7 +468,7 @@ void GMPParent::Shutdown() { |
467 | 468 | }
|
468 | 469 | |
469 | 470 | MOZ_ASSERT(!IsUsed());
|
470 | - if (mState == GMPStateNotLoaded || mState == GMPStateClosing) {
|
|
471 | + if (mState == GMPState::NotLoaded || mState == GMPState::Closing) {
|
|
471 | 472 | return;
|
472 | 473 | }
|
473 | 474 | |
... | ... | @@ -480,7 +481,7 @@ void GMPParent::Shutdown() { |
480 | 481 | // Destroy ourselves and rise from the fire to save memory
|
481 | 482 | mService->ReAddOnGMPThread(self);
|
482 | 483 | } // else we've been asked to die and stay dead
|
483 | - MOZ_ASSERT(mState == GMPStateNotLoaded);
|
|
484 | + MOZ_ASSERT(mState == GMPState::NotLoaded);
|
|
484 | 485 | }
|
485 | 486 | |
486 | 487 | class NotifyGMPShutdownTask : public Runnable {
|
... | ... | @@ -524,10 +525,10 @@ void GMPParent::DeleteProcess() { |
524 | 525 | MOZ_ASSERT(GMPEventTarget()->IsOnCurrentThread());
|
525 | 526 | GMP_PARENT_LOG_DEBUG("%s", __FUNCTION__);
|
526 | 527 | |
527 | - if (mState != GMPStateClosing) {
|
|
528 | + if (mState != GMPState::Closing) {
|
|
528 | 529 | // Don't Close() twice!
|
529 | 530 | // Probably remove when bug 1043671 is resolved
|
530 | - mState = GMPStateClosing;
|
|
531 | + mState = GMPState::Closing;
|
|
531 | 532 | Close();
|
532 | 533 | }
|
533 | 534 | mProcess->Delete(NewRunnableMethod("gmp::GMPParent::ChildTerminated", this,
|
... | ... | @@ -536,7 +537,7 @@ void GMPParent::DeleteProcess() { |
536 | 537 | mProcess = nullptr;
|
537 | 538 | |
538 | 539 | #if defined(MOZ_WIDGET_ANDROID)
|
539 | - if (mState != GMPStateNotLoaded) {
|
|
540 | + if (mState != GMPState::NotLoaded) {
|
|
540 | 541 | nsCOMPtr<nsIEventTarget> launcherThread(GetIPCLauncher());
|
541 | 542 | MOZ_ASSERT(launcherThread);
|
542 | 543 | |
... | ... | @@ -553,7 +554,7 @@ void GMPParent::DeleteProcess() { |
553 | 554 | }
|
554 | 555 | #endif // defined(MOZ_WIDGET_ANDROID)
|
555 | 556 | |
556 | - mState = GMPStateNotLoaded;
|
|
557 | + mState = GMPState::NotLoaded;
|
|
557 | 558 | |
558 | 559 | nsCOMPtr<nsIRunnable> r =
|
559 | 560 | new NotifyGMPShutdownTask(NS_ConvertUTF8toUTF16(mNodeId));
|
... | ... | @@ -623,16 +624,18 @@ bool GMPCapability::Supports(const nsTArray<GMPCapability>& aCapabilities, |
623 | 624 | }
|
624 | 625 | |
625 | 626 | bool GMPParent::EnsureProcessLoaded() {
|
626 | - if (mState == GMPStateLoaded) {
|
|
627 | - return true;
|
|
628 | - }
|
|
629 | - if (mState == GMPStateClosing || mState == GMPStateUnloading) {
|
|
630 | - return false;
|
|
627 | + switch (mState) {
|
|
628 | + case GMPState::NotLoaded:
|
|
629 | + return NS_SUCCEEDED(LoadProcess());
|
|
630 | + case GMPState::Loaded:
|
|
631 | + return true;
|
|
632 | + case GMPState::Unloading:
|
|
633 | + case GMPState::Closing:
|
|
634 | + return false;
|
|
631 | 635 | }
|
632 | 636 | |
633 | - nsresult rv = LoadProcess();
|
|
634 | - |
|
635 | - return NS_SUCCEEDED(rv);
|
|
637 | + MOZ_ASSERT_UNREACHABLE("Unhandled GMPState!");
|
|
638 | + return false;
|
|
636 | 639 | }
|
637 | 640 | |
638 | 641 | void GMPParent::AddCrashAnnotations() {
|
... | ... | @@ -695,7 +698,7 @@ void GMPParent::ActorDestroy(ActorDestroyReason aWhy) { |
695 | 698 | }
|
696 | 699 | |
697 | 700 | // warn us off trying to close again
|
698 | - mState = GMPStateClosing;
|
|
701 | + mState = GMPState::Closing;
|
|
699 | 702 | mAbnormalShutdownInProgress = true;
|
700 | 703 | CloseActive(false);
|
701 | 704 | |
... | ... | @@ -704,7 +707,7 @@ void GMPParent::ActorDestroy(ActorDestroyReason aWhy) { |
704 | 707 | RefPtr<GMPParent> self(this);
|
705 | 708 | // Must not call Close() again in DeleteProcess(), as we'll recurse
|
706 | 709 | // infinitely if we do.
|
707 | - MOZ_ASSERT(mState == GMPStateClosing);
|
|
710 | + MOZ_ASSERT(mState == GMPState::Closing);
|
|
708 | 711 | DeleteProcess();
|
709 | 712 | // Note: final destruction will be Dispatched to ourself
|
710 | 713 | mService->ReAddOnGMPThread(self);
|
... | ... | @@ -20,6 +20,7 @@ |
20 | 20 | #include "nsString.h"
|
21 | 21 | #include "nsTArray.h"
|
22 | 22 | #include "nsIFile.h"
|
23 | +#include "mozilla/Atomics.h"
|
|
23 | 24 | #include "mozilla/MozPromise.h"
|
24 | 25 | |
25 | 26 | namespace mozilla::gmp {
|
... | ... | @@ -42,12 +43,7 @@ class GMPCapability { |
42 | 43 | const nsCString& aAPI, const nsCString& aTag);
|
43 | 44 | };
|
44 | 45 | |
45 | -enum GMPState {
|
|
46 | - GMPStateNotLoaded,
|
|
47 | - GMPStateLoaded,
|
|
48 | - GMPStateUnloading,
|
|
49 | - GMPStateClosing
|
|
50 | -};
|
|
46 | +enum class GMPState : uint32_t { NotLoaded, Loaded, Unloading, Closing };
|
|
51 | 47 | |
52 | 48 | class GMPContentParent;
|
53 | 49 | |
... | ... | @@ -194,7 +190,7 @@ class GMPParent final |
194 | 190 | uint32_t& aArchSet);
|
195 | 191 | #endif
|
196 | 192 | |
197 | - GMPState mState;
|
|
193 | + Atomic<GMPState> mState;
|
|
198 | 194 | nsCOMPtr<nsIFile> mDirectory; // plugin directory on disk
|
199 | 195 | nsString mName; // base name of plugin on disk, UTF-16 because used for paths
|
200 | 196 | nsCString mDisplayName; // name of plugin displayed to users
|
... | ... | @@ -643,7 +643,7 @@ void GeckoMediaPluginServiceParent::SendFlushFOGData( |
643 | 643 | MutexAutoLock lock(mMutex);
|
644 | 644 | |
645 | 645 | for (const RefPtr<GMPParent>& gmp : mPlugins) {
|
646 | - if (gmp->State() != GMPState::GMPStateLoaded) {
|
|
646 | + if (gmp->State() != GMPState::Loaded) {
|
|
647 | 647 | // Plugins that are not in the Loaded state have no process attached to
|
648 | 648 | // them, and any IPC we would attempt to send them would be ignored (or
|
649 | 649 | // result in a warning on debug builds).
|
... | ... | @@ -681,7 +681,7 @@ GeckoMediaPluginServiceParent::TestTriggerMetrics() { |
681 | 681 | {
|
682 | 682 | MutexAutoLock lock(mMutex);
|
683 | 683 | for (const RefPtr<GMPParent>& gmp : mPlugins) {
|
684 | - if (gmp->State() != GMPState::GMPStateLoaded) {
|
|
684 | + if (gmp->State() != GMPState::Loaded) {
|
|
685 | 685 | // Plugins that are not in the Loaded state have no process attached to
|
686 | 686 | // them, and any IPC we would attempt to send them would be ignored (or
|
687 | 687 | // result in a warning on debug builds).
|
... | ... | @@ -1003,7 +1003,7 @@ void GeckoMediaPluginServiceParent::RemoveOnGMPThread( |
1003 | 1003 | }
|
1004 | 1004 | |
1005 | 1005 | RefPtr<GMPParent> gmp = mPlugins[i];
|
1006 | - if (aDeleteFromDisk && gmp->State() != GMPStateNotLoaded) {
|
|
1006 | + if (aDeleteFromDisk && gmp->State() != GMPState::NotLoaded) {
|
|
1007 | 1007 | // We have to wait for the child process to release its lib handle
|
1008 | 1008 | // before we can delete the GMP.
|
1009 | 1009 | inUse = true;
|
... | ... | @@ -1014,7 +1014,7 @@ void GeckoMediaPluginServiceParent::RemoveOnGMPThread( |
1014 | 1014 | }
|
1015 | 1015 | }
|
1016 | 1016 | |
1017 | - if (gmp->State() == GMPStateNotLoaded || !aCanDefer) {
|
|
1017 | + if (gmp->State() == GMPState::NotLoaded || !aCanDefer) {
|
|
1018 | 1018 | // GMP not in use or shutdown is being forced; can shut it down now.
|
1019 | 1019 | deadPlugins.AppendElement(gmp);
|
1020 | 1020 | mPlugins.RemoveElementAt(i);
|
... | ... | @@ -478,6 +478,9 @@ NotificationPermissionRequest::Run() { |
478 | 478 | bool blocked = false;
|
479 | 479 | if (isSystem) {
|
480 | 480 | mPermission = NotificationPermission::Granted;
|
481 | + } else if (mPrincipal->GetPrivateBrowsingId() != 0) {
|
|
482 | + mPermission = NotificationPermission::Denied;
|
|
483 | + blocked = true;
|
|
481 | 484 | } else {
|
482 | 485 | // File are automatically granted permission.
|
483 | 486 | |
... | ... | @@ -1483,7 +1486,12 @@ already_AddRefed<Promise> Notification::RequestPermission( |
1483 | 1486 | aRv.Throw(NS_ERROR_UNEXPECTED);
|
1484 | 1487 | return nullptr;
|
1485 | 1488 | }
|
1489 | + |
|
1486 | 1490 | nsCOMPtr<nsIPrincipal> principal = sop->GetPrincipal();
|
1491 | + if (!principal) {
|
|
1492 | + aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
1493 | + return nullptr;
|
|
1494 | + }
|
|
1487 | 1495 | |
1488 | 1496 | RefPtr<Promise> promise = Promise::Create(window->AsGlobal(), aRv);
|
1489 | 1497 | if (aRv.Failed()) {
|
... | ... | @@ -1537,6 +1545,15 @@ NotificationPermission Notification::GetPermissionInternal(nsISupports* aGlobal, |
1537 | 1545 | }
|
1538 | 1546 | |
1539 | 1547 | nsCOMPtr<nsIPrincipal> principal = sop->GetPrincipal();
|
1548 | + if (!principal) {
|
|
1549 | + aRv.Throw(NS_ERROR_UNEXPECTED);
|
|
1550 | + return NotificationPermission::Denied;
|
|
1551 | + }
|
|
1552 | + |
|
1553 | + if (principal->GetPrivateBrowsingId() != 0) {
|
|
1554 | + return NotificationPermission::Denied;
|
|
1555 | + }
|
|
1556 | + |
|
1540 | 1557 | return GetPermissionInternal(principal, aRv);
|
1541 | 1558 | }
|
1542 | 1559 |
... | ... | @@ -2390,7 +2390,23 @@ void HttpBaseChannel::NotifySetCookie(const nsACString& aCookie) { |
2390 | 2390 | }
|
2391 | 2391 | |
2392 | 2392 | bool HttpBaseChannel::IsBrowsingContextDiscarded() const {
|
2393 | - return mLoadGroup && mLoadGroup->GetIsBrowsingContextDiscarded();
|
|
2393 | + // If there is no loadGroup attached to the current channel, we check the
|
|
2394 | + // global private browsing state for the private channel instead. For
|
|
2395 | + // non-private channel, we will always return false here.
|
|
2396 | + //
|
|
2397 | + // Note that we can only access the global private browsing state in the
|
|
2398 | + // parent process. So, we will fallback to just return false in the content
|
|
2399 | + // process.
|
|
2400 | + if (!mLoadGroup) {
|
|
2401 | + if (!XRE_IsParentProcess()) {
|
|
2402 | + return false;
|
|
2403 | + }
|
|
2404 | + |
|
2405 | + return mLoadInfo->GetOriginAttributes().mPrivateBrowsingId != 0 &&
|
|
2406 | + !dom::CanonicalBrowsingContext::IsPrivateBrowsingActive();
|
|
2407 | + }
|
|
2408 | + |
|
2409 | + return mLoadGroup->GetIsBrowsingContextDiscarded();
|
|
2394 | 2410 | }
|
2395 | 2411 | |
2396 | 2412 | // https://mikewest.github.io/corpp/#process-navigation-response
|
... | ... | @@ -619,6 +619,7 @@ class HttpBaseChannel : public nsHashPropertyBag, |
619 | 619 | |
620 | 620 | friend class PrivateBrowsingChannel<HttpBaseChannel>;
|
621 | 621 | friend class InterceptFailedOnStop;
|
622 | + friend class HttpChannelParent;
|
|
622 | 623 | |
623 | 624 | protected:
|
624 | 625 | // this section is for main-thread-only object
|
... | ... | @@ -18,6 +18,7 @@ |
18 | 18 | #include "mozilla/net/NeckoParent.h"
|
19 | 19 | #include "mozilla/InputStreamLengthHelper.h"
|
20 | 20 | #include "mozilla/IntegerPrintfMacros.h"
|
21 | +#include "mozilla/Preferences.h"
|
|
21 | 22 | #include "mozilla/ProfilerLabels.h"
|
22 | 23 | #include "mozilla/StoragePrincipalHelper.h"
|
23 | 24 | #include "mozilla/UniquePtr.h"
|
... | ... | @@ -2005,6 +2006,17 @@ void HttpChannelParent::SetCookie(nsCString&& aCookie) { |
2005 | 2006 | LOG(("HttpChannelParent::SetCookie [this=%p]", this));
|
2006 | 2007 | MOZ_ASSERT(!mAfterOnStartRequestBegun);
|
2007 | 2008 | MOZ_ASSERT(mCookie.IsEmpty());
|
2009 | + |
|
2010 | + // The loadGroup of the channel in the parent process could be null in the
|
|
2011 | + // XPCShell content process test, see test_cookiejars_wrap.js. In this case,
|
|
2012 | + // we cannot explicitly set the loadGroup for the parent channel because it's
|
|
2013 | + // created from the content process. To workaround this, we add a testing pref
|
|
2014 | + // to skip this check.
|
|
2015 | + if (!Preferences::GetBool(
|
|
2016 | + "network.cookie.skip_browsing_context_check_in_parent_for_testing") &&
|
|
2017 | + mChannel->IsBrowsingContextDiscarded()) {
|
|
2018 | + return;
|
|
2019 | + }
|
|
2008 | 2020 | mCookie = std::move(aCookie);
|
2009 | 2021 | }
|
2010 | 2022 |
... | ... | @@ -60,6 +60,23 @@ function setupChannel(path) { |
60 | 60 | });
|
61 | 61 | chan.loadInfo.originAttributes = tests[i].originAttributes;
|
62 | 62 | chan.QueryInterface(Ci.nsIHttpChannel);
|
63 | + |
|
64 | + let loadGroup = Cc["@mozilla.org/network/load-group;1"].createInstance(
|
|
65 | + Ci.nsILoadGroup
|
|
66 | + );
|
|
67 | + |
|
68 | + if (chan.loadInfo.originAttributes.privateBrowsingId == 0) {
|
|
69 | + loadGroup.notificationCallbacks = Cu.createLoadContext();
|
|
70 | + chan.loadGroup = loadGroup;
|
|
71 | + |
|
72 | + chan.notificationCallbacks = Cu.createLoadContext();
|
|
73 | + } else {
|
|
74 | + loadGroup.notificationCallbacks = Cu.createPrivateLoadContext();
|
|
75 | + chan.loadGroup = loadGroup;
|
|
76 | + |
|
77 | + chan.notificationCallbacks = Cu.createPrivateLoadContext();
|
|
78 | + }
|
|
79 | + |
|
63 | 80 | return chan;
|
64 | 81 | }
|
65 | 82 |
... | ... | @@ -4,6 +4,10 @@ function run_test() { |
4 | 4 | "network.cookieJarSettings.unblocked_for_testing",
|
5 | 5 | true
|
6 | 6 | );
|
7 | + Services.prefs.setBoolPref(
|
|
8 | + "network.cookie.skip_browsing_context_check_in_parent_for_testing",
|
|
9 | + true
|
|
10 | + );
|
|
7 | 11 | Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
|
8 | 12 | run_test_in_child("../unit/test_cookiejars.js");
|
9 | 13 | } |