From af84337437631966a685f86b4d46c5fb393bf473 Mon Sep 17 00:00:00 2001 From: Francis Dominic Fajardo Date: Fri, 27 Jun 2025 12:23:26 +0800 Subject: [PATCH 1/3] Issue #2765 - Follow-up: Make scrollbar width checks use the originating non-NAC style context on Linux and Mac --- widget/cocoa/nsNativeThemeCocoa.mm | 4 +++- widget/gtk/nsNativeThemeGTK.cpp | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/widget/cocoa/nsNativeThemeCocoa.mm b/widget/cocoa/nsNativeThemeCocoa.mm index 056c453f2a..5681a40d1d 100644 --- a/widget/cocoa/nsNativeThemeCocoa.mm +++ b/widget/cocoa/nsNativeThemeCocoa.mm @@ -2282,7 +2282,9 @@ IsHiDPIContext(nsPresContext* aContext) static bool IsScrollbarWidthThin(nsIFrame* aFrame) { - return aFrame->StyleUserInterface()->mScrollbarWidth == StyleScrollbarWidth::Thin; + nsStyleContext* styleContext = nsLayoutUtils::GetNonAnonymousStyleContext(aFrame); + auto scrollbarWidth = styleContext->StyleUIReset()->mScrollbarWidth; + return scrollbarWidth == StyleScrollbarWidth::Thin; } NS_IMETHODIMP diff --git a/widget/gtk/nsNativeThemeGTK.cpp b/widget/gtk/nsNativeThemeGTK.cpp index cb4e7debf2..d9fd132d28 100644 --- a/widget/gtk/nsNativeThemeGTK.cpp +++ b/widget/gtk/nsNativeThemeGTK.cpp @@ -1101,7 +1101,9 @@ nsNativeThemeGTK::GetExtraSizeForWidget(nsIFrame* aFrame, uint8_t aWidgetType, static bool IsScrollbarWidthThin(nsIFrame* aFrame) { - return aFrame->StyleUserInterface()->mScrollbarWidth == StyleScrollbarWidth::Thin; + nsStyleContext* styleContext = nsLayoutUtils::GetNonAnonymousStyleContext(aFrame); + auto scrollbarWidth = styleContext->StyleUIReset()->mScrollbarWidth; + return scrollbarWidth == StyleScrollbarWidth::Thin; } NS_IMETHODIMP From 6e358f1039908b43c2e9f826b9b949e3e0bf2e8a Mon Sep 17 00:00:00 2001 From: Francis Dominic Fajardo Date: Fri, 27 Jun 2025 23:43:23 +0800 Subject: [PATCH 2/3] Issue #2765 - Follow-up: Fix UAF when returning the non-NAC style context from a frameless node --- layout/base/nsLayoutUtils.cpp | 10 +++------- layout/base/nsLayoutUtils.h | 2 +- layout/generic/nsGfxScrollFrame.cpp | 2 +- widget/cocoa/nsNativeThemeCocoa.mm | 2 +- widget/gtk/nsNativeThemeGTK.cpp | 2 +- widget/windows/nsNativeThemeWin.cpp | 2 +- 6 files changed, 8 insertions(+), 12 deletions(-) diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 06014e5c50..854c401938 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -9338,7 +9338,7 @@ nsLayoutUtils::ComputeGeometryBox(nsIFrame* aFrame, return r; } -/* static */ nsStyleContext* +/* static */ already_AddRefed nsLayoutUtils::GetNonAnonymousStyleContext(nsIFrame* aFrame) { nsIContent* node = aFrame->GetContent(); @@ -9348,7 +9348,7 @@ nsLayoutUtils::GetNonAnonymousStyleContext(nsIFrame* aFrame) } MOZ_ASSERT(node, "Native anonymous element with no originating node?"); if (nsIFrame* primaryFrame = node->GetPrimaryFrame()) { - return primaryFrame->StyleContext(); + return RefPtr(primaryFrame->StyleContext()).forget(); } // If the element doesn't have primary frame, get the computed style // from the element directly. @@ -9356,9 +9356,5 @@ nsLayoutUtils::GetNonAnonymousStyleContext(nsIFrame* aFrame) MOZ_ASSERT(node == pc->Document()->GetRootElement(), "Root element is the only case for this fallback " "path to be triggered"); - RefPtr styleContext = - pc->StyleSet()->ResolveStyleFor(node->AsElement(), nullptr); - // Dropping the strong reference is fine because the style should be - // held strongly by the element. - return styleContext.get(); + return pc->StyleSet()->ResolveStyleFor(node->AsElement(), nullptr); } diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index ea9a026007..b18edbc9c9 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -2885,7 +2885,7 @@ public: * @param aFrame The frame associated with native anonymous content. * @return The resolved style context of the nearest non-anonymous DOM ancestor. */ - static nsStyleContext* GetNonAnonymousStyleContext(nsIFrame* aFrame); + static already_AddRefed GetNonAnonymousStyleContext(nsIFrame* aFrame); private: static uint32_t sFontSizeInflationEmPerLine; diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index 6197cf94c3..cbf2cf4f7a 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -1058,7 +1058,7 @@ nsHTMLScrollFrame::Reflow(nsPresContext* aPresContext, // This is only needed for root element because scrollbars of non- // root elements with "scrollbar-width: none" is already suppressed // in ScrollFrameHelper::CreateAnonymousContent. - nsStyleContext* scrollbarStyle = nsLayoutUtils::GetNonAnonymousStyleContext(this); + RefPtr scrollbarStyle = nsLayoutUtils::GetNonAnonymousStyleContext(this); auto scrollbarWidth = scrollbarStyle->StyleUIReset()->mScrollbarWidth; if (scrollbarWidth == StyleScrollbarWidth::None) { state.mVScrollbar = ShowScrollbar::Never; diff --git a/widget/cocoa/nsNativeThemeCocoa.mm b/widget/cocoa/nsNativeThemeCocoa.mm index 5681a40d1d..ad16ecb0ec 100644 --- a/widget/cocoa/nsNativeThemeCocoa.mm +++ b/widget/cocoa/nsNativeThemeCocoa.mm @@ -2282,7 +2282,7 @@ IsHiDPIContext(nsPresContext* aContext) static bool IsScrollbarWidthThin(nsIFrame* aFrame) { - nsStyleContext* styleContext = nsLayoutUtils::GetNonAnonymousStyleContext(aFrame); + RefPtr styleContext = nsLayoutUtils::GetNonAnonymousStyleContext(aFrame); auto scrollbarWidth = styleContext->StyleUIReset()->mScrollbarWidth; return scrollbarWidth == StyleScrollbarWidth::Thin; } diff --git a/widget/gtk/nsNativeThemeGTK.cpp b/widget/gtk/nsNativeThemeGTK.cpp index d9fd132d28..59f611e723 100644 --- a/widget/gtk/nsNativeThemeGTK.cpp +++ b/widget/gtk/nsNativeThemeGTK.cpp @@ -1101,7 +1101,7 @@ nsNativeThemeGTK::GetExtraSizeForWidget(nsIFrame* aFrame, uint8_t aWidgetType, static bool IsScrollbarWidthThin(nsIFrame* aFrame) { - nsStyleContext* styleContext = nsLayoutUtils::GetNonAnonymousStyleContext(aFrame); + RefPtr styleContext = nsLayoutUtils::GetNonAnonymousStyleContext(aFrame); auto scrollbarWidth = styleContext->StyleUIReset()->mScrollbarWidth; return scrollbarWidth == StyleScrollbarWidth::Thin; } diff --git a/widget/windows/nsNativeThemeWin.cpp b/widget/windows/nsNativeThemeWin.cpp index 3250fec5c9..cb14f74f69 100644 --- a/widget/windows/nsNativeThemeWin.cpp +++ b/widget/windows/nsNativeThemeWin.cpp @@ -1572,7 +1572,7 @@ GetThemeDpiScaleFactor(nsIFrame* aFrame) static bool IsScrollbarWidthThin(nsIFrame* aFrame) { - nsStyleContext* styleContext = nsLayoutUtils::GetNonAnonymousStyleContext(aFrame); + RefPtr styleContext = nsLayoutUtils::GetNonAnonymousStyleContext(aFrame); auto scrollbarWidth = styleContext->StyleUIReset()->mScrollbarWidth; return scrollbarWidth == StyleScrollbarWidth::Thin; } From e4630ce481ad622c831f88faf1ec973137f4e4d7 Mon Sep 17 00:00:00 2001 From: Francis Dominic Fajardo Date: Sat, 28 Jun 2025 16:14:55 +0800 Subject: [PATCH 3/3] Issue #2765 - Follow-up: Avoid declaring RefPtr in the return statement --- layout/base/nsLayoutUtils.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 854c401938..e78536d00e 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -9348,7 +9348,8 @@ nsLayoutUtils::GetNonAnonymousStyleContext(nsIFrame* aFrame) } MOZ_ASSERT(node, "Native anonymous element with no originating node?"); if (nsIFrame* primaryFrame = node->GetPrimaryFrame()) { - return RefPtr(primaryFrame->StyleContext()).forget(); + RefPtr context = primaryFrame->StyleContext(); + return context.forget(); } // If the element doesn't have primary frame, get the computed style // from the element directly.