From 49a97dbb664f6f3a1e9cbb1bf42170e850e2ec50 Mon Sep 17 00:00:00 2001 From: sjorsdonkers <72333389+sjorsdonkers@users.noreply.github.com> Date: Thu, 10 Jul 2025 10:26:44 +0200 Subject: [PATCH] fix callback crash with Node.Union --- src/browser/dom/node_filter.zig | 3 +- src/browser/dom/node_iterator.zig | 32 +++++++++++---------- src/browser/dom/tree_walker.zig | 46 ++++++++++++++++--------------- 3 files changed, 43 insertions(+), 38 deletions(-) diff --git a/src/browser/dom/node_filter.zig b/src/browser/dom/node_filter.zig index 54ce6b67..88cb4e57 100644 --- a/src/browser/dom/node_filter.zig +++ b/src/browser/dom/node_filter.zig @@ -19,6 +19,7 @@ const std = @import("std"); const parser = @import("../netsurf.zig"); const Env = @import("../env.zig").Env; +const Node = @import("node.zig").Node; pub const NodeFilter = struct { pub const _FILTER_ACCEPT: u16 = 1; @@ -63,7 +64,7 @@ pub fn verify(what_to_show: u32, filter: ?Env.Function, node: *parser.Node) !Ver // Verify that we aren't filtering it out. if (filter) |f| { - const acceptance = try f.call(u16, .{node}); + const acceptance = try f.call(u16, .{try Node.toInterface(node)}); return switch (acceptance) { NodeFilter._FILTER_ACCEPT => .accept, NodeFilter._FILTER_REJECT => .reject, diff --git a/src/browser/dom/node_iterator.zig b/src/browser/dom/node_iterator.zig index d79812e0..039227af 100644 --- a/src/browser/dom/node_iterator.zig +++ b/src/browser/dom/node_iterator.zig @@ -20,9 +20,11 @@ const std = @import("std"); const parser = @import("../netsurf.zig"); const Env = @import("../env.zig").Env; const NodeFilter = @import("node_filter.zig"); +const Node = @import("node.zig").Node; +const NodeUnion = @import("node.zig").Union; // https://developer.mozilla.org/en-US/docs/Web/API/NodeIterator -// While this is similar to TreeWalker it has it's own implementation as there are several suttle differences +// While this is similar to TreeWalker it has its own implementation as there are several subtle differences // For example: // - nextNode returns the reference node, whereas TreeWalker returns the next node // - Skip and reject are equivalent for NodeIterator, for TreeWalker they are different @@ -66,36 +68,36 @@ pub const NodeIterator = struct { return self.pointer_before_current; } - pub fn get_referenceNode(self: *const NodeIterator) *parser.Node { - return self.reference_node; + pub fn get_referenceNode(self: *const NodeIterator) !NodeUnion { + return try Node.toInterface(self.reference_node); } - pub fn get_root(self: *const NodeIterator) *parser.Node { - return self.root; + pub fn get_root(self: *const NodeIterator) !NodeUnion { + return try Node.toInterface(self.root); } pub fn get_whatToShow(self: *const NodeIterator) u32 { return self.what_to_show; } - pub fn _nextNode(self: *NodeIterator) !?*parser.Node { + pub fn _nextNode(self: *NodeIterator) !?NodeUnion { if (self.pointer_before_current) { // Unlike TreeWalker, NodeIterator starts at the first node self.pointer_before_current = false; if (.accept == try NodeFilter.verify(self.what_to_show, self.filter_func, self.reference_node)) { - return self.reference_node; + return try Node.toInterface(self.reference_node); } } if (try self.firstChild(self.reference_node)) |child| { self.reference_node = child; - return child; + return try Node.toInterface(child); } var current = self.reference_node; while (current != self.root) { if (try self.nextSibling(current)) |sibling| { self.reference_node = sibling; - return sibling; + return try Node.toInterface(sibling); } current = (try parser.nodeParentNode(current)) orelse break; @@ -104,11 +106,11 @@ pub const NodeIterator = struct { return null; } - pub fn _previousNode(self: *NodeIterator) !?*parser.Node { + pub fn _previousNode(self: *NodeIterator) !?NodeUnion { if (!self.pointer_before_current) { self.pointer_before_current = true; if (.accept == try NodeFilter.verify(self.what_to_show, self.filter_func, self.reference_node)) { - return self.reference_node; // Still need to verify as last may be first as well + return try Node.toInterface(self.reference_node); // Still need to verify as last may be first as well } } if (self.reference_node == self.root) return null; @@ -122,18 +124,18 @@ pub const NodeIterator = struct { // Get last child if it has one. if (try self.lastChild(current)) |child| { self.reference_node = child; - return child; + return try Node.toInterface(child); } // Otherwise, this node is our previous one. self.reference_node = current; - return current; + return try Node.toInterface(current); }, .reject, .skip => { // Get last child if it has one. if (try self.lastChild(current)) |child| { self.reference_node = child; - return child; + return try Node.toInterface(child); } }, } @@ -142,7 +144,7 @@ pub const NodeIterator = struct { if (current != self.root) { if (try self.parentNode(current)) |parent| { self.reference_node = parent; - return parent; + return try Node.toInterface(parent); } } diff --git a/src/browser/dom/tree_walker.zig b/src/browser/dom/tree_walker.zig index 22952f97..4822e615 100644 --- a/src/browser/dom/tree_walker.zig +++ b/src/browser/dom/tree_walker.zig @@ -22,6 +22,8 @@ const parser = @import("../netsurf.zig"); const NodeFilter = @import("node_filter.zig"); const Env = @import("../env.zig").Env; const Page = @import("../page.zig").Page; +const Node = @import("node.zig").Node; +const NodeUnion = @import("node.zig").Union; // https://developer.mozilla.org/en-US/docs/Web/API/TreeWalker pub const TreeWalker = struct { @@ -55,12 +57,12 @@ pub const TreeWalker = struct { }; } - pub fn get_root(self: *TreeWalker) *parser.Node { - return self.root; + pub fn get_root(self: *TreeWalker) !NodeUnion { + return try Node.toInterface(self.root); } - pub fn get_currentNode(self: *TreeWalker) *parser.Node { - return self.current_node; + pub fn get_currentNode(self: *TreeWalker) !NodeUnion { + return try Node.toInterface(self.current_node); } pub fn get_whatToShow(self: *TreeWalker) u32 { @@ -157,35 +159,35 @@ pub const TreeWalker = struct { } } - pub fn _firstChild(self: *TreeWalker) !?*parser.Node { + pub fn _firstChild(self: *TreeWalker) !?NodeUnion { if (try self.firstChild(self.current_node)) |child| { self.current_node = child; - return child; + return try Node.toInterface(child); } return null; } - pub fn _lastChild(self: *TreeWalker) !?*parser.Node { + pub fn _lastChild(self: *TreeWalker) !?NodeUnion { if (try self.lastChild(self.current_node)) |child| { self.current_node = child; - return child; + return try Node.toInterface(child); } return null; } - pub fn _nextNode(self: *TreeWalker) !?*parser.Node { + pub fn _nextNode(self: *TreeWalker) !?NodeUnion { if (try self.firstChild(self.current_node)) |child| { self.current_node = child; - return child; + return try Node.toInterface(child); } var current = self.current_node; while (current != self.root) { if (try self.nextSibling(current)) |sibling| { self.current_node = sibling; - return sibling; + return try Node.toInterface(sibling); } current = (try parser.nodeParentNode(current)) orelse break; @@ -194,25 +196,25 @@ pub const TreeWalker = struct { return null; } - pub fn _nextSibling(self: *TreeWalker) !?*parser.Node { + pub fn _nextSibling(self: *TreeWalker) !?NodeUnion { if (try self.nextSibling(self.current_node)) |sibling| { self.current_node = sibling; - return sibling; + return try Node.toInterface(sibling); } return null; } - pub fn _parentNode(self: *TreeWalker) !?*parser.Node { + pub fn _parentNode(self: *TreeWalker) !?NodeUnion { if (try self.parentNode(self.current_node)) |parent| { self.current_node = parent; - return parent; + return try Node.toInterface(parent); } return null; } - pub fn _previousNode(self: *TreeWalker) !?*parser.Node { + pub fn _previousNode(self: *TreeWalker) !?NodeUnion { if (self.current_node == self.root) return null; var current = self.current_node; @@ -224,19 +226,19 @@ pub const TreeWalker = struct { // Get last child if it has one. if (try self.lastChild(current)) |child| { self.current_node = child; - return child; + return try Node.toInterface(child); } // Otherwise, this node is our previous one. self.current_node = current; - return current; + return try Node.toInterface(current); }, .reject => continue, .skip => { // Get last child if it has one. if (try self.lastChild(current)) |child| { self.current_node = child; - return child; + return try Node.toInterface(child); } }, } @@ -245,17 +247,17 @@ pub const TreeWalker = struct { if (current != self.root) { if (try self.parentNode(current)) |parent| { self.current_node = parent; - return parent; + return try Node.toInterface(parent); } } return null; } - pub fn _previousSibling(self: *TreeWalker) !?*parser.Node { + pub fn _previousSibling(self: *TreeWalker) !?NodeUnion { if (try self.previousSibling(self.current_node)) |sibling| { self.current_node = sibling; - return sibling; + return try Node.toInterface(sibling); } return null;