mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-22 04:34:44 +00:00
Merge pull request #1846 from lightpanda-io/origin_cdp_fix
Fix use-after-free with certain CDP scripts
This commit is contained in:
@@ -167,12 +167,11 @@ pub fn setOrigin(self: *Context, key: ?[]const u8) !void {
|
|||||||
const env = self.env;
|
const env = self.env;
|
||||||
const isolate = env.isolate;
|
const isolate = env.isolate;
|
||||||
|
|
||||||
|
lp.assert(self.origin.rc == 1, "Ref opaque origin", .{ .rc = self.origin.rc });
|
||||||
|
|
||||||
const origin = try self.session.getOrCreateOrigin(key);
|
const origin = try self.session.getOrCreateOrigin(key);
|
||||||
errdefer self.session.releaseOrigin(origin);
|
errdefer self.session.releaseOrigin(origin);
|
||||||
|
try origin.takeover(self.origin);
|
||||||
try self.origin.transferTo(origin);
|
|
||||||
lp.assert(self.origin.rc == 1, "Ref opaque origin", .{ .rc = self.origin.rc });
|
|
||||||
self.origin.deinit(env.app);
|
|
||||||
|
|
||||||
self.origin = origin;
|
self.origin = origin;
|
||||||
|
|
||||||
|
|||||||
@@ -68,6 +68,8 @@ temps: std.AutoHashMapUnmanaged(usize, v8.Global) = .empty,
|
|||||||
// if v8 hasn't called the finalizer directly itself.
|
// if v8 hasn't called the finalizer directly itself.
|
||||||
finalizer_callbacks: std.AutoHashMapUnmanaged(usize, *FinalizerCallback) = .empty,
|
finalizer_callbacks: std.AutoHashMapUnmanaged(usize, *FinalizerCallback) = .empty,
|
||||||
|
|
||||||
|
taken_over: std.ArrayList(*Origin),
|
||||||
|
|
||||||
pub fn init(app: *App, isolate: js.Isolate, key: []const u8) !*Origin {
|
pub fn init(app: *App, isolate: js.Isolate, key: []const u8) !*Origin {
|
||||||
const arena = try app.arena_pool.acquire();
|
const arena = try app.arena_pool.acquire();
|
||||||
errdefer app.arena_pool.release(arena);
|
errdefer app.arena_pool.release(arena);
|
||||||
@@ -86,14 +88,19 @@ pub fn init(app: *App, isolate: js.Isolate, key: []const u8) !*Origin {
|
|||||||
.rc = 1,
|
.rc = 1,
|
||||||
.arena = arena,
|
.arena = arena,
|
||||||
.key = owned_key,
|
.key = owned_key,
|
||||||
.globals = .empty,
|
|
||||||
.temps = .empty,
|
.temps = .empty,
|
||||||
|
.globals = .empty,
|
||||||
|
.taken_over = .empty,
|
||||||
.security_token = token_global,
|
.security_token = token_global,
|
||||||
};
|
};
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Origin, app: *App) void {
|
pub fn deinit(self: *Origin, app: *App) void {
|
||||||
|
for (self.taken_over.items) |o| {
|
||||||
|
o.deinit(app);
|
||||||
|
}
|
||||||
|
|
||||||
// Call finalizers before releasing anything
|
// Call finalizers before releasing anything
|
||||||
{
|
{
|
||||||
var it = self.finalizer_callbacks.valueIterator();
|
var it = self.finalizer_callbacks.valueIterator();
|
||||||
@@ -196,42 +203,44 @@ pub fn createFinalizerCallback(
|
|||||||
return fc;
|
return fc;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transferTo(self: *Origin, dest: *Origin) !void {
|
pub fn takeover(self: *Origin, original: *Origin) !void {
|
||||||
const arena = dest.arena;
|
const arena = self.arena;
|
||||||
|
|
||||||
try dest.globals.ensureUnusedCapacity(arena, self.globals.items.len);
|
try self.globals.ensureUnusedCapacity(arena, self.globals.items.len);
|
||||||
for (self.globals.items) |obj| {
|
for (original.globals.items) |obj| {
|
||||||
dest.globals.appendAssumeCapacity(obj);
|
self.globals.appendAssumeCapacity(obj);
|
||||||
}
|
}
|
||||||
self.globals.clearRetainingCapacity();
|
original.globals.clearRetainingCapacity();
|
||||||
|
|
||||||
{
|
{
|
||||||
try dest.temps.ensureUnusedCapacity(arena, self.temps.count());
|
try self.temps.ensureUnusedCapacity(arena, original.temps.count());
|
||||||
var it = self.temps.iterator();
|
var it = original.temps.iterator();
|
||||||
while (it.next()) |kv| {
|
while (it.next()) |kv| {
|
||||||
try dest.temps.put(arena, kv.key_ptr.*, kv.value_ptr.*);
|
try self.temps.put(arena, kv.key_ptr.*, kv.value_ptr.*);
|
||||||
}
|
}
|
||||||
self.temps.clearRetainingCapacity();
|
original.temps.clearRetainingCapacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
try dest.finalizer_callbacks.ensureUnusedCapacity(arena, self.finalizer_callbacks.count());
|
try self.finalizer_callbacks.ensureUnusedCapacity(arena, original.finalizer_callbacks.count());
|
||||||
var it = self.finalizer_callbacks.iterator();
|
var it = original.finalizer_callbacks.iterator();
|
||||||
while (it.next()) |kv| {
|
while (it.next()) |kv| {
|
||||||
kv.value_ptr.*.origin = dest;
|
kv.value_ptr.*.origin = self;
|
||||||
try dest.finalizer_callbacks.put(arena, kv.key_ptr.*, kv.value_ptr.*);
|
try self.finalizer_callbacks.put(arena, kv.key_ptr.*, kv.value_ptr.*);
|
||||||
}
|
}
|
||||||
self.finalizer_callbacks.clearRetainingCapacity();
|
original.finalizer_callbacks.clearRetainingCapacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
try dest.identity_map.ensureUnusedCapacity(arena, self.identity_map.count());
|
try self.identity_map.ensureUnusedCapacity(arena, original.identity_map.count());
|
||||||
var it = self.identity_map.iterator();
|
var it = original.identity_map.iterator();
|
||||||
while (it.next()) |kv| {
|
while (it.next()) |kv| {
|
||||||
try dest.identity_map.put(arena, kv.key_ptr.*, kv.value_ptr.*);
|
try self.identity_map.put(arena, kv.key_ptr.*, kv.value_ptr.*);
|
||||||
}
|
}
|
||||||
self.identity_map.clearRetainingCapacity();
|
original.identity_map.clearRetainingCapacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try self.taken_over.append(self.arena, original);
|
||||||
}
|
}
|
||||||
|
|
||||||
// A type that has a finalizer can have its finalizer called one of two ways.
|
// A type that has a finalizer can have its finalizer called one of two ways.
|
||||||
|
|||||||
Reference in New Issue
Block a user