From 69eaf0d338fd2e5ffb158624cfa68624eca4405a Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Wed, 23 Apr 2025 13:31:05 +0800 Subject: [PATCH] Manually "clone" processing_instruction When you clone a processing_node via the node_clone_node, or directly via the processing_node copy, you end up in _dom_pi_copy: https://github.com/lightpanda-io/libdom/blob/da8b967905a38455e4f6b75cc9ad2767bae3ccde/src/core/pi.c#L104 For whatever, reason, the node created here gets a vtable that doesn't seem compatible with how we cast vtables in netsurf.zig. For now, a simple fix is to create a new new and copy the attributes over. Fixes https://github.com/lightpanda-io/browser/issues/123 and a WPT crash. --- src/browser/dom/processing_instruction.zig | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/browser/dom/processing_instruction.zig b/src/browser/dom/processing_instruction.zig index baf426cb..98e1fd3f 100644 --- a/src/browser/dom/processing_instruction.zig +++ b/src/browser/dom/processing_instruction.zig @@ -20,6 +20,7 @@ const std = @import("std"); const parser = @import("../netsurf.zig"); const Node = @import("node.zig").Node; +const SessionState = @import("../env.zig").SessionState; // https://dom.spec.whatwg.org/#processinginstruction pub const ProcessingInstruction = struct { @@ -35,8 +36,15 @@ pub const ProcessingInstruction = struct { return try parser.nodeName(parser.processingInstructionToNode(self)); } - pub fn _cloneNode(self: *parser.ProcessingInstruction, _: ?bool) !*parser.ProcessingInstruction { - return try parser.processInstructionCopy(self); + // There's something wrong when we try to clone a ProcessInstruction normally. + // The resulting object can't be cast back into a node (it crashes). This is + // a simple workaround. + pub fn _cloneNode(self: *parser.ProcessingInstruction, _: ?bool, state: *SessionState) !*parser.ProcessingInstruction { + return try parser.documentCreateProcessingInstruction( + @ptrCast(state.document), + try get_target(self), + (try get_data(self)) orelse "", + ); } pub fn get_data(self: *parser.ProcessingInstruction) !?[]const u8 { @@ -61,5 +69,6 @@ test "Browser.DOM.ProcessingInstruction" { .{ "pi.data", "foo" }, .{ "let pi2 = pi.cloneNode()", "undefined" }, + .{ "pi2.nodeType", "7" }, }, .{}); }