From 513af82751cb8aad3b95af25c97e00276395dbbe Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Wed, 15 Apr 2026 17:40:33 +0800 Subject: [PATCH] On page reset, reset IsolatedWorld identity This is an attempt to fix reference counting issues. When Session.replacePage is called, isolated worlds survive. This appears to be the correct behavior, but it means that their identity outlives the page reset, which can result in a use-after-free. The idea is that, on reset, IsolatedWorld persist, but their identity is cleared. --- src/cdp/domains/page.zig | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/cdp/domains/page.zig b/src/cdp/domains/page.zig index 17455391..83c01b28 100644 --- a/src/cdp/domains/page.zig +++ b/src/cdp/domains/page.zig @@ -283,6 +283,12 @@ fn navigate(cmd: *CDP.Command) !void { var page = session.currentPage() orelse return error.PageNotLoaded; if (page._load_state != .waiting) { + // Reset isolated world identities to disable V8 weak callbacks before + // resetPageResources releases refs. Prevents double-release crashes. + for (bc.isolated_worlds.items) |isolated_world| { + isolated_world.identity.deinit(); + isolated_world.identity = .{}; + } page = try session.replacePage(); } @@ -313,6 +319,12 @@ fn doReload(cmd: *CDP.Command) !void { const reload_url = try cmd.arena.dupeZ(u8, page.url); if (page._load_state != .waiting) { + // Reset isolated world identities to disable V8 weak callbacks before + // resetPageResources releases refs. Prevents double-release crashes. + for (bc.isolated_worlds.items) |isolated_world| { + isolated_world.identity.deinit(); + isolated_world.identity = .{}; + } page = try session.replacePage(); }