Skip to content

Commit ade13e8

Browse files
committed
Fix alias emitted in mapping
The idea is to make sure that a YAML alias in a mapping is followed by a space before the : An issue appeared with the refactoring made recently that made sure to respect the YAML specification that allows having a `:` in an anchor and alias name.
1 parent ce7f773 commit ade13e8

File tree

3 files changed

+70
-1
lines changed

3 files changed

+70
-1
lines changed

decode_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,19 @@ var unmarshalTests = []struct {
606606
&struct{ B []int }{[]int{1, 2}},
607607
},
608608

609+
// Bug https://github.com/yaml/go-yaml/issues/109
610+
{
611+
// alias must be followed by a space in mapping node
612+
"foo: &bar bar\n*bar : quz\n",
613+
map[string]any{"foo": "bar", "bar": "quz"},
614+
},
615+
616+
{
617+
// alias can contain various characters specified by the YAML specification
618+
"foo: &b./ar bar\n*b./ar : quz\n",
619+
map[string]any{"foo": "bar", "bar": "quz"},
620+
},
621+
609622
// Bug #1133337
610623
{
611624
"foo: ''",
@@ -1111,6 +1124,9 @@ var unmarshalErrorTests = []struct {
11111124
{"a: 1\nb: 2\nc 2\nd: 3\n", "^yaml: line 3: could not find expected ':'$"},
11121125
{"#\n-\n{", "yaml: line 3: could not find expected ':'"}, // Issue #665
11131126
{"0: [:!00 \xef", "yaml: incomplete UTF-8 octet sequence"}, // Issue #666
1127+
// anchor cannot contain a colon
1128+
// https://github.com/yaml/go-yaml/issues/109
1129+
{"foo: &bar: bar\n*bar: : quz\n", "^yaml: mapping values are not allowed in this context$"},
11141130
{
11151131
"a: &a [00,00,00,00,00,00,00,00,00]\n" +
11161132
"b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]\n" +

emitterc.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -813,7 +813,16 @@ func (emitter *yamlEmitter) emitBlockMappingKey(event *yamlEvent, first bool) bo
813813
}
814814
if emitter.checkSimpleKey() {
815815
emitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE)
816-
return emitter.emitNode(event, false, false, true, true)
816+
if !emitter.emitNode(event, false, false, true, true) {
817+
return false
818+
}
819+
820+
if event.typ == yaml_ALIAS_EVENT {
821+
// make sure there's a space after the alias
822+
return emitter.put(' ')
823+
}
824+
825+
return true
817826
}
818827
if !emitter.writeIndicator([]byte{'?'}, true, false, true) {
819828
return false

node_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,6 +1186,50 @@ var nodeTests = []struct {
11861186
},
11871187
}},
11881188
},
1189+
}, {
1190+
"a: &x 1\n*x : c\n",
1191+
yaml.Node{
1192+
Kind: yaml.DocumentNode,
1193+
Line: 1,
1194+
Column: 1,
1195+
Content: []*yaml.Node{{
1196+
Kind: yaml.MappingNode,
1197+
Line: 1,
1198+
Column: 1,
1199+
Tag: "!!map",
1200+
Content: []*yaml.Node{
1201+
{
1202+
Kind: yaml.ScalarNode,
1203+
Value: "a",
1204+
Tag: "!!str",
1205+
Line: 1,
1206+
Column: 1,
1207+
},
1208+
saveNode("x", &yaml.Node{
1209+
Kind: yaml.ScalarNode,
1210+
Value: "1",
1211+
Tag: "!!int",
1212+
Anchor: "x",
1213+
Line: 1,
1214+
Column: 4,
1215+
}),
1216+
{
1217+
Kind: yaml.AliasNode,
1218+
Value: "x",
1219+
Alias: dropNode("x"),
1220+
Line: 2,
1221+
Column: 1,
1222+
},
1223+
{
1224+
Kind: yaml.ScalarNode,
1225+
Value: "c",
1226+
Tag: "!!str",
1227+
Line: 2,
1228+
Column: 6,
1229+
},
1230+
},
1231+
}},
1232+
},
11891233
}, {
11901234
"# One\n# Two\ntrue # Three\n# Four\n# Five\n",
11911235
yaml.Node{

0 commit comments

Comments
 (0)