mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-09-14 23:15:14 -04:00
script: fix segfault when a tool call triggers navigation
A press/click that submits a form or follows a link commits a replacement Page inside the tool call itself (finalizeAction -> awaitQueuedNavigation), freeing the Frame that Session._tool_frame_override still pointed at; finalizeAction then dereferenced it via requireFrame -> currentFrame. Any script whose press/click navigated crashed on replay. Store a frame id instead of a pointer and resolve it at every currentFrame call. The replacement page keeps the frame id (see commitPendingPage), so the same handle stays routable across the swap.
This commit is contained in:
1 parent
933dc61bf6
commit
ae2359c1af
2 files changed
+32
-7
No files matched your search
+23
-2
@@ -449,10 +449,10 @@ fn invoke(self: *Runtime, tool: BrowserTool, info: *const v8.FunctionCallbackInf
|
||||
// `pages[0]` is not necessarily this handle's page.
|
||||
const frame_id = self.receiverFrameId(context, info) orelse
|
||||
return self.throwError("page is not navigated or has been closed; call page.goto(url) first");
|
||||
const frame = self.session.findFrameByFrameId(frame_id) orelse
|
||||
if (self.session.findFrameByFrameId(frame_id) == null)
|
||||
return self.throwError("page handle is no longer valid; the page was closed");
|
||||
|
||||
self.session.setToolFrameOverride(frame);
|
||||
self.session.setToolFrameOverride(frame_id);
|
||||
defer self.session.setToolFrameOverride(null);
|
||||
|
||||
const result = self.callTool(arena, tool, args) catch |err| switch (err) {
|
||||
@@ -1083,6 +1083,27 @@ test "agent script runtime: parallel gotos coexist and route per page" {
|
||||
);
|
||||
}
|
||||
|
||||
test "agent script runtime: a tool-triggered navigation keeps the handle routable" {
|
||||
defer testing.reset();
|
||||
defer testing.test_session.closeAllPages();
|
||||
|
||||
var registry = CDPNode.Registry.init(testing.allocator);
|
||||
defer registry.deinit();
|
||||
|
||||
const runtime = try Runtime.init(testing.allocator, testing.test_app, testing.test_session, ®istry);
|
||||
defer runtime.deinit();
|
||||
|
||||
// click commits a replacement Page mid-call; the frame override and the
|
||||
// handle's frame id must both survive the swap.
|
||||
try runTestScript(runtime,
|
||||
\\const page = new Page();
|
||||
\\await page.goto("http://localhost:9582/src/browser/tests/mcp_nav.html");
|
||||
\\page.click("#navlink");
|
||||
\\const href = page.evaluate("location.href");
|
||||
\\if (href !== "about:blank") throw new Error("expected about:blank, got: " + href);
|
||||
);
|
||||
}
|
||||
|
||||
test "agent script runtime: re-goto on the same page object replaces its page" {
|
||||
defer testing.reset();
|
||||
defer testing.test_session.closeAllPages();
|
||||
|
||||
Reference in new issue
Block a user