this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

internal/encoding/yaml: support alias to scalars as map keys

This makes the decoder follow aliases in YAML map keys.
Before this commit the decoder would outright reject these keys as
non-scalar keys. This commit adds support specifically for keys which
are aliases to scalar values. YAML also permits non-scalar keys such as
maps / sequences, but there's no equivalent for those in CUE, so we
error out.

Note that this used to work in CUE v0.8.2, before we transitioned
from our own older fork of go-yaml to yaml.v3. The minor regression in
behavior was unintentional and went unnoticed as we lacked test cases.

Fixes #3821.

Closes #3822 as merged as of commit b6c33cdd.

Signed-off-by: Omri Steiner <omri@steiners.co.il>
Change-Id: I53bfc09a40ab0a1bbfabde63db1690dbb9222584
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1213252
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>
Unity-Result: CUE porcuepine <cue.porcuepine@gmail.com>
Reviewed-by: Roger Peppe <rogpeppe@gmail.com>

authored by

Omri Steiner and committed by
Daniel Martí
a6fff277 52d96897

+28 -7
+20 -7
internal/encoding/yaml/decode.go
··· 390 390 } 391 391 continue 392 392 } 393 - if yk.Kind != yaml.ScalarNode { 394 - return d.posErrorf(yn, "invalid map key: %v", yk.ShortTag()) 395 - } 396 393 397 394 field := &ast.Field{} 398 395 label, err := d.label(yk) ··· 450 447 func (d *decoder) label(yn *yaml.Node) (ast.Label, error) { 451 448 pos := d.pos(yn) 452 449 453 - expr, err := d.scalar(yn) 450 + var expr ast.Expr 451 + var err error 452 + var value string 453 + switch yn.Kind { 454 + case yaml.ScalarNode: 455 + expr, err = d.scalar(yn) 456 + value = yn.Value 457 + case yaml.AliasNode: 458 + if yn.Alias.Kind != yaml.ScalarNode { 459 + return nil, d.posErrorf(yn, "invalid map key: %v", yn.Alias.ShortTag()) 460 + } 461 + expr, err = d.alias(yn) 462 + value = yn.Alias.Value 463 + default: 464 + return nil, d.posErrorf(yn, "invalid map key: %v", yn.ShortTag()) 465 + } 454 466 if err != nil { 455 467 return nil, err 456 468 } 469 + 457 470 switch expr := expr.(type) { 458 471 case *ast.BasicLit: 459 472 if expr.Kind == token.STRING { 460 - if ast.IsValidIdent(yn.Value) && !internal.IsDefOrHidden(yn.Value) { 473 + if ast.IsValidIdent(value) && !internal.IsDefOrHidden(value) { 461 474 return &ast.Ident{ 462 475 NamePos: pos, 463 - Name: yn.Value, 476 + Name: value, 464 477 }, nil 465 478 } 466 479 ast.SetPos(expr, pos) ··· 474 487 }, nil 475 488 476 489 default: 477 - return nil, d.posErrorf(yn, "invalid label "+yn.Value) 490 + return nil, d.posErrorf(yn, "invalid label "+value) 478 491 } 479 492 } 480 493
+8
internal/encoding/yaml/decode_test.go
··· 488 488 "a: &a [1, 2]\nb: *a", 489 489 "a: [1, 2]\nb: [1, 2]", // TODO: a: [1, 2], b: a 490 490 }, 491 + { 492 + `a: &a "b" 493 + *a : "c"`, 494 + `a: "b" 495 + b: "c"`, 496 + }, 491 497 492 498 { 493 499 "foo: ''", ··· 921 927 {"a:\n- b: *,", "test.yaml:2: did not find expected alphabetic or numeric character"}, 922 928 {"a: *b\n", "test.yaml: unknown anchor 'b' referenced"}, 923 929 {"a: &a\n b: *a\n", `test.yaml:2: anchor "a" value contains itself`}, 930 + {"a: &a { b: c }\n*a : foo", "test.yaml:2: invalid map key: !!map"}, 931 + {"a: &a [b]\n*a : foo", "test.yaml:2: invalid map key: !!seq"}, 924 932 {"value: -", "test.yaml: block sequence entries are not allowed in this context"}, 925 933 {"a: !!binary ==", "test.yaml:1: !!binary value contains invalid base64 data"}, 926 934 {"{[.]}", `test.yaml:1: invalid map key: !!seq`},