diff --git a/src/browser/parser/Parser.zig b/src/browser/parser/Parser.zig
index e313a3dba..d1c87e9b5 100644
--- a/src/browser/parser/Parser.zig
+++ b/src/browser/parser/Parser.zig
@@ -728,6 +728,7 @@ fn _appendCallback(self: *Parser, parent: *Node, node_or_text: h5e.NodeOrText) !
try self.frame.appendNew(parent, child);
},
.text => |txt| try self.appendTextChunk(parent, txt),
+ .failed => {},
}
}
@@ -801,6 +802,7 @@ fn _appendBeforeSiblingCallback(self: *Parser, sibling: *Node, node_or_text: h5e
break :blk child;
},
.text => |txt| try Frame.node_factory.createTextNode(self.frame, txt),
+ .failed => return,
};
try self.frame.insertNodeRelative(parent, node, .{ .before = sibling }, .{});
}
diff --git a/src/browser/parser/html5ever.zig b/src/browser/parser/html5ever.zig
index 4d1a29776..4ccbe73b0 100644
--- a/src/browser/parser/html5ever.zig
+++ b/src/browser/parser/html5ever.zig
@@ -184,12 +184,15 @@ pub const AttributeIterator = extern struct {
pub const NodeOrText = extern struct {
tag: u8,
- node: *anyopaque,
+ // Null for text. Also null for a node when its create callback failed:
+ // html5ever still appends the null ref it got back.
+ node: ?*anyopaque,
text: StringSlice,
pub fn toUnion(self: NodeOrText) Union {
if (self.tag == 0) {
- return .{ .node = @ptrCast(@alignCast(self.node)) };
+ const node = self.node orelse return .failed;
+ return .{ .node = @ptrCast(@alignCast(node)) };
}
return .{ .text = self.text.slice() };
}
@@ -197,6 +200,8 @@ pub const NodeOrText = extern struct {
const Union = union(enum) {
node: *ParsedNode,
text: []const u8,
+ // The create callback failed and already set Parser.err.
+ failed,
};
};
diff --git a/src/browser/tests/domparser.html b/src/browser/tests/domparser.html
index ec1b4c29a..4f328b625 100644
--- a/src/browser/tests/domparser.html
+++ b/src/browser/tests/domparser.html
@@ -506,6 +506,8 @@
'', // duplicate attribute
'1', // undeclared prefix
'',
+ '1x?>', // invalid processing instruction target
+ '1x?>',
]) {
testing.expectEqual(bad + ' -> error', bad + (isError(p.parseFromString(bad, 'text/xml')) ? ' -> error' : ' -> ok'));
}