ma1 pushed to branch tor-browser-102.15.0esr-12.5-1 at The Tor Project / Applications / Tor Browser
Commits:
- 
0db28aff
by Andrew Osmond at 2023-08-27T12:55:13+02:00
- 
8cab913f
by Tim Huang at 2023-08-27T15:46:35+02:00
- 
0293325a
by Tim Huang at 2023-08-27T15:46:35+02:00
- 
ee0e3ac2
by hsingh at 2023-08-27T17:55:05+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 |  } |