Skip to content

Commit cd2e36a

Browse files
encoding.xml: fix parsing of single letter tag names (#19815)
1 parent 10160c0 commit cd2e36a

File tree

3 files changed

+92
-3
lines changed

3 files changed

+92
-3
lines changed

vlib/encoding/xml/parser.v

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -534,9 +534,12 @@ fn parse_single_node(first_char u8, mut reader io.Reader) !XMLNode {
534534
if ch == `/` {
535535
return error('XML node cannot start with "</".')
536536
}
537-
contents.write_u8(ch)
538537

539-
for {
538+
if ch != `>` {
539+
contents.write_u8(ch)
540+
}
541+
542+
for ch != `>` {
540543
ch = next_char(mut reader, mut local_buf)!
541544
if ch == `>` {
542545
break
@@ -547,7 +550,7 @@ fn parse_single_node(first_char u8, mut reader io.Reader) !XMLNode {
547550
tag_contents := contents.str().trim_space()
548551

549552
parts := tag_contents.split_any(' \t\n')
550-
name := first_char.ascii_str() + parts[0]
553+
name := if parts.len > 0 { first_char.ascii_str() + parts[0] } else { first_char.ascii_str() }
551554

552555
// Check if it is a self-closing tag
553556
if tag_contents.ends_with('/') {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<sst count="5" uniqueCount="5">
3+
<si>
4+
<t>Item 1</t>
5+
</si>
6+
<si>
7+
<t>Item 2</t>
8+
</si>
9+
<si>
10+
<t>Item 3</t>
11+
</si>
12+
<si>
13+
<t>Item 4</t>
14+
</si>
15+
<si>
16+
<t>Item 5</t>
17+
</si>
18+
</sst>
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
module main
2+
3+
import os
4+
import encoding.xml
5+
6+
fn test_valid_parsing() {
7+
path := os.join_path(os.dir(@FILE), 'shared.xml')
8+
9+
expected := xml.XMLDocument{
10+
root: xml.XMLNode{
11+
name: 'sst'
12+
attributes: {
13+
'count': '5'
14+
'uniqueCount': '5'
15+
}
16+
children: [
17+
xml.XMLNode{
18+
name: 'si'
19+
children: [
20+
xml.XMLNode{
21+
name: 't'
22+
children: ['Item 1']
23+
},
24+
]
25+
},
26+
xml.XMLNode{
27+
name: 'si'
28+
children: [
29+
xml.XMLNode{
30+
name: 't'
31+
children: ['Item 2']
32+
},
33+
]
34+
},
35+
xml.XMLNode{
36+
name: 'si'
37+
children: [
38+
xml.XMLNode{
39+
name: 't'
40+
children: ['Item 3']
41+
},
42+
]
43+
},
44+
xml.XMLNode{
45+
name: 'si'
46+
children: [
47+
xml.XMLNode{
48+
name: 't'
49+
children: ['Item 4']
50+
},
51+
]
52+
},
53+
xml.XMLNode{
54+
name: 'si'
55+
children: [
56+
xml.XMLNode{
57+
name: 't'
58+
children: ['Item 5']
59+
},
60+
]
61+
},
62+
]
63+
}
64+
}
65+
actual := xml.XMLDocument.from_file(path)!
66+
67+
assert expected == actual, 'Parsed XML document should be equal to expected XML document'
68+
}

0 commit comments

Comments
 (0)