From 3fa49bfdb5ab8a2c53671f8363014523d859744d Mon Sep 17 00:00:00 2001 From: Masaaki Goshima Date: Tue, 12 Nov 2024 10:39:52 +0900 Subject: [PATCH] fix validation of map at flow mode (#523) --- parser/parser.go | 37 ++++++++++++++++++++++++++++--------- parser/parser_test.go | 20 ++++++++++++++++++++ 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/parser/parser.go b/parser/parser.go index 846469b7..60f9db57 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -202,7 +202,7 @@ func (p *parser) parseSequence(ctx *context) (*ast.SequenceNode, error) { break } - value, err := p.parseToken(ctx.withIndex(uint(len(node.Values))), p.currentToken()) + value, err := p.parseToken(ctx.withIndex(uint(len(node.Values))).withFlow(true), p.currentToken()) if err != nil { return nil, err } @@ -481,14 +481,8 @@ func (p *parser) parseMappingValue(ctx *context) (ast.Node, error) { ntk = p.nextNotCommentToken() antk = p.afterNextNotCommentToken() } - validationTk := node.Start - if len(node.Values) != 0 { - validationTk = node.Values[len(node.Values)-1].Key.GetToken() - } - if tk := p.nextNotCommentToken(); tk != nil && tk.Position.Line > validationTk.Position.Line && tk.Position.Column > validationTk.Position.Column { - // a: b - // c <= this token is invalid. - return nil, errors.ErrSyntax("value is not allowed in this context", tk) + if err := p.validateMapNextToken(ctx, node); err != nil { + return nil, err } if len(node.Values) == 1 { mapKeyCol := mvnode.Key.GetToken().Position.Column @@ -512,6 +506,31 @@ func (p *parser) parseMappingValue(ctx *context) (ast.Node, error) { return node, nil } +func (p *parser) validateMapNextToken(ctx *context, node *ast.MappingNode) error { + keyTk := node.Start + if len(node.Values) != 0 { + keyTk = node.Values[len(node.Values)-1].Key.GetToken() + } + tk := p.nextNotCommentToken() + if tk == nil { + return nil + } + + if ctx.isFlow && (tk.Type == token.CollectEntryType || tk.Type == token.SequenceEndType || tk.Type == token.MappingEndType) { + // a: { + // key: value + // } , <= if context is flow mode, "," or "]" or "}" is allowed. + return nil + } + + if tk.Position.Line > keyTk.Position.Line && tk.Position.Column > keyTk.Position.Column { + // a: b + // c <= this token is invalid. + return errors.ErrSyntax("value is not allowed in this context", tk) + } + return nil +} + func (p *parser) parseFlowMapNullValue(ctx *context, key ast.MapKeyNode) (*ast.MappingValueNode, error) { tk := p.currentToken() if tk == nil { diff --git a/parser/parser_test.go b/parser/parser_test.go index 78baba9a..b6153bf4 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -96,6 +96,26 @@ func TestParser(t *testing.T) { "a:\n-", "a: {foo}", "a: {foo,bar}", + ` +{ + a: { + b: c + }, + d: e +} +`, + ` +[ + a: { + b: c + }] +`, + ` +{ + a: { + b: c + }} +`, } for _, src := range sources { if _, err := parser.Parse(lexer.Tokenize(src), 0); err != nil {