From 44efc9caeec07ee6fce44fa5b05aadac0308973c Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Thu, 26 Feb 2026 21:58:49 +0300 Subject: [PATCH] net.html: unmatched closing tag breaks dom parsing (fixes #26619) --- vlib/net/html/dom.v | 5 +++++ vlib/net/html/dom_test.v | 10 ++++++++++ 2 files changed, 15 insertions(+) diff --git a/vlib/net/html/dom.v b/vlib/net/html/dom.v index e84bf1470..435d3f323 100644 --- a/vlib/net/html/dom.v +++ b/vlib/net/html/dom.v @@ -125,6 +125,7 @@ fn (mut dom DocumentObjectModel) construct(tag_list []&Tag) { if is_close_tag(tag) { temp_int = stack.peek() temp_string = tag.name[1..] + old_stack_size := stack.size for !is_null(temp_int) && temp_string != tag_list[temp_int].name && !tag_list[temp_int].closed { dom.print_debug(temp_string + ' >> ' + tag_list[temp_int].name + ' ' + @@ -132,6 +133,10 @@ fn (mut dom DocumentObjectModel) construct(tag_list []&Tag) { stack.pop() temp_int = stack.peek() } + if is_null(temp_int) || temp_string != tag_list[temp_int].name { + stack.size = old_stack_size + continue + } temp_int = stack.peek() temp_int = if !is_null(temp_int) { stack.pop() } else { root_index } if is_null(temp_int) { diff --git a/vlib/net/html/dom_test.v b/vlib/net/html/dom_test.v index be4600717..b891b0a83 100644 --- a/vlib/net/html/dom_test.v +++ b/vlib/net/html/dom_test.v @@ -84,3 +84,13 @@ fn test_search_by_class() { assert shuffled_class_tags.len == 1 assert shuffled_class_tags[0].attributes['class'] == 'complex-0 complex-1 complex-2' } + +fn test_unmatched_close_tag_is_ignored() { + content := '
x
hello
' + mut dom := parse(content) + by_attr := dom.get_tags_by_attribute_value('class', 'news-post') + by_class := dom.get_tags_by_class_name('news-post') + assert by_attr.len == 1 + assert by_class.len == 1 + assert by_class[0].name == 'article' +} -- 2.39.5