[tor-commits] [Git][tpo/applications/tor-browser][base-browser-115.13.0esr-13.5-1] 11 commits: Bug 1743329 - Handle ESC key to release pointer lock in parent process; r=smaug

ma1 (@ma1) git at gitlab.torproject.org
Tue Jul 9 14:35:18 UTC 2024



ma1 pushed to branch base-browser-115.13.0esr-13.5-1 at The Tor Project / Applications / Tor Browser


Commits:
7c8b558c by Edgar Chen at 2024-07-09T16:34:24+02:00
Bug 1743329 - Handle ESC key to release pointer lock in parent process; r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D211621
- - - - -
bdf856f3 by Edgar Chen at 2024-07-09T16:34:24+02:00
Bug 1743329 - Release pointer lock when xul popup is open; r=smaug,pbz

Differential Revision: https://phabricator.services.mozilla.com/D211620

- - - - -
0dd2cc3a by Edgar Chen at 2024-07-09T16:34:25+02:00
Bug 1743329 - Use nsMenuPopupFrame in GetVisiblePopups(); r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D211619

A further change was needed in nsCaret.cpp, see
https://gitlab.torproject.org/tpo/applications/tor-browser/-/merge_requests/1048#note_3046018

- - - - -
27ce49d5 by Otto Länd at 2024-07-09T16:34:25+02:00
Bug 1743329: apply code formatting via Lando

# ignore-this-changeset
- - - - -
bad880b6 by edgul at 2024-07-09T16:34:26+02:00
Bug 1879952 - Fix test expectations with samesite=lax turned on r=tschuster

Differential Revision: https://phabricator.services.mozilla.com/D201639
- - - - -
0165eb24 by edgul at 2024-07-09T16:34:26+02:00
Bug 1844827 - Added checks for sub-document navigations from cross-site to same-site in third-party checks when setting a cookie. r=cookie-reviewers,valentin,bvandersloot a=RyanVM

Differential Revision: https://phabricator.services.mozilla.com/D204074
- - - - -
c310d435 by Ed at 2024-07-09T16:34:26+02:00
Bug 1844827 - Update the cookie test expectations for iframe samesite r=cookie-reviewers,valentin a=RyanVM

Depends on D199770

Differential Revision: https://phabricator.services.mozilla.com/D199772
- - - - -
44cac309 by Julian Descottes at 2024-07-09T16:34:27+02:00
Bug 1880374 - Disable DNS prefetching if document nodePrincipal is systemPrincipal r=valentin

Differential Revision: https://phabricator.services.mozilla.com/D210830
- - - - -
537f4dc7 by Edgar Chen at 2024-07-09T16:34:27+02:00
Bug 1883396 - Exit fullscreen when two Escape keyup events occur in a short time; r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D209667

- - - - -
4f428345 by Jan de Mooij at 2024-07-09T16:34:28+02:00
Bug 1900523 - Don't use bailout data for JSJitToWasm frames. r=iain

Differential Revision: https://phabricator.services.mozilla.com/D212554
- - - - -
ff246121 by Jan de Mooij at 2024-07-09T16:34:28+02:00
Bug 1902983 - Don't use bailout data after iterating Wasm frames.  a=RyanVM

This is similar to bug 1900523, but the fix there was incomplete because the
`JSJitToWasm` frame type is only used when we go through the Wasm JIT entry
trampoline. Ion can also call Wasm functions directly and in that case the type
will be `FrameType::Exit`.

Original Revision: https://phabricator.services.mozilla.com/D214098

Differential Revision: https://phabricator.services.mozilla.com/D214375
- - - - -


22 changed files:

