mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-21 20:24:42 +00:00
Fix issues with blobs
https://github.com/lightpanda-io/browser/pull/1775 made blobs finalizable and https://github.com/lightpanda-io/browser/pull/1795 made it possible to navigate from blobs (important for WPT tests). This fixes a number of issues related to both. First, weak/strong ref'ing a value now uses the resolved value. When registering a finalizer, we use the resolved value (the most specific type in the prototype chain). For this reason, when toggling a weak/strong ref, we have to use the same resolved value. This solves a segfault where a File is created, but extended as a Blob (e.g. in createObjectURL). Next, two issues were fixed when navigating to an invalid blob. First, the frame is properly removed from the parent list on frame navigation error. Second, on frame navigation error, we don't stop _all_ other navigations, we just log the error and move on to the next frame.
This commit is contained in:
@@ -548,7 +548,9 @@ fn processQueuedNavigation(self: *Session) !void {
|
||||
continue;
|
||||
}
|
||||
|
||||
try self.processFrameNavigation(page, qn);
|
||||
self.processFrameNavigation(page, qn) catch |err| {
|
||||
log.warn(.page, "frame navigation", .{ .url = qn.url, .err = err });
|
||||
};
|
||||
}
|
||||
|
||||
// Clear the queue after first pass
|
||||
@@ -588,7 +590,8 @@ fn processFrameNavigation(self: *Session, page: *Page, qn: *QueuedNavigation) !v
|
||||
|
||||
errdefer iframe._window = null;
|
||||
|
||||
if (page._parent_notified) {
|
||||
const parent_notified = page._parent_notified;
|
||||
if (parent_notified) {
|
||||
// we already notified the parent that we had loaded
|
||||
parent._pending_loads += 1;
|
||||
}
|
||||
@@ -598,7 +601,19 @@ fn processFrameNavigation(self: *Session, page: *Page, qn: *QueuedNavigation) !v
|
||||
page.* = undefined;
|
||||
|
||||
try Page.init(page, frame_id, self, parent);
|
||||
errdefer page.deinit(true);
|
||||
errdefer {
|
||||
for (parent.frames.items, 0..) |frame, i| {
|
||||
if (frame == page) {
|
||||
parent.frames_sorted = false;
|
||||
_ = parent.frames.swapRemove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (parent_notified) {
|
||||
parent._pending_loads -= 1;
|
||||
}
|
||||
page.deinit(true);
|
||||
}
|
||||
|
||||
page.iframe = iframe;
|
||||
iframe._window = page.window;
|
||||
|
||||
@@ -197,18 +197,20 @@ pub fn trackTemp(self: *Context, global: v8.Global) !void {
|
||||
}
|
||||
|
||||
pub fn weakRef(self: *Context, obj: anytype) void {
|
||||
const fc = self.origin.finalizer_callbacks.get(@intFromPtr(obj)) orelse {
|
||||
const resolved = js.Local.resolveValue(obj);
|
||||
const fc = self.origin.finalizer_callbacks.get(@intFromPtr(resolved.ptr)) orelse {
|
||||
if (comptime IS_DEBUG) {
|
||||
// should not be possible
|
||||
std.debug.assert(false);
|
||||
}
|
||||
return;
|
||||
};
|
||||
v8.v8__Global__SetWeakFinalizer(&fc.global, fc, bridge.Struct(@TypeOf(obj)).JsApi.Meta.finalizer.from_v8, v8.kParameter);
|
||||
v8.v8__Global__SetWeakFinalizer(&fc.global, fc, resolved.finalizer_from_v8, v8.kParameter);
|
||||
}
|
||||
|
||||
pub fn safeWeakRef(self: *Context, obj: anytype) void {
|
||||
const fc = self.origin.finalizer_callbacks.get(@intFromPtr(obj)) orelse {
|
||||
const resolved = js.Local.resolveValue(obj);
|
||||
const fc = self.origin.finalizer_callbacks.get(@intFromPtr(resolved.ptr)) orelse {
|
||||
if (comptime IS_DEBUG) {
|
||||
// should not be possible
|
||||
std.debug.assert(false);
|
||||
@@ -216,11 +218,12 @@ pub fn safeWeakRef(self: *Context, obj: anytype) void {
|
||||
return;
|
||||
};
|
||||
v8.v8__Global__ClearWeak(&fc.global);
|
||||
v8.v8__Global__SetWeakFinalizer(&fc.global, fc, bridge.Struct(@TypeOf(obj)).JsApi.Meta.finalizer.from_v8, v8.kParameter);
|
||||
v8.v8__Global__SetWeakFinalizer(&fc.global, fc, resolved.finalizer_from_v8, v8.kParameter);
|
||||
}
|
||||
|
||||
pub fn strongRef(self: *Context, obj: anytype) void {
|
||||
const fc = self.origin.finalizer_callbacks.get(@intFromPtr(obj)) orelse {
|
||||
const resolved = js.Local.resolveValue(obj);
|
||||
const fc = self.origin.finalizer_callbacks.get(@intFromPtr(resolved.ptr)) orelse {
|
||||
if (comptime IS_DEBUG) {
|
||||
// should not be possible
|
||||
std.debug.assert(false);
|
||||
|
||||
Reference in New Issue
Block a user