Skip to content

Commit c1c2cda

Browse files
committed
internal/encoding/yaml: canonicalize non-string map keys
We should probably not support non-string map keys at all. But until that time, at the very least canonicalize non-string map keys. Signed-off-by: Marcel van Lohuizen <mpvl@golang.org> Change-Id: Idf6efb83df61c1d5920c6e1515ed27956723924a Signed-off-by: Marcel van Lohuizen <mpvl@golang.org> Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/527817 Unity-Result: CUEcueckoo <cueckoo@cuelang.org> TryBot-Result: CUEcueckoo <cueckoo@cuelang.org> Reviewed-by: Paul Jolly <paul@myitcv.io>
1 parent a83c6c6 commit c1c2cda

File tree

2 files changed

+52
-5
lines changed

2 files changed

+52
-5
lines changed

internal/third_party/yaml/decode.go

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -539,13 +539,35 @@ func (d *decoder) scalar(n *node) ast.Expr {
539539
}
540540

541541
func (d *decoder) label(n *node) ast.Label {
542-
if ast.IsValidIdent(n.value) && !internal.IsDefOrHidden(n.value) {
543-
return d.ident(n, n.value)
542+
pos := d.pos(n.startPos)
543+
544+
switch x := d.scalar(n).(type) {
545+
case *ast.BasicLit:
546+
if x.Kind == token.STRING {
547+
if ast.IsValidIdent(n.value) && !internal.IsDefOrHidden(n.value) {
548+
return &ast.Ident{
549+
NamePos: pos,
550+
Name: n.value,
551+
}
552+
}
553+
ast.SetPos(x, pos)
554+
return x
555+
}
556+
557+
return &ast.BasicLit{
558+
ValuePos: pos,
559+
Kind: token.STRING,
560+
Value: literal.Label.Quote(x.Value),
561+
}
562+
563+
default:
564+
d.p.failf(n.startPos.line, "invalid label: %q", n.value)
544565
}
566+
545567
return &ast.BasicLit{
546-
ValuePos: d.start(n),
568+
ValuePos: pos,
547569
Kind: token.STRING,
548-
Value: literal.Label.Quote(n.value),
570+
Value: "<invalid>",
549571
}
550572
}
551573

internal/third_party/yaml/decode_test.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ var unmarshalTests = []struct {
165165
`"_#foo": 1`,
166166
}, {
167167
"~: null key",
168-
`"~": "null key"`,
168+
`"null": "null key"`,
169169
}, {
170170
`empty:
171171
apple: "newline"`,
@@ -260,6 +260,15 @@ apple: "newline"`,
260260
}, {
261261
"{ a: 1, b: {c: 1} }",
262262
`a: 1, b: {c: 1}`,
263+
}, {
264+
`
265+
True: 1
266+
Null: 1
267+
.Inf: 2
268+
`,
269+
`"true": 1
270+
"null": 1
271+
"+Inf": 2`,
263272
},
264273

265274
// Some cross type conversions
@@ -736,6 +745,22 @@ func TestUnmarshal(t *testing.T) {
736745
}
737746
}
738747

748+
// For debug purposes: do not delete.
749+
func TestX(t *testing.T) {
750+
y := `
751+
`
752+
y = strings.TrimSpace(y)
753+
if len(y) == 0 {
754+
t.Skip()
755+
}
756+
757+
expr, err := callUnmarshal(t, y)
758+
if _, ok := err.(*yaml.TypeError); !ok && err != nil {
759+
t.Fatal(err)
760+
}
761+
t.Error(cueStr(expr))
762+
}
763+
739764
// // TODO(v3): This test should also work when unmarshaling onto an interface{}.
740765
// func (s *S) TestUnmarshalFullTimestamp(c *C) {
741766
// // Full timestamp in same format as encoded. This is confirmed to be

0 commit comments

Comments
 (0)