- browser/base/content/test/popupNotifications/browser_popupNotification_security_delay.js
- dom/base/PointerLockManager.cpp
- dom/base/PointerLockManager.h
- dom/html/HTMLDNSPrefetch.cpp
- dom/ipc/BrowserChild.cpp
- dom/ipc/BrowserChild.h
- dom/ipc/BrowserParent.cpp
- dom/ipc/PBrowser.ipdl
- + js/src/jit-test/tests/ion/bug1900523.js
- + js/src/jit-test/tests/ion/bug1902983.js
- js/src/jit/JSJitFrameIter.cpp
- js/src/jit/JSJitFrameIter.h
- layout/base/PresShell.cpp
- layout/base/PresShell.h
- layout/base/nsCaret.cpp
- layout/base/nsLayoutUtils.cpp
- layout/xul/nsXULPopupManager.cpp
- layout/xul/nsXULPopupManager.h
- modules/libpref/init/StaticPrefList.yaml
- netwerk/cookie/CookieService.cpp
- netwerk/cookie/CookieServiceChild.cpp
- testing/web-platform/meta/cookies/samesite/setcookie-navigation.https.html.ini


Changes:

=====================================
browser/base/content/test/popupNotifications/browser_popupNotification_security_delay.js
=====================================
@@ -558,5 +558,7 @@ add_task(async function test_notificationDuringFullScreenTransition() {
     info("Wait for full screen transition end.");
     await promiseFullScreenTransitionEnd;
     info("Full screen transition end");
+
+    await SpecialPowers.popPrefEnv();
   });
 });


=====================================
dom/base/PointerLockManager.cpp
=====================================
@@ -17,8 +17,10 @@
 #include "mozilla/dom/BrowsingContext.h"
 #include "mozilla/dom/Document.h"
 #include "mozilla/dom/Element.h"
+#include "mozilla/dom/PointerEventHandler.h"
 #include "mozilla/dom/WindowContext.h"
 #include "nsCOMPtr.h"
+#include "nsMenuPopupFrame.h"
 #include "nsSandboxFlags.h"
 
 namespace mozilla {
@@ -86,6 +88,25 @@ static void DispatchPointerLockError(Document* aTarget, const char* aMessage) {
                                   aMessage);
 }
 
