fix(xml): panic when encoding a sequence tagged as a map
The pre-pass that emits processing instructions first walks Content in
key/value pairs, which is only valid for a mapping, but it gated on
node.Tag instead of node.Kind. A sequence tagged !!map can have an odd
Content length, so Content[i+1] ran off the end:
printf '!!map [cat, dog, fish]\n' | yq -o=xml
panic: runtime error: index out of range [3] with length 3
That pre-pass runs before the switch on node.Kind, which would otherwise
have returned the usual 'cannot encode ... to XML' error.
The same check also skipped well formed mappings that carry a custom
tag, so their processing instructions were dropped: encodeTopLevelMap
then skipped the key as already processed and it disappeared from the
output altogether.
Gate the pre-pass on Kind, as the rest of the file already does in the
switch in Encode, in doEncode and in encodeMap.
This commit is contained in:
1 parent
d4883e8aa2
commit
b0f3a8b909
2 files changed
+15
-1
No files matched your search
@@ -46,7 +46,7 @@ func (e *xmlEncoder) Encode(writer io.Writer, node *CandidateNode) error {
|
|||||||
encoder.Indent("", e.indentString)
|
encoder.Indent("", e.indentString)
|
||||||
var newLine xml.CharData = []byte("\n")
|
var newLine xml.CharData = []byte("\n")
|
||||||
|
|
||||||
if node.Tag == "!!map" {
|
if node.Kind == MappingNode {
|
||||||
// make sure <?xml .. ?> processing instructions are encoded first
|
// make sure <?xml .. ?> processing instructions are encoded first
|
||||||
for i := 0; i < len(node.Content); i += 2 {
|
for i := 0; i < len(node.Content); i += 2 {
|
||||||
key := node.Content[i]
|
key := node.Content[i]
|
||||||
|
|||||||
@@ -557,6 +557,20 @@ var xmlScenarios = []formatScenario{
|
|||||||
expectedError: "cannot encode !!seq to XML - only maps can be encoded",
|
expectedError: "cannot encode !!seq to XML - only maps can be encoded",
|
||||||
scenarioType: "encode-error",
|
scenarioType: "encode-error",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
description: "arrays tagged as maps cannot be encoded",
|
||||||
|
skipDoc: true,
|
||||||
|
input: "!!map [cat, dog, fish]",
|
||||||
|
expectedError: "cannot encode !!map to XML - only maps can be encoded",
|
||||||
|
scenarioType: "encode-error",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "proc instructions of a map with a custom tag",
|
||||||
|
skipDoc: true,
|
||||||
|
input: "!custom\n+p_xml: version=\"1.0\"\na: b\n",
|
||||||
|
expected: "<?xml version=\"1.0\"?>\n<a>b</a>\n",
|
||||||
|
scenarioType: "encode",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
description: "Encode xml: attributes with content",
|
description: "Encode xml: attributes with content",
|
||||||
subdescription: "Fields with the matching xml-content-name is assumed to be content.",
|
subdescription: "Fields with the matching xml-content-name is assumed to be content.",
|
||||||
|
|||||||
Reference in new issue
Block a user