Skip to content

Commit 68f47c0

Browse files
committed
XML Decoder: Checking for invalid content outside of a root node #1448
1 parent 02be2b2 commit 68f47c0

File tree

5 files changed

+33
-9
lines changed

5 files changed

+33
-9
lines changed

examples/mike.xml

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
<?xml version="1.0"?>
2-
<!DOCTYPE config SYSTEM "/etc/iwatch/iwatch.dtd" >
3-
<apple>
4-
<?coolioo version="1.0"?>
5-
<!DOCTYPE config SYSTEM "/etc/iwatch/iwatch.dtd" >
6-
<b>things</b>
7-
</apple>
1+
date: "2022-11-25"
2+
raw:
3+
id: 1
4+
XML: text_outside_1<Tag1 />text_outside_2<Tag2Kling Klong</Tag2>text_outside_3
5+
time: 09:19:00

pkg/yqlib/decoder_xml.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package yqlib
33
import (
44
"encoding/xml"
55
"errors"
6+
"fmt"
67
"io"
78
"strings"
89
"unicode"
@@ -226,6 +227,8 @@ func (dec *xmlDecoder) decodeXML(root *xmlNode) error {
226227
// That will convert the charset if the provided XML is non-UTF-8
227228
xmlDec.CharsetReader = charset.NewReaderLabel
228229

230+
started := false
231+
229232
// Create first element from the root node
230233
elem := &element{
231234
parent: nil,
@@ -269,8 +272,13 @@ func (dec *xmlDecoder) decodeXML(root *xmlNode) error {
269272
elem.n.AddChild(dec.prefs.AttributePrefix+a.Name.Local, &xmlNode{Data: []string{a.Value}})
270273
}
271274
case xml.CharData:
275+
272276
// Extract XML data (if any)
273277
newBit := trimNonGraphic(string(se))
278+
if !started && len(newBit) > 0 {
279+
return fmt.Errorf("invalid XML: Encountered chardata [%v] outside of XML node", newBit)
280+
}
281+
274282
if len(newBit) > 0 {
275283
elem.n.Data = append(elem.n.Data, newBit)
276284
elem.state = "chardata"
@@ -309,6 +317,7 @@ func (dec *xmlDecoder) decodeXML(root *xmlNode) error {
309317
elem.n.AddChild(dec.prefs.DirectiveName, &xmlNode{Data: []string{string(se)}})
310318
}
311319
}
320+
started = true
312321
}
313322

314323
return nil

pkg/yqlib/operators_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ type expressionScenario struct {
3131
}
3232

3333
func TestMain(m *testing.M) {
34-
logging.SetLevel(logging.DEBUG, "")
34+
logging.SetLevel(logging.ERROR, "")
3535
Now = func() time.Time {
3636
return time.Date(2021, time.May, 19, 1, 2, 3, 4, time.UTC)
3737
}

pkg/yqlib/xml_test.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,9 +235,15 @@ const expectedXmlWithProcInstAndDirectives = `<?xml version="1.0"?>
235235
var xmlScenarios = []formatScenario{
236236
{
237237
skipDoc: true,
238-
input: "<root>value<!-- comment--> </root>",
238+
input: " <root>value<!-- comment--> </root>",
239239
expected: "root: value # comment\n",
240240
},
241+
{
242+
skipDoc: true,
243+
input: "value<root>value</root>",
244+
expectedError: "bad file 'sample.yml': invalid XML: Encountered chardata [value] outside of XML node",
245+
scenarioType: "decode-error",
246+
},
241247
{
242248
skipDoc: true,
243249
input: "<root> <!-- comment-->value</root>",
@@ -502,6 +508,13 @@ func testXMLScenario(t *testing.T, s formatScenario) {
502508
prefs := NewDefaultXmlPreferences()
503509
prefs.SkipDirectives = true
504510
test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewXMLDecoder(prefs), NewXMLEncoder(2, prefs)), s.description)
511+
case "decode-error":
512+
result, err := processFormatScenario(s, NewXMLDecoder(NewDefaultXmlPreferences()), NewYamlEncoder(2, false, ConfiguredYamlPreferences))
513+
if err == nil {
514+
t.Errorf("Expected error '%v' but it worked: %v", s.expectedError, result)
515+
} else {
516+
test.AssertResultComplexWithContext(t, s.expectedError, err.Error(), s.description)
517+
}
505518
case "encode-error":
506519
result, err := processFormatScenario(s, NewYamlDecoder(ConfiguredYamlPreferences), NewXMLEncoder(2, NewDefaultXmlPreferences()))
507520
if err == nil {

release_notes.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
4.30.5:
2+
- Fixed
3+
- Special thanks to Kopfbremse for finding all the bugs
4+
15
4.30.4:
26
- Fixed bug in automated versioning (snap/brew)
37

0 commit comments

Comments
 (0)