Fix use-after free

On CDP.BrowserContext.deinit, clear the isolated world ExecutionContext before
terminating the session. This is important as the isolated_world list is
allocated from the session.arena.

Also, semi-revert 63f1c85964. Before all this
we were running microtasks on ExecutionWorld.removeContext. That didn't seem
right (and I thought it was the original source of the bug). But, for the "real"
Page context, this is critical, since Microtasks can reference the Page object.
Since microTasks are isolation-level, it's possible for a microtasks for Page1
to execute after Page1 goes away (if we create a new page, Page2). This re-adds
the microtask "draining", but only for the Page (i.e. in Page.deinit).
This commit is contained in:
Karl Seguin
2026-01-14 09:37:10 +08:00
parent 63f1c85964
commit 223a6170d5
2 changed files with 10 additions and 8 deletions

View File

@@ -411,15 +411,16 @@ pub fn BrowserContext(comptime CDP_T: type) type {
transfer.abort(error.ClientDisconnect);
}
for (self.isolated_worlds.items) |*world| {
world.deinit();
}
self.isolated_worlds.clearRetainingCapacity();
// If the session has a page, we need to clear it first. The page
// context is always nested inside of the isolated world context,
// so we need to shutdown the page one first.
self.cdp.browser.closeSession();
for (self.isolated_worlds.items) |*world| {
world.deinit();
}
self.isolated_worlds.clearRetainingCapacity();
self.node_registry.deinit();
self.node_search_list.deinit();
self.cdp.browser.notification.unregisterAll(self);