Description
std.parseYaml mishandles YAML merge keys (<<: *anchor): merged fields are replaced by a bogus "true" key, and the corruption can extend to the anchor sources themselves.
Reproduction 1
std.parseYaml("base: &b {x: 1}\nchild:\n <<: *b\n y: 2")
Actual (go-jsonnet v0.22.0):
{
"base": {
"x": 1
},
"child": {
"true": 2,
"x": 1
}
}
Expected (YAML merge-key semantics):
{
"base": {
"x": 1
},
"child": {
"x": 1,
"y": 2
}
}
Reproduction 2 (multi-anchor merge)
std.parseYaml("a: &a {x: 1}\nb: &b {y: 2}\nc:\n <<: [*a, *b]")
Actual:
{
"a": {
"x": 1
},
"b": {
"true": 2
},
"c": {
"true": 2,
"x": 1
}
}
Expected:
{
"a": {
"x": 1
},
"b": {
"y": 2
},
"c": {
"x": 1,
"y": 2
}
}
Note b is corrupted as well (y replaced by "true"), even though it is only referenced as an anchor.
Notes
- It looks as if the merge-key sentinel (
<<, represented as a boolean by the YAML library) leaks into converted mappings as the string "true", displacing a real key.
- Both sjsonnet and jrsonnet produce the Expected output for both reproductions.
- Found while differential-testing sjsonnet against go-jsonnet.
Description
std.parseYamlmishandles YAML merge keys (<<: *anchor): merged fields are replaced by a bogus"true"key, and the corruption can extend to the anchor sources themselves.Reproduction 1
std.parseYaml("base: &b {x: 1}\nchild:\n <<: *b\n y: 2")Actual (go-jsonnet v0.22.0):
{ "base": { "x": 1 }, "child": { "true": 2, "x": 1 } }Expected (YAML merge-key semantics):
{ "base": { "x": 1 }, "child": { "x": 1, "y": 2 } }Reproduction 2 (multi-anchor merge)
std.parseYaml("a: &a {x: 1}\nb: &b {y: 2}\nc:\n <<: [*a, *b]")Actual:
{ "a": { "x": 1 }, "b": { "true": 2 }, "c": { "true": 2, "x": 1 } }Expected:
{ "a": { "x": 1 }, "b": { "y": 2 }, "c": { "x": 1, "y": 2 } }Note
bis corrupted as well (yreplaced by"true"), even though it is only referenced as an anchor.Notes
<<, represented as a boolean by the YAML library) leaks into converted mappings as the string"true", displacing a real key.