From 5c0ad869a502d99af279cc41d442e9e5b5d0dc53 Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Sat, 29 Aug 2026 11:15:00 +0800 Subject: [PATCH] crash: fix unsafe element cast .unknown can map to either an Svg.Unknown or Html.Unknown. The dump was assuming HTML when doing a void-tag check, but we can skip the entire issue here since only HTML has void tags. --- src/browser/dump.zig | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/src/browser/dump.zig b/src/browser/dump.zig index 32a8261fd..f3382a537 100644 --- a/src/browser/dump.zig +++ b/src/browser/dump.zig @@ -349,15 +349,15 @@ fn dumpSlotContent(slot: *Slot, opts: Opts, writer: *std.Io.Writer, frame: *Fram } fn isVoidElement(el: *Node.Element) bool { + if (el._namespace != .html) { + // only html has void tags + return false; + } + return switch (el.getTag()) { .area, .base, .br, .col, .embed, .hr, .img, .input, .link, .meta, .param, .source, .track => true, - .unknown => { - const unknown = el.as(Node.Element.Html.Unknown); - if (unknown._tag_name.eql(comptime .wrap("wbr"))) { - return true; - } - return false; - }, + // has no dedicated Tag, so it lands in Html.Unknown. + .unknown => el.as(Node.Element.Html.Unknown)._tag_name.eql(comptime .wrap("wbr")), else => false, }; } @@ -521,6 +521,28 @@ test "dump: void elements have no end tag" { , aw.written()); } +// There are no void SVG elements: every one gets an end tag, including those +// whose tag name is void in HTML, and those with no dedicated Element.Tag +// (which report .unknown, same as an unrecognized HTML element). +test "dump: no svg element is void" { + const frame = try testing.createFrame(); + defer testing.test_session.closeAllPages(); + + const doc = frame.window._document; + const div = try doc.createElement("div", null, frame); + try Frame.parse.htmlAsChildren(frame, div.asNode(), + \\abafter + ); + + var aw: std.Io.Writer.Allocating = .init(testing.allocator); + defer aw.deinit(); + try deep(div.asNode(), .{}, &aw.writer, frame); + + try testing.expectString( + \\
abafter
+ , aw.written()); +} + test "dump: strip.js removes script and noscript" { try expectDump(.{ .strip = .{ .js = true } }, \\