Skip to content

Commit d98cd1a

Browse files
ccoVeilleingydotnet
authored andcommitted
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 68b6824 commit d98cd1a

File tree

3 files changed

+76
-1
lines changed

3 files changed

+76
-1
lines changed

decode_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,25 @@ 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./a:r bar\n*b./a:r : quz\n",
619+
map[string]any{"foo": "bar", "bar": "quz"},
620+
},
621+
622+
{
623+
// alias containing a trailing colon is supported, but can be ambiguous
624+
"foo: &bar: bar\n*bar: : quz\n",
625+
map[string]any{"foo": "bar", "bar": "quz"},
626+
},
627+
609628
// Bug #1133337
610629
{
611630
"foo: ''",
@@ -1111,6 +1130,9 @@ var unmarshalErrorTests = []struct {
11111130
{"a: 1\nb: 2\nc 2\nd: 3\n", "^yaml: line 3: could not find expected ':'$"},
11121131
{"#\n-\n{", "yaml: line 3: could not find expected ':'"}, // Issue #665
11131132
{"0: [:!00 \xef", "yaml: incomplete UTF-8 octet sequence"}, // Issue #666
1133+
// anchor must be followed by a space in mapping node
1134+
// https://github.com/yaml/go-yaml/issues/109
1135+
{"foo: bar\n*bar: quz\n", "^yaml: line 2: could not find expected ':'$"},
11141136
{
11151137
"a: &a [00,00,00,00,00,00,00,00,00]\n" +
11161138
"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
@@ -1128,6 +1128,50 @@ var nodeTests = []struct {
11281128
},
11291129
}},
11301130
},
1131+
}, {
1132+
"a: &x: 1\n*x: : c\n",
1133+
yaml.Node{
1134+
Kind: yaml.DocumentNode,
1135+
Line: 1,
1136+
Column: 1,
1137+
Content: []*yaml.Node{{
1138+
Kind: yaml.MappingNode,
1139+
Line: 1,
1140+
Column: 1,
1141+
Tag: "!!map",
1142+
Content: []*yaml.Node{
1143+
{
1144+
Kind: yaml.ScalarNode,
1145+
Value: "a",
1146+
Tag: "!!str",
1147+
Line: 1,
1148+
Column: 1,
1149+
},
1150+
saveNode("x:", &yaml.Node{
1151+
Kind: yaml.ScalarNode,
1152+
Value: "1",
1153+
Tag: "!!int",
1154+
Anchor: "x:",
1155+
Line: 1,
1156+
Column: 4,
1157+
}),
1158+
{
1159+
Kind: yaml.AliasNode,
1160+
Value: "x:",
1161+
Alias: dropNode("x:"),
1162+
Line: 2,
1163+
Column: 1,
1164+
},
1165+
{
1166+
Kind: yaml.ScalarNode,
1167+
Value: "c",
1168+
Tag: "!!str",
1169+
Line: 2,
1170+
Column: 7,
1171+
},
1172+
},
1173+
}},
1174+
},
11311175
}, {
11321176
"a: &anchor(.!@#$%^&*+=?:;)name [1, 2]\nb: *anchor(.!@#$%^&*+=?:;)name\n",
11331177
yaml.Node{

0 commit comments

Comments
 (0)