+static bool IsPopupOpened() {
+  // Check if any popup is open.
+  nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
+  if (!pm) {
+    return false;
+  }
+
+  nsTArray<nsMenuPopupFrame*> popups;
+  pm->GetVisiblePopups(popups, true);
+
+  for (nsMenuPopupFrame* popup : popups) {
+    if (popup->GetPopupType() != widget::PopupType::Tooltip) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
 static const char* GetPointerLockError(Element* aElement, Element* aCurrentLock,
                                        bool aNoFocusCheck = false) {
   // Check if pointer lock pref is enabled
@@ -136,6 +157,10 @@ static const char* GetPointerLockError(Element* aElement, Element* aCurrentLock,
     }
   }
 
+  if (IsPopupOpened()) {
+    return "PointerLockDeniedFailedToLock";
+  }
+
   return nullptr;
 }
 
@@ -167,6 +192,14 @@ void PointerLockManager::RequestLock(Element* aElement,
 
 /* static */
 void PointerLockManager::Unlock(Document* aDoc) {
+  if (sLockedRemoteTarget) {
+    MOZ_ASSERT(XRE_IsParentProcess());
+    MOZ_ASSERT(!sIsLocked);
+    Unused << sLockedRemoteTarget->SendReleasePointerLock();
+    sLockedRemoteTarget = nullptr;
+    return;
+  }
+
   if (!sIsLocked) {
     return;
   }
@@ -311,14 +344,24 @@ bool PointerLockManager::IsInLockContext(BrowsingContext* aContext) {
 }
 
 /* static */
-bool PointerLockManager::SetLockedRemoteTarget(BrowserParent* aBrowserParent) {
+void PointerLockManager::SetLockedRemoteTarget(BrowserParent* aBrowserParent,
+                                               nsACString& aError) {
   MOZ_ASSERT(XRE_IsParentProcess());
   if (sLockedRemoteTarget) {
-    return sLockedRemoteTarget == aBrowserParent;
+    if (sLockedRemoteTarget != aBrowserParent) {
+      aError = "PointerLockDeniedInUse"_ns;
+    }
+    return;
+  }
+
+  // Check if any popup is open.
+  if (IsPopupOpened()) {
+    aError = "PointerLockDeniedFailedToLock"_ns;
+    return;
   }
 
   sLockedRemoteTarget = aBrowserParent;
-  return true;
+  PointerEventHandler::ReleaseAllPointerCaptureRemoteTarget();
 }
 
 /* static */


=====================================
dom/base/PointerLockManager.h
=====================================
@@ -47,7 +47,8 @@ class PointerLockManager final {
 
   // Set/release pointer lock remote target. Should only be called in parent
   // process.
-  static bool SetLockedRemoteTarget(dom::BrowserParent* aBrowserParent);
+  static void SetLockedRemoteTarget(dom::BrowserParent* aBrowserParent,
+                                    nsACString& aError);
   static void ReleaseLockedRemoteTarget(dom::BrowserParent* aBrowserParent);
 
  private:


=====================================
dom/html/HTMLDNSPrefetch.cpp
=====================================
@@ -180,6 +180,13 @@ static bool EnsureDNSService() {
 }
 
 bool HTMLDNSPrefetch::IsAllowed(Document* aDocument) {
+  // Do not use prefetch if the document's node principal is the system
+  // principal.
+  nsCOMPtr<nsIPrincipal> principal = aDocument->NodePrincipal();
+  if (principal->IsSystemPrincipal()) {
+    return false;
+  }
+
   // There is no need to do prefetch on non UI scenarios such as XMLHttpRequest.
   return aDocument->IsDNSPrefetchAllowed() && aDocument->GetWindow();
 }


=====================================
dom/ipc/BrowserChild.cpp
=====================================
@@ -39,6 +39,7 @@
 #include "mozilla/MouseEvents.h"
 #include "mozilla/NativeKeyBindingsType.h"
 #include "mozilla/NullPrincipal.h"
+#include "mozilla/PointerLockManager.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/PresShell.h"
 #include "mozilla/ProcessHangMonitor.h"
@@ -3184,6 +3185,11 @@ mozilla::ipc::IPCResult BrowserChild::RecvReleaseAllPointerCapture() {
   return IPC_OK();
 }
 
+mozilla::ipc::IPCResult BrowserChild::RecvReleasePointerLock() {
+  PointerLockManager::Unlock();
+  return IPC_OK();
+}
+
 PPaymentRequestChild* BrowserChild::AllocPPaymentRequestChild() {
   MOZ_CRASH(
       "We should never be manually allocating PPaymentRequestChild actors");


=====================================
dom/ipc/BrowserChild.h
=====================================
@@ -696,6 +696,8 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
 
   mozilla::ipc::IPCResult RecvReleaseAllPointerCapture();
 
+  mozilla::ipc::IPCResult RecvReleasePointerLock();
+
  private:
   void HandleDoubleTap(const CSSPoint& aPoint, const Modifiers& aModifiers,
                        const ScrollableLayerGuid& aGuid);


=====================================
dom/ipc/BrowserParent.cpp
=====================================
@@ -4067,15 +4067,14 @@ static BrowserParent* GetTopLevelBrowserParent(BrowserParent* aBrowserParent) {
 
 mozilla::ipc::IPCResult BrowserParent::RecvRequestPointerLock(
     RequestPointerLockResolver&& aResolve) {
-  nsCString error;
   if (sTopLevelWebFocus != GetTopLevelBrowserParent(this)) {
-    error = "PointerLockDeniedNotFocused";
-  } else if (!PointerLockManager::SetLockedRemoteTarget(this)) {
-    error = "PointerLockDeniedInUse";
-  } else {
-    PointerEventHandler::ReleaseAllPointerCaptureRemoteTarget();
+    aResolve("PointerLockDeniedNotFocused"_ns);
+    return IPC_OK();
   }
-  aResolve(error);
+
+  nsCString error;
+  PointerLockManager::SetLockedRemoteTarget(this, error);
+  aResolve(std::move(error));
   return IPC_OK();
 }
 


=====================================
dom/ipc/PBrowser.ipdl
=====================================
@@ -557,18 +557,18 @@ parent:
 
     async ImageLoadComplete(nsresult aResult);
 
-    /**
-     * Child informs the parent that a pointer lock has requested/released.
-     */
-    async RequestPointerLock() returns (nsCString error);
-    async ReleasePointerLock();
-
     /**
      * Child informs the parent that a pointer capture has requested/released.
      */
     async RequestPointerCapture(uint32_t aPointerId) returns (bool aSuccess);
     async ReleasePointerCapture(uint32_t aPointerId);
 
+both:
+    /**
+     * informs that a pointer lock has released.
+     */
+    async ReleasePointerLock();
+
 child:
     async NativeSynthesisResponse(uint64_t aObserverId, nsCString aResponse);
     async UpdateSHistory();


=====================================
js/src/jit-test/tests/ion/bug1900523.js
=====================================
@@ -0,0 +1,28 @@
+// |jit-test| --fast-warmup; --no-threads; skip-if: !wasmIsSupported()
+function f1() {
+  Promise.allSettled().catch(e => null);
+  do {
+    f2(10n, -1n);
+    try {
+      f2(-2147483648n);
+    } catch {}
+  } while (!inIon());
+}
+function f2(x, y) {
+  const z = x >> x;
+  z <= z ? z : z;
+  y ^ y;
+}
+const binary = wasmTextToBinary(`
+  (module
+    (import "m" "f" (func $f))
+    (func (export "test")
+      (call $f)
+    )
+  )
+`);
+const mod = new WebAssembly.Module(binary);
+const inst = new WebAssembly.Instance(mod, {"m": {"f": f1}});
+for (let i = 0; i < 6; i++) {
+  inst.exports.test();
+}


=====================================
js/src/jit-test/tests/ion/bug1902983.js
=====================================
@@ -0,0 +1,24 @@
+// |jit-test| --fast-warmup; --gc-zeal=21,100; skip-if: !wasmIsSupported()
+let counter = 0;
+function g() {
+    counter++;
+    const y = BigInt.asIntN(counter, -883678545n);
+    const z = y >> y;
+    BigInt.asUintN(2 ** counter, 883678545n);
+    try { g(); } catch (e) { }
+}
+function f() {
+    for (let i = 0; i < 5; i++) {
+        for (let j = 0; j < 30; j++) { }
+        Promise.allSettled().catch(e => null);
+        counter = 0;
+        g();
+    }
+}
+const binary = wasmTextToBinary(`(module (import "m" "f" (func $f)) (func (export "test") (call $f)))`);
+const mod = new WebAssembly.Module(binary);
+const inst = new WebAssembly.Instance(mod, { m: { f: f } });
+for (let i = 0; i < 100; i++) { }
+for (let i = 0; i < 5; i++) {
+    inst.exports.test();
+}


=====================================
js/src/jit/JSJitFrameIter.cpp
=====================================
@@ -26,22 +26,29 @@ using namespace js;
 using namespace js::jit;
 
 JSJitFrameIter::JSJitFrameIter(const JitActivation* activation)
-    : JSJitFrameIter(activation, FrameType::Exit, activation->jsExitFP()) {}
-
-JSJitFrameIter::JSJitFrameIter(const JitActivation* activation,
-                               FrameType frameType, uint8_t* fp)
-    : current_(fp),
-      type_(frameType),
-      resumePCinCurrentFrame_(nullptr),
-      cachedSafepointIndex_(nullptr),
+    : current_(activation->jsExitFP()),
+      type_(FrameType::Exit),
       activation_(activation) {
-  MOZ_ASSERT(type_ == FrameType::JSJitToWasm || type_ == FrameType::Exit);
+  // If we're currently performing a bailout, we have to use the activation's
+  // bailout data when we start iterating over the activation's frames.
   if (activation_->bailoutData()) {
     current_ = activation_->bailoutData()->fp();
     type_ = FrameType::Bailout;
-  } else {
-    MOZ_ASSERT(!TlsContext.get()->inUnsafeCallWithABI);
   }
+  MOZ_ASSERT(!TlsContext.get()->inUnsafeCallWithABI);
+}
+
+JSJitFrameIter::JSJitFrameIter(const JitActivation* activation,
+                               FrameType frameType, uint8_t* fp)
+    : current_(fp), type_(frameType), activation_(activation) {
+  // This constructor is only used when resuming iteration after iterating Wasm
+  // frames in the same JitActivation so ignore activation_->bailoutData().
+  //
+  // Note: FrameType::JSJitToWasm is used for JIT => Wasm calls through the Wasm
+  // JIT entry trampoline. FrameType::Exit is used for direct Ion => Wasm calls.
+  MOZ_ASSERT(fp > activation->jsOrWasmExitFP());
+  MOZ_ASSERT(type_ == FrameType::JSJitToWasm || type_ == FrameType::Exit);
+  MOZ_ASSERT(!TlsContext.get()->inUnsafeCallWithABI);
 }
 
 bool JSJitFrameIter::checkInvalidation() const {


=====================================
js/src/jit/JSJitFrameIter.h
=====================================
@@ -111,14 +111,14 @@ class JSJitFrameIter {
  protected:
   uint8_t* current_;
   FrameType type_;
-  uint8_t* resumePCinCurrentFrame_;
+  uint8_t* resumePCinCurrentFrame_ = nullptr;
 
   // Size of the current Baseline frame. Equivalent to
   // BaselineFrame::debugFrameSize_ in debug builds.
   mozilla::Maybe<uint32_t> baselineFrameSize_;
 
  private:
-  mutable const SafepointIndex* cachedSafepointIndex_;
+  mutable const SafepointIndex* cachedSafepointIndex_ = nullptr;
   const JitActivation* activation_;
 
   void dumpBaseline() const;


=====================================
layout/base/PresShell.cpp
=====================================
@@ -8463,24 +8463,46 @@ void PresShell::EventHandler::MaybeHandleKeyboardEventBeforeDispatch(
 
     // The event listeners in chrome can prevent this ESC behavior by
     // calling prevent default on the preceding keydown/press events.
-    if (!mPresShell->mIsLastChromeOnlyEscapeKeyConsumed &&
-        aKeyboardEvent->mMessage == eKeyUp) {
-      // ESC key released while in DOM fullscreen mode.
-      // Fully exit all browser windows and documents from
-      // fullscreen mode.
-      Document::AsyncExitFullscreen(nullptr);
+    if (aKeyboardEvent->mMessage == eKeyUp) {
+      bool shouldExitFullscreen =
+          !mPresShell->mIsLastChromeOnlyEscapeKeyConsumed;
+      if (!shouldExitFullscreen) {
+        if (mPresShell->mLastConsumedEscapeKeyUpForFullscreen &&
+            (aKeyboardEvent->mTimeStamp -
+             mPresShell->mLastConsumedEscapeKeyUpForFullscreen) <=
+                TimeDuration::FromMilliseconds(
+                    StaticPrefs::
+                        dom_fullscreen_force_exit_on_multiple_escape_interval())) {
+          shouldExitFullscreen = true;
+          mPresShell->mLastConsumedEscapeKeyUpForFullscreen = TimeStamp();
+        } else {
+          mPresShell->mLastConsumedEscapeKeyUpForFullscreen =
+              aKeyboardEvent->mTimeStamp;
+        }
+      }
+
+      if (shouldExitFullscreen) {
+        // ESC key released while in DOM fullscreen mode.
+        // Fully exit all browser windows and documents from
+        // fullscreen mode.
+        Document::AsyncExitFullscreen(nullptr);
+      }
     }
   }
 
-  nsCOMPtr<Document> pointerLockedDoc = PointerLockManager::GetLockedDocument();
-  if (!mPresShell->mIsLastChromeOnlyEscapeKeyConsumed && pointerLockedDoc) {
-    // XXX See above comment to understand the reason why this needs
-    //     to claim that the Escape key event is consumed by content
-    //     even though it will be dispatched only into chrome.
-    aKeyboardEvent->PreventDefaultBeforeDispatch(CrossProcessForwarding::eStop);
-    aKeyboardEvent->mFlags.mOnlyChromeDispatch = true;
-    if (aKeyboardEvent->mMessage == eKeyUp) {
-      PointerLockManager::Unlock();
+  if (XRE_IsParentProcess() &&
+      !mPresShell->mIsLastChromeOnlyEscapeKeyConsumed) {
+    if (PointerLockManager::GetLockedRemoteTarget() ||
+        PointerLockManager::IsLocked()) {
+      // XXX See above comment to understand the reason why this needs
+      //     to claim that the Escape key event is consumed by content
+      //     even though it will be dispatched only into chrome.
+      aKeyboardEvent->PreventDefaultBeforeDispatch(
+          CrossProcessForwarding::eStop);
+      aKeyboardEvent->mFlags.mOnlyChromeDispatch = true;
+      if (aKeyboardEvent->mMessage == eKeyUp) {
+        PointerLockManager::Unlock();
+      }
     }
   }
 }


=====================================
layout/base/PresShell.h
=====================================
@@ -3209,6 +3209,10 @@ class PresShell final : public nsStubDocumentObserver,
   bool mProcessingReflowCommands : 1;
   bool mPendingDidDoReflow : 1;
 
+  // The last TimeStamp when the keyup event did not exit fullscreen because it
+  // was consumed.
+  TimeStamp mLastConsumedEscapeKeyUpForFullscreen;
+
   struct CapturingContentInfo final {
     CapturingContentInfo()
         : mRemoteTarget(nullptr),


=====================================
layout/base/nsCaret.cpp
=====================================
@@ -855,7 +855,7 @@ size_t nsCaret::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
 bool nsCaret::IsMenuPopupHidingCaret() {
   // Check if there are open popups.
   nsXULPopupManager* popMgr = nsXULPopupManager::GetInstance();
-  nsTArray<nsIFrame*> popups;
+  nsTArray<nsMenuPopupFrame*> popups;
   popMgr->GetVisiblePopups(popups);
 
   if (popups.Length() == 0)
@@ -873,7 +873,7 @@ bool nsCaret::IsMenuPopupHidingCaret() {
   // If there's a menu popup open before the popup with
   // the caret, don't show the caret.
   for (uint32_t i = 0; i < popups.Length(); i++) {
-    nsMenuPopupFrame* popupFrame = static_cast<nsMenuPopupFrame*>(popups[i]);
+    nsMenuPopupFrame* popupFrame = popups[i];
     nsIContent* popupContent = popupFrame->GetContent();
 
     if (caretContent->IsInclusiveDescendantOf(popupContent)) {


=====================================
layout/base/nsLayoutUtils.cpp
=====================================
@@ -138,6 +138,7 @@
 #include "nsIScrollableFrame.h"
 #include "nsIWidget.h"
 #include "nsListControlFrame.h"
+#include "nsMenuPopupFrame.h"
 #include "nsPIDOMWindow.h"
 #include "nsPlaceholderFrame.h"
 #include "nsPresContext.h"
@@ -1757,10 +1758,10 @@ nsIFrame* nsLayoutUtils::GetPopupFrameForPoint(
   if (!pm) {
     return nullptr;
   }
-  nsTArray<nsIFrame*> popups;
+  nsTArray<nsMenuPopupFrame*> popups;
   pm->GetVisiblePopups(popups);
   // Search from top to bottom
-  for (nsIFrame* popup : popups) {
+  for (nsMenuPopupFrame* popup : popups) {
     if (popup->PresContext()->GetRootPresContext() != aRootPresContext) {
       continue;
     }


=====================================
layout/xul/nsXULPopupManager.cpp
=====================================
@@ -53,6 +53,7 @@
 #include "mozilla/EventStateManager.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/MouseEvents.h"
+#include "mozilla/PointerLockManager.h"
 #include "mozilla/PresShell.h"
 #include "mozilla/Services.h"
 #include "mozilla/StaticPrefs_layout.h"
@@ -987,6 +988,7 @@ bool nsXULPopupManager::ShowPopupAsNativeMenu(Element* aPopup, int32_t aXPos,
     EventStateManager::ClearGlobalActiveContent(activeESM);
     activeESM->StopTrackingDragGesture(true);
   }
+  PointerLockManager::Unlock();
   PresShell::ReleaseCapturingContent();
 
   return true;
@@ -1201,6 +1203,10 @@ void nsXULPopupManager::ShowPopupCallback(Element* aPopup,
   // Caret visibility may have been affected, ensure that
   // the caret isn't now drawn when it shouldn't be.
   CheckCaretDrawingState();
+
+  if (popupType != PopupType::Tooltip) {
+    PointerLockManager::Unlock();
+  }
 }
 
 nsMenuChainItem* nsXULPopupManager::FindPopup(Element* aPopup) const {
@@ -1851,8 +1857,17 @@ nsIContent* nsXULPopupManager::GetTopActiveMenuItemContent() {
   return nullptr;
 }
 
-void nsXULPopupManager::GetVisiblePopups(nsTArray<nsIFrame*>& aPopups) {
+void nsXULPopupManager::GetVisiblePopups(nsTArray<nsMenuPopupFrame*>& aPopups,
+                                         bool aIncludeNativeMenu) {
   aPopups.Clear();
+  if (aIncludeNativeMenu && mNativeMenu) {
+    nsCOMPtr<nsIContent> popup = mNativeMenu->Element();
+    nsMenuPopupFrame* popupFrame = GetPopupFrameForContent(popup, true);
+    if (popupFrame && popupFrame->IsVisible() &&
+        !popupFrame->IsMouseTransparent()) {
+      aPopups.AppendElement(popupFrame);
+    }
+  }
   for (nsMenuChainItem* item = mPopups.get(); item; item = item->GetParent()) {
     // Skip panels which are not visible as well as popups that are transparent
     // to mouse events.


=====================================
layout/xul/nsXULPopupManager.h
=====================================
@@ -184,10 +184,10 @@ using HidePopupOptions = mozilla::EnumSet<HidePopupOption>;
  */
 extern const nsNavigationDirection DirectionFromKeyCodeTable[2][6];
 
-#define NS_DIRECTION_FROM_KEY_CODE(frame, keycode) \
-  (DirectionFromKeyCodeTable[static_cast<uint8_t>( \
-      (frame)->StyleVisibility()->mDirection)][(   \
-      keycode)-mozilla::dom::KeyboardEvent_Binding::DOM_VK_END])
+#define NS_DIRECTION_FROM_KEY_CODE(frame, keycode)                    \
+  (DirectionFromKeyCodeTable                                          \
+       [static_cast<uint8_t>((frame)->StyleVisibility()->mDirection)] \
+       [(keycode) - mozilla::dom::KeyboardEvent_Binding::DOM_VK_END])
 
 // Used to hold information about a popup that is about to be opened.
 struct PendingPopup {
@@ -601,8 +601,10 @@ class nsXULPopupManager final : public nsIDOMEventListener,
   /**
    * Return an array of all the open and visible popup frames for
    * menus, in order from top to bottom.
+   * XXX should we always include native menu?
    */
-  void GetVisiblePopups(nsTArray<nsIFrame*>& aPopups);
+  void GetVisiblePopups(nsTArray<nsMenuPopupFrame*>& aPopups,
+                        bool aIncludeNativeMenu = false);
 
   /**
    * Get the node that last triggered a popup or tooltip in the document


=====================================
modules/libpref/init/StaticPrefList.yaml
=====================================
@@ -2701,6 +2701,13 @@
   value: false
   mirror: always
 
+# The interval in milliseconds between two Escape key events where the second
+# key event will exit fullscreen, even if it is consumed.
+- name: dom.fullscreen.force_exit_on_multiple_escape_interval
+  type: uint32_t
+  value: 500
+  mirror: always
+
 # Whether fullscreen should make the rest of the document inert.
 # This matches other browsers but historically not Gecko.
 - name: dom.fullscreen.modal
@@ -11417,6 +11424,11 @@
   value: false
   mirror: always
 
+- name: network.cookie.sameSite.crossSiteIframeSetCheck
+  type: bool
+  value: true
+  mirror: always
+
 - name: network.cookie.thirdparty.sessionOnly
   type: bool
   value: false


=====================================
netwerk/cookie/CookieService.cpp
=====================================
@@ -675,6 +675,18 @@ CookieService::SetCookieStringFromHttp(nsIURI* aHostURI,
   if (!addonAllowsLoad) {
     mThirdPartyUtil->IsThirdPartyChannel(aChannel, aHostURI,
                                          &isForeignAndNotAddon);
+
+    // include sub-document navigations from cross-site to same-site
+    // wrt top-level in our check for thirdparty-ness
+    if (StaticPrefs::network_cookie_sameSite_crossSiteIframeSetCheck() &&
+        !isForeignAndNotAddon &&
+        loadInfo->GetExternalContentPolicyType() ==
+            ExtContentPolicy::TYPE_SUBDOCUMENT) {
+      bool triggeringPrincipalIsThirdParty = false;
+      BasePrincipal::Cast(loadInfo->TriggeringPrincipal())
+          ->IsThirdPartyURI(channelURI, &triggeringPrincipalIsThirdParty);
+      isForeignAndNotAddon |= triggeringPrincipalIsThirdParty;
+    }
   }
 
   nsCString cookieHeader(aCookieHeader);


=====================================
netwerk/cookie/CookieServiceChild.cpp
=====================================
@@ -517,6 +517,18 @@ CookieServiceChild::SetCookieStringFromHttp(nsIURI* aHostURI,
   if (!addonAllowsLoad) {
     mThirdPartyUtil->IsThirdPartyChannel(aChannel, aHostURI,
                                          &isForeignAndNotAddon);
+
+    // include sub-document navigations from cross-site to same-site
+    // wrt top-level in our check for thirdparty-ness
+    if (StaticPrefs::network_cookie_sameSite_crossSiteIframeSetCheck() &&
+        !isForeignAndNotAddon &&
+        loadInfo->GetExternalContentPolicyType() ==
+            ExtContentPolicy::TYPE_SUBDOCUMENT) {
+      bool triggeringPrincipalIsThirdParty = false;
+      BasePrincipal::Cast(loadInfo->TriggeringPrincipal())
+          ->IsThirdPartyURI(finalChannelURI, &triggeringPrincipalIsThirdParty);
+      isForeignAndNotAddon |= triggeringPrincipalIsThirdParty;
+    }
   }
 
   bool moreCookies;


=====================================
testing/web-platform/meta/cookies/samesite/setcookie-navigation.https.html.ini
=====================================
@@ -1,11 +1,4 @@
 [setcookie-navigation.https.html]
+  prefs: [network.cookie.sameSite.laxByDefault:true, network.cookie.sameSite.noneRequiresSecure:true]
   expected:
     if (os == "android") and fission: [OK, TIMEOUT]
-  [Cross-site to same-site iframe navigation should only be able to set SameSite=None cookies.]
-    expected: FAIL
-
-  [Same-site to cross-site-site iframe navigation should only be able to set SameSite=None cookies.]
-    expected: FAIL
-
-  [Cross-site to cross-site iframe navigation should only be able to set SameSite=None cookies.]
-    expected: FAIL



View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/9d5f7f327952f6502fe9ff84c0efd6c6f6fb0f44...ff246121a03d387cbf58f09907b0aa7905613d5b

-- 
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/9d5f7f327952f6502fe9ff84c0efd6c6f6fb0f44...ff246121a03d387cbf58f09907b0aa7905613d5b
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/tor-commits/attachments/20240709/a00508c1/attachment-0001.htm>


More information about the tor-commits mailing list