XML Decoder: Checking for invalid content outside of a root node #1448

This commit is contained in:
Mike Farah 2022-11-27 17:46:32 +11:00
parent 02be2b2918
commit 68f47c02c8
5 changed files with 33 additions and 9 deletions

View File

@ -1,7 +1,5 @@
<?xml version="1.0"?> date: "2022-11-25"
<!DOCTYPE config SYSTEM "/etc/iwatch/iwatch.dtd" > raw:
<apple> id: 1
<?coolioo version="1.0"?> XML: text_outside_1<Tag1 />text_outside_2<Tag2Kling Klong</Tag2>text_outside_3
<!DOCTYPE config SYSTEM "/etc/iwatch/iwatch.dtd" > time: 09:19:00
<b>things</b>
</apple>

View File

@ -3,6 +3,7 @@ package yqlib
import ( import (
"encoding/xml" "encoding/xml"
"errors" "errors"
"fmt"
"io" "io"
"strings" "strings"
"unicode" "unicode"
@ -226,6 +227,8 @@ func (dec *xmlDecoder) decodeXML(root *xmlNode) error {
// That will convert the charset if the provided XML is non-UTF-8 // That will convert the charset if the provided XML is non-UTF-8
xmlDec.CharsetReader = charset.NewReaderLabel xmlDec.CharsetReader = charset.NewReaderLabel
started := false
// Create first element from the root node // Create first element from the root node
elem := &element{ elem := &element{
parent: nil, parent: nil,
@ -269,8 +272,13 @@ func (dec *xmlDecoder) decodeXML(root *xmlNode) error {
elem.n.AddChild(dec.prefs.AttributePrefix+a.Name.Local, &xmlNode{Data: []string{a.Value}}) elem.n.AddChild(dec.prefs.AttributePrefix+a.Name.Local, &xmlNode{Data: []string{a.Value}})
} }
case xml.CharData: case xml.CharData:
// Extract XML data (if any) // Extract XML data (if any)
newBit := trimNonGraphic(string(se)) newBit := trimNonGraphic(string(se))
if !started && len(newBit) > 0 {
return fmt.Errorf("invalid XML: Encountered chardata [%v] outside of XML node", newBit)
}
if len(newBit) > 0 { if len(newBit) > 0 {
elem.n.Data = append(elem.n.Data, newBit) elem.n.Data = append(elem.n.Data, newBit)
elem.state = "chardata" elem.state = "chardata"
@ -309,6 +317,7 @@ func (dec *xmlDecoder) decodeXML(root *xmlNode) error {
elem.n.AddChild(dec.prefs.DirectiveName, &xmlNode{Data: []string{string(se)}}) elem.n.AddChild(dec.prefs.DirectiveName, &xmlNode{Data: []string{string(se)}})
} }
} }
started = true
} }
return nil return nil

View File

@ -31,7 +31,7 @@ type expressionScenario struct {
} }
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
logging.SetLevel(logging.DEBUG, "") logging.SetLevel(logging.ERROR, "")
Now = func() time.Time { Now = func() time.Time {
return time.Date(2021, time.May, 19, 1, 2, 3, 4, time.UTC) return time.Date(2021, time.May, 19, 1, 2, 3, 4, time.UTC)
} }

View File

@ -235,9 +235,15 @@ const expectedXmlWithProcInstAndDirectives = `<?xml version="1.0"?>
var xmlScenarios = []formatScenario{ var xmlScenarios = []formatScenario{
{ {
skipDoc: true, skipDoc: true,
input: "<root>value<!-- comment--> </root>", input: " <root>value<!-- comment--> </root>",
expected: "root: value # comment\n", expected: "root: value # comment\n",
}, },
{
skipDoc: true,
input: "value<root>value</root>",
expectedError: "bad file 'sample.yml': invalid XML: Encountered chardata [value] outside of XML node",
scenarioType: "decode-error",
},
{ {
skipDoc: true, skipDoc: true,
input: "<root> <!-- comment-->value</root>", input: "<root> <!-- comment-->value</root>",
@ -502,6 +508,13 @@ func testXMLScenario(t *testing.T, s formatScenario) {
prefs := NewDefaultXmlPreferences() prefs := NewDefaultXmlPreferences()
prefs.SkipDirectives = true prefs.SkipDirectives = true
test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewXMLDecoder(prefs), NewXMLEncoder(2, prefs)), s.description) test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewXMLDecoder(prefs), NewXMLEncoder(2, prefs)), s.description)
case "decode-error":
result, err := processFormatScenario(s, NewXMLDecoder(NewDefaultXmlPreferences()), NewYamlEncoder(2, false, ConfiguredYamlPreferences))
if err == nil {
t.Errorf("Expected error '%v' but it worked: %v", s.expectedError, result)
} else {
test.AssertResultComplexWithContext(t, s.expectedError, err.Error(), s.description)
}
case "encode-error": case "encode-error":
result, err := processFormatScenario(s, NewYamlDecoder(ConfiguredYamlPreferences), NewXMLEncoder(2, NewDefaultXmlPreferences())) result, err := processFormatScenario(s, NewYamlDecoder(ConfiguredYamlPreferences), NewXMLEncoder(2, NewDefaultXmlPreferences()))
if err == nil { if err == nil {

View File

@ -1,3 +1,7 @@
4.30.5:
- Fixed
- Special thanks to Kopfbremse for finding all the bugs
4.30.4: 4.30.4:
- Fixed bug in automated versioning (snap/brew) - Fixed bug in automated versioning (snap/brew)