fix: uaf in non-client hittest during view teardown (#50053)

* fix: uaf in non-client hittest during view teardown

Co-authored-by: deepak1556 <hop2deep@gmail.com>

* chore: update crash spec

Co-authored-by: deepak1556 <hop2deep@gmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: deepak1556 <hop2deep@gmail.com>
This commit is contained in:
trop[bot]
2026-03-03 14:16:05 -05:00
committed by GitHub
parent 1598b9116d
commit 79d1e32281
3 changed files with 36 additions and 2 deletions

View File

@@ -83,13 +83,17 @@ void WebContentsView::ApplyBorderRadius() {
int WebContentsView::NonClientHitTest(const gfx::Point& point) {
if (api_web_contents_) {
auto* iwc = api_web_contents_->inspectable_web_contents();
if (!iwc)
return HTNOWHERE;
// Convert the point to the contents view's coordinate space rather than
// the InspectableWebContentsView's coordinate space, because the draggable
// region is relative to the web content area. When DevTools is docked
// (e.g. to the left), the contents view is offset within the parent,
// so we need to account for that offset.
auto* inspectable_view =
api_web_contents_->inspectable_web_contents()->GetView();
auto* inspectable_view = iwc->GetView();
if (!inspectable_view)
return HTNOWHERE;
auto* contents_view = inspectable_view->GetContentsView();
gfx::Point local_point(point);
views::View::ConvertPointFromWidget(contents_view, &local_point);

View File

@@ -343,6 +343,10 @@ InspectableWebContents::InspectableWebContents(
}
InspectableWebContents::~InspectableWebContents() {
// Explicitly destroy the view first to ensure that any callbacks triggered
// during view teardown (like NonClientHitTest) does not access a
// partially-destroyed view.
view_.reset();
// Unsubscribe from devtools and Clean up resources.
if (GetDevToolsWebContents())
WebContentsDestroyed();

View File

@@ -0,0 +1,26 @@
const { app, BrowserWindow } = require('electron');
if (process.platform !== 'win32') {
process.exit(0);
}
app.on('window-all-closed', () => {
app.quit();
});
app.whenReady().then(() => {
let win = new BrowserWindow({
frame: false,
show: true
});
win.loadURL('about:blank');
setTimeout(() => {
win.close();
}, 5000);
win.on('closed', () => {
win = null;
});
});