cdp: fix memory leak in msg parsing of the JSON

Signed-off-by: Francis Bouvier <francis@lightpanda.io>
This commit is contained in:
Francis Bouvier
2024-11-09 03:25:42 +01:00
parent f60fcbec04
commit ed3a464843
10 changed files with 131 additions and 46 deletions

View File

@@ -23,6 +23,7 @@ const Ctx = server.Ctx;
const cdp = @import("cdp.zig"); const cdp = @import("cdp.zig");
const result = cdp.result; const result = cdp.result;
const IncomingMessage = @import("msg.zig").IncomingMessage; const IncomingMessage = @import("msg.zig").IncomingMessage;
const Input = @import("msg.zig").Input;
const log = std.log.scoped(.cdp); const log = std.log.scoped(.cdp);
@@ -62,7 +63,8 @@ fn getVersion(
_: *Ctx, _: *Ctx,
) ![]const u8 { ) ![]const u8 {
// input // input
const input = try msg.getInput(alloc, void); const input = try Input(void).get(alloc, msg);
defer input.deinit();
log.debug("Req > id {d}, method {s}", .{ input.id, "browser.getVersion" }); log.debug("Req > id {d}, method {s}", .{ input.id, "browser.getVersion" });
// ouput // ouput
@@ -89,7 +91,8 @@ fn setDownloadBehavior(
downloadPath: ?[]const u8 = null, downloadPath: ?[]const u8 = null,
eventsEnabled: ?bool = null, eventsEnabled: ?bool = null,
}; };
const input = try msg.getInput(alloc, Params); const input = try Input(Params).get(alloc, msg);
defer input.deinit();
log.debug("REQ > id {d}, method {s}", .{ input.id, "browser.setDownloadBehavior" }); log.debug("REQ > id {d}, method {s}", .{ input.id, "browser.setDownloadBehavior" });
// output // output
@@ -109,7 +112,8 @@ fn getWindowForTarget(
const Params = struct { const Params = struct {
targetId: ?[]const u8 = null, targetId: ?[]const u8 = null,
}; };
const input = try msg.getInput(alloc, Params); const input = try Input(Params).get(alloc, msg);
defer input.deinit();
std.debug.assert(input.sessionId != null); std.debug.assert(input.sessionId != null);
log.debug("Req > id {d}, method {s}", .{ input.id, "browser.getWindowForTarget" }); log.debug("Req > id {d}, method {s}", .{ input.id, "browser.getWindowForTarget" });
@@ -133,9 +137,10 @@ fn setWindowBounds(
msg: *IncomingMessage, msg: *IncomingMessage,
_: *Ctx, _: *Ctx,
) ![]const u8 { ) ![]const u8 {
const input = try msg.getInput(alloc, void);
// input // input
const input = try Input(void).get(alloc, msg);
defer input.deinit();
log.debug("Req > id {d}, method {s}", .{ input.id, "browser.setWindowBounds" }); log.debug("Req > id {d}, method {s}", .{ input.id, "browser.setWindowBounds" });
// output // output

View File

@@ -24,6 +24,7 @@ const cdp = @import("cdp.zig");
const result = cdp.result; const result = cdp.result;
const stringify = cdp.stringify; const stringify = cdp.stringify;
const IncomingMessage = @import("msg.zig").IncomingMessage; const IncomingMessage = @import("msg.zig").IncomingMessage;
const Input = @import("msg.zig").Input;
const log = std.log.scoped(.cdp); const log = std.log.scoped(.cdp);
@@ -67,7 +68,8 @@ fn setEmulatedMedia(
media: ?[]const u8 = null, media: ?[]const u8 = null,
features: ?[]MediaFeature = null, features: ?[]MediaFeature = null,
}; };
const input = try msg.getInput(alloc, Params); const input = try Input(Params).get(alloc, msg);
defer input.deinit();
log.debug("Req > id {d}, method {s}", .{ input.id, "emulation.setEmulatedMedia" }); log.debug("Req > id {d}, method {s}", .{ input.id, "emulation.setEmulatedMedia" });
// output // output
@@ -84,7 +86,8 @@ fn setFocusEmulationEnabled(
const Params = struct { const Params = struct {
enabled: bool, enabled: bool,
}; };
const input = try msg.getInput(alloc, Params); const input = try Input(Params).get(alloc, msg);
defer input.deinit();
log.debug("Req > id {d}, method {s}", .{ input.id, "emulation.setFocusEmulationEnabled" }); log.debug("Req > id {d}, method {s}", .{ input.id, "emulation.setFocusEmulationEnabled" });
// output // output
@@ -98,7 +101,8 @@ fn setDeviceMetricsOverride(
_: *Ctx, _: *Ctx,
) ![]const u8 { ) ![]const u8 {
// input // input
const input = try msg.getInput(alloc, void); const input = try Input(void).get(alloc, msg);
defer input.deinit();
log.debug("Req > id {d}, method {s}", .{ input.id, "emulation.setDeviceMetricsOverride" }); log.debug("Req > id {d}, method {s}", .{ input.id, "emulation.setDeviceMetricsOverride" });
// output // output
@@ -111,7 +115,8 @@ fn setTouchEmulationEnabled(
msg: *IncomingMessage, msg: *IncomingMessage,
_: *Ctx, _: *Ctx,
) ![]const u8 { ) ![]const u8 {
const input = try msg.getInput(alloc, void); const input = try Input(void).get(alloc, msg);
defer input.deinit();
log.debug("Req > id {d}, method {s}", .{ input.id, "emulation.setTouchEmulationEnabled" }); log.debug("Req > id {d}, method {s}", .{ input.id, "emulation.setTouchEmulationEnabled" });
return result(alloc, input.id, null, null, input.sessionId); return result(alloc, input.id, null, null, input.sessionId);

View File

@@ -23,6 +23,7 @@ const Ctx = server.Ctx;
const cdp = @import("cdp.zig"); const cdp = @import("cdp.zig");
const result = cdp.result; const result = cdp.result;
const IncomingMessage = @import("msg.zig").IncomingMessage; const IncomingMessage = @import("msg.zig").IncomingMessage;
const Input = @import("msg.zig").Input;
const log = std.log.scoped(.cdp); const log = std.log.scoped(.cdp);
@@ -50,7 +51,8 @@ fn disable(
msg: *IncomingMessage, msg: *IncomingMessage,
_: *Ctx, _: *Ctx,
) ![]const u8 { ) ![]const u8 {
const input = try msg.getInput(alloc, void); const input = try Input(void).get(alloc, msg);
defer input.deinit();
log.debug("Req > id {d}, method {s}", .{ input.id, "fetch.disable" }); log.debug("Req > id {d}, method {s}", .{ input.id, "fetch.disable" });
return result(alloc, input.id, null, null, input.sessionId); return result(alloc, input.id, null, null, input.sessionId);

View File

@@ -23,6 +23,7 @@ const Ctx = server.Ctx;
const cdp = @import("cdp.zig"); const cdp = @import("cdp.zig");
const result = cdp.result; const result = cdp.result;
const IncomingMessage = @import("msg.zig").IncomingMessage; const IncomingMessage = @import("msg.zig").IncomingMessage;
const Input = @import("msg.zig").Input;
const stringify = cdp.stringify; const stringify = cdp.stringify;
const log_cdp = std.log.scoped(.cdp); const log_cdp = std.log.scoped(.cdp);
@@ -50,7 +51,8 @@ fn enable(
msg: *IncomingMessage, msg: *IncomingMessage,
_: *Ctx, _: *Ctx,
) ![]const u8 { ) ![]const u8 {
const input = try msg.getInput(alloc, void); const input = try Input(void).get(alloc, msg);
defer input.deinit();
log_cdp.debug("Req > id {d}, method {s}", .{ input.id, "log.enable" }); log_cdp.debug("Req > id {d}, method {s}", .{ input.id, "log.enable" });
return result(alloc, input.id, null, null, input.sessionId); return result(alloc, input.id, null, null, input.sessionId);

View File

@@ -136,8 +136,9 @@ pub const IncomingMessage = struct {
} }
// getParams restart the JSON parsing // getParams restart the JSON parsing
fn getParams(self: *IncomingMessage, alloc: std.mem.Allocator, T: type) !T { fn getParams(self: *IncomingMessage, alloc: ?std.mem.Allocator, T: type) !T {
if (T == void) return void{}; if (T == void) return void{};
std.debug.assert(alloc != null); // if T is not void, alloc should not be null
if (self.params_skip) { if (self.params_skip) {
// TODO if the params have been skipped, we have to retart the // TODO if the params have been skipped, we have to retart the
@@ -150,19 +151,55 @@ pub const IncomingMessage = struct {
// parse "params" // parse "params"
const options = std.json.ParseOptions{ const options = std.json.ParseOptions{
.max_value_len = self.scanner.input.len, .max_value_len = self.scanner.input.len,
.allocate = .alloc_if_needed, .allocate = .alloc_always,
}; };
return try std.json.innerParse(T, alloc, &self.scanner, options); return try std.json.innerParse(T, alloc.?, &self.scanner, options);
}
};
pub fn Input(T: type) type {
return struct {
arena: ?*std.heap.ArenaAllocator = null,
id: u16,
params: T,
sessionId: ?[]const u8,
const Self = @This();
pub fn get(alloc: std.mem.Allocator, msg: *IncomingMessage) !Self {
var arena: ?*std.heap.ArenaAllocator = null;
var allocator: ?std.mem.Allocator = null;
if (T != void) {
arena = try alloc.create(std.heap.ArenaAllocator);
arena.?.* = std.heap.ArenaAllocator.init(alloc);
allocator = arena.?.allocator();
}
errdefer {
if (arena) |_arena| {
_arena.deinit();
alloc.destroy(_arena);
}
} }
pub fn getInput(self: *IncomingMessage, alloc: std.mem.Allocator, T: type) !struct { id: u16, sessionId: ?[]const u8, params: T } {
return .{ return .{
.params = try self.getParams(alloc, T), .arena = arena,
.id = try self.getId(), .params = try msg.getParams(allocator, T),
.sessionId = try self.getSessionId(), .id = try msg.getId(),
.sessionId = try msg.getSessionId(),
}; };
} }
pub fn deinit(self: Self) void {
if (self.arena) |arena| {
const allocator = arena.child_allocator;
arena.deinit();
allocator.destroy(arena);
}
}
}; };
}
test "read incoming message" { test "read incoming message" {
const inputs = [_][]const u8{ const inputs = [_][]const u8{
@@ -185,11 +222,12 @@ test "read incoming message" {
try std.testing.expectEqualSlices(u8, "bar", (try msg.getSessionId()).?); try std.testing.expectEqualSlices(u8, "bar", (try msg.getSessionId()).?);
const T = struct { bar: []const u8 }; const T = struct { bar: []const u8 };
const in = msg.getInput(std.testing.allocator, T) catch |err| { const in = Input(T).get(std.testing.allocator, &msg) catch |err| {
if (err != error.SkippedParams) return err; if (err != error.SkippedParams) return err;
// TODO remove this check when params in the beginning is handled. // TODO remove this check when params in the beginning is handled.
continue; continue;
}; };
defer in.deinit();
try std.testing.expectEqualSlices(u8, "baz", in.params.bar); try std.testing.expectEqualSlices(u8, "baz", in.params.bar);
} }
} }

View File

@@ -23,6 +23,7 @@ const Ctx = server.Ctx;
const cdp = @import("cdp.zig"); const cdp = @import("cdp.zig");
const result = cdp.result; const result = cdp.result;
const IncomingMessage = @import("msg.zig").IncomingMessage; const IncomingMessage = @import("msg.zig").IncomingMessage;
const Input = @import("msg.zig").Input;
const log = std.log.scoped(.cdp); const log = std.log.scoped(.cdp);
@@ -52,7 +53,8 @@ fn enable(
_: *Ctx, _: *Ctx,
) ![]const u8 { ) ![]const u8 {
// input // input
const input = try msg.getInput(alloc, void); const input = try Input(void).get(alloc, msg);
defer input.deinit();
log.debug("Req > id {d}, method {s}", .{ input.id, "network.enable" }); log.debug("Req > id {d}, method {s}", .{ input.id, "network.enable" });
return result(alloc, input.id, null, null, input.sessionId); return result(alloc, input.id, null, null, input.sessionId);
@@ -65,7 +67,8 @@ fn setCacheDisabled(
_: *Ctx, _: *Ctx,
) ![]const u8 { ) ![]const u8 {
// input // input
const input = try msg.getInput(alloc, void); const input = try Input(void).get(alloc, msg);
defer input.deinit();
log.debug("Req > id {d}, method {s}", .{ input.id, "network.setCacheDisabled" }); log.debug("Req > id {d}, method {s}", .{ input.id, "network.setCacheDisabled" });
return result(alloc, input.id, null, null, input.sessionId); return result(alloc, input.id, null, null, input.sessionId);

View File

@@ -25,6 +25,7 @@ const result = cdp.result;
const stringify = cdp.stringify; const stringify = cdp.stringify;
const sendEvent = cdp.sendEvent; const sendEvent = cdp.sendEvent;
const IncomingMessage = @import("msg.zig").IncomingMessage; const IncomingMessage = @import("msg.zig").IncomingMessage;
const Input = @import("msg.zig").Input;
const log = std.log.scoped(.cdp); const log = std.log.scoped(.cdp);
@@ -63,7 +64,8 @@ fn enable(
_: *Ctx, _: *Ctx,
) ![]const u8 { ) ![]const u8 {
// input // input
const input = try msg.getInput(alloc, void); const input = try Input(void).get(alloc, msg);
defer input.deinit();
log.debug("Req > id {d}, method {s}", .{ input.id, "page.enable" }); log.debug("Req > id {d}, method {s}", .{ input.id, "page.enable" });
return result(alloc, input.id, null, null, input.sessionId); return result(alloc, input.id, null, null, input.sessionId);
@@ -90,7 +92,8 @@ fn getFrameTree(
ctx: *Ctx, ctx: *Ctx,
) ![]const u8 { ) ![]const u8 {
// input // input
const input = try msg.getInput(alloc, void); const input = try Input(void).get(alloc, msg);
defer input.deinit();
log.debug("Req > id {d}, method {s}", .{ input.id, "page.getFrameTree" }); log.debug("Req > id {d}, method {s}", .{ input.id, "page.getFrameTree" });
// output // output
@@ -142,7 +145,8 @@ fn setLifecycleEventsEnabled(
const Params = struct { const Params = struct {
enabled: bool, enabled: bool,
}; };
const input = try msg.getInput(alloc, Params); const input = try Input(Params).get(alloc, msg);
defer input.deinit();
log.debug("Req > id {d}, method {s}", .{ input.id, "page.setLifecycleEventsEnabled" }); log.debug("Req > id {d}, method {s}", .{ input.id, "page.setLifecycleEventsEnabled" });
ctx.state.page_life_cycle_events = true; ctx.state.page_life_cycle_events = true;
@@ -171,7 +175,8 @@ fn addScriptToEvaluateOnNewDocument(
includeCommandLineAPI: bool = false, includeCommandLineAPI: bool = false,
runImmediately: bool = false, runImmediately: bool = false,
}; };
const input = try msg.getInput(alloc, Params); const input = try Input(Params).get(alloc, msg);
defer input.deinit();
log.debug("Req > id {d}, method {s}", .{ input.id, "page.addScriptToEvaluateOnNewDocument" }); log.debug("Req > id {d}, method {s}", .{ input.id, "page.addScriptToEvaluateOnNewDocument" });
// output // output
@@ -205,7 +210,8 @@ fn createIsolatedWorld(
worldName: []const u8, worldName: []const u8,
grantUniveralAccess: bool, grantUniveralAccess: bool,
}; };
const input = try msg.getInput(alloc, Params); const input = try Input(Params).get(alloc, msg);
defer input.deinit();
std.debug.assert(input.sessionId != null); std.debug.assert(input.sessionId != null);
log.debug("Req > id {d}, method {s}", .{ input.id, "page.createIsolatedWorld" }); log.debug("Req > id {d}, method {s}", .{ input.id, "page.createIsolatedWorld" });
@@ -247,7 +253,8 @@ fn navigate(
frameId: ?[]const u8 = null, frameId: ?[]const u8 = null,
referrerPolicy: ?[]const u8 = null, // TODO: enum referrerPolicy: ?[]const u8 = null, // TODO: enum
}; };
const input = try msg.getInput(alloc, Params); const input = try Input(Params).get(alloc, msg);
defer input.deinit();
std.debug.assert(input.sessionId != null); std.debug.assert(input.sessionId != null);
log.debug("Req > id {d}, method {s}", .{ input.id, "page.navigate" }); log.debug("Req > id {d}, method {s}", .{ input.id, "page.navigate" });

View File

@@ -23,6 +23,7 @@ const Ctx = server.Ctx;
const cdp = @import("cdp.zig"); const cdp = @import("cdp.zig");
const result = cdp.result; const result = cdp.result;
const IncomingMessage = @import("msg.zig").IncomingMessage; const IncomingMessage = @import("msg.zig").IncomingMessage;
const Input = @import("msg.zig").Input;
const log = std.log.scoped(.cdp); const log = std.log.scoped(.cdp);
@@ -50,7 +51,8 @@ fn enable(
_: *Ctx, _: *Ctx,
) ![]const u8 { ) ![]const u8 {
// input // input
const input = try msg.getInput(alloc, void); const input = try Input(void).get(alloc, msg);
defer input.deinit();
log.debug("Req > id {d}, method {s}", .{ input.id, "performance.enable" }); log.debug("Req > id {d}, method {s}", .{ input.id, "performance.enable" });
return result(alloc, input.id, null, null, input.sessionId); return result(alloc, input.id, null, null, input.sessionId);

View File

@@ -26,6 +26,7 @@ const Ctx = server.Ctx;
const cdp = @import("cdp.zig"); const cdp = @import("cdp.zig");
const result = cdp.result; const result = cdp.result;
const IncomingMessage = @import("msg.zig").IncomingMessage; const IncomingMessage = @import("msg.zig").IncomingMessage;
const Input = @import("msg.zig").Input;
const stringify = cdp.stringify; const stringify = cdp.stringify;
const log = std.log.scoped(.cdp); const log = std.log.scoped(.cdp);
@@ -77,9 +78,13 @@ fn sendInspector(
userGesture: ?bool = null, userGesture: ?bool = null,
}; };
const input = try msg.getInput(alloc, Params); const input = try Input(Params).get(alloc, msg);
defer input.deinit();
log.debug("Req > id {d}, method {s} (script saved on cache)", .{ input.id, "runtime.evaluate" }); log.debug("Req > id {d}, method {s} (script saved on cache)", .{ input.id, "runtime.evaluate" });
script = input.params.expression; const params = input.params;
const func = try alloc.alloc(u8, params.expression.len);
@memcpy(func, params.expression);
script = func;
id = input.id; id = input.id;
} else if (method == .callFunctionOn) { } else if (method == .callFunctionOn) {
const Params = struct { const Params = struct {
@@ -95,14 +100,19 @@ fn sendInspector(
userGesture: ?bool = null, userGesture: ?bool = null,
}; };
const input = try msg.getInput(alloc, Params); const input = try Input(Params).get(alloc, msg);
defer input.deinit();
log.debug("Req > id {d}, method {s} (script saved on cache)", .{ input.id, "runtime.callFunctionOn" }); log.debug("Req > id {d}, method {s} (script saved on cache)", .{ input.id, "runtime.callFunctionOn" });
script = input.params.functionDeclaration; const params = input.params;
const func = try alloc.alloc(u8, params.functionDeclaration.len);
@memcpy(func, params.functionDeclaration);
script = func;
id = input.id; id = input.id;
} }
if (script) |src| { if (script) |src| {
try cdp.dumpFile(alloc, id, src); try cdp.dumpFile(alloc, id, src);
alloc.free(src);
} }
} }
@@ -163,7 +173,8 @@ fn runIfWaitingForDebugger(
msg: *IncomingMessage, msg: *IncomingMessage,
_: *Ctx, _: *Ctx,
) ![]const u8 { ) ![]const u8 {
const input = try msg.getInput(alloc, void); const input = try Input(void).get(alloc, msg);
defer input.deinit();
log.debug("Req > id {d}, method {s}", .{ input.id, "runtime.runIfWaitingForDebugger" }); log.debug("Req > id {d}, method {s}", .{ input.id, "runtime.runIfWaitingForDebugger" });
return result(alloc, input.id, null, null, input.sessionId); return result(alloc, input.id, null, null, input.sessionId);

View File

@@ -24,6 +24,7 @@ const cdp = @import("cdp.zig");
const result = cdp.result; const result = cdp.result;
const stringify = cdp.stringify; const stringify = cdp.stringify;
const IncomingMessage = @import("msg.zig").IncomingMessage; const IncomingMessage = @import("msg.zig").IncomingMessage;
const Input = @import("msg.zig").Input;
const log = std.log.scoped(.cdp); const log = std.log.scoped(.cdp);
@@ -72,7 +73,8 @@ fn setDiscoverTargets(
_: *Ctx, _: *Ctx,
) ![]const u8 { ) ![]const u8 {
// input // input
const input = try msg.getInput(alloc, void); const input = try Input(void).get(alloc, msg);
defer input.deinit();
log.debug("Req > id {d}, method {s}", .{ input.id, "target.setDiscoverTargets" }); log.debug("Req > id {d}, method {s}", .{ input.id, "target.setDiscoverTargets" });
// output // output
@@ -111,7 +113,8 @@ fn setAutoAttach(
flatten: bool = true, flatten: bool = true,
filter: ?[]TargetFilter = null, filter: ?[]TargetFilter = null,
}; };
const input = try msg.getInput(alloc, Params); const input = try Input(Params).get(alloc, msg);
defer input.deinit();
log.debug("Req > id {d}, method {s}", .{ input.id, "target.setAutoAttach" }); log.debug("Req > id {d}, method {s}", .{ input.id, "target.setAutoAttach" });
// attachedToTarget event // attachedToTarget event
@@ -144,7 +147,8 @@ fn attachToTarget(
targetId: []const u8, targetId: []const u8,
flatten: bool = true, flatten: bool = true,
}; };
const input = try msg.getInput(alloc, Params); const input = try Input(Params).get(alloc, msg);
defer input.deinit();
log.debug("Req > id {d}, method {s}", .{ input.id, "target.attachToTarget" }); log.debug("Req > id {d}, method {s}", .{ input.id, "target.attachToTarget" });
// attachedToTarget event // attachedToTarget event
@@ -180,7 +184,8 @@ fn getTargetInfo(
const Params = struct { const Params = struct {
targetId: ?[]const u8 = null, targetId: ?[]const u8 = null,
}; };
const input = try msg.getInput(alloc, Params); const input = try Input(Params).get(alloc, msg);
defer input.deinit();
log.debug("Req > id {d}, method {s}", .{ input.id, "target.getTargetInfo" }); log.debug("Req > id {d}, method {s}", .{ input.id, "target.getTargetInfo" });
// output // output
@@ -213,7 +218,8 @@ fn getBrowserContexts(
ctx: *Ctx, ctx: *Ctx,
) ![]const u8 { ) ![]const u8 {
// input // input
const input = try msg.getInput(alloc, void); const input = try Input(void).get(alloc, msg);
defer input.deinit();
log.debug("Req > id {d}, method {s}", .{ input.id, "target.getBrowserContexts" }); log.debug("Req > id {d}, method {s}", .{ input.id, "target.getBrowserContexts" });
// ouptut // ouptut
@@ -246,7 +252,8 @@ fn createBrowserContext(
proxyBypassList: ?[]const u8 = null, proxyBypassList: ?[]const u8 = null,
originsWithUniversalNetworkAccess: ?[][]const u8 = null, originsWithUniversalNetworkAccess: ?[][]const u8 = null,
}; };
const input = try msg.getInput(alloc, Params); const input = try Input(Params).get(alloc, msg);
defer input.deinit();
log.debug("Req > id {d}, method {s}", .{ input.id, "target.createBrowserContext" }); log.debug("Req > id {d}, method {s}", .{ input.id, "target.createBrowserContext" });
ctx.state.contextID = ContextID; ctx.state.contextID = ContextID;
@@ -279,7 +286,8 @@ fn disposeBrowserContext(
const Params = struct { const Params = struct {
browserContextId: []const u8, browserContextId: []const u8,
}; };
const input = try msg.getInput(alloc, Params); const input = try Input(Params).get(alloc, msg);
defer input.deinit();
log.debug("Req > id {d}, method {s}", .{ input.id, "target.disposeBrowserContext" }); log.debug("Req > id {d}, method {s}", .{ input.id, "target.disposeBrowserContext" });
// output // output
@@ -309,7 +317,8 @@ fn createTarget(
background: bool = false, background: bool = false,
forTab: ?bool = null, forTab: ?bool = null,
}; };
const input = try msg.getInput(alloc, Params); const input = try Input(Params).get(alloc, msg);
defer input.deinit();
log.debug("Req > id {d}, method {s}", .{ input.id, "target.createTarget" }); log.debug("Req > id {d}, method {s}", .{ input.id, "target.createTarget" });
// change CDP state // change CDP state
@@ -326,7 +335,7 @@ fn createTarget(
.targetId = ctx.state.frameID, .targetId = ctx.state.frameID,
.title = "", .title = "",
.url = ctx.state.url, .url = ctx.state.url,
.browserContextId = msg.params.?.browserContextId orelse ContextID, .browserContextId = input.params.browserContextId orelse ContextID,
}, },
.waitingForDebugger = true, .waitingForDebugger = true,
}; };
@@ -360,7 +369,8 @@ fn closeTarget(
const Params = struct { const Params = struct {
targetId: []const u8, targetId: []const u8,
}; };
const input = try msg.getInput(alloc, Params); const input = try Input(Params).get(alloc, msg);
defer input.deinit();
log.debug("Req > id {d}, method {s}", .{ input.id, "target.closeTarget" }); log.debug("Req > id {d}, method {s}", .{ input.id, "target.closeTarget" });
// output // output