Skip to content

Commit

Permalink
fix: Avoid creating new documents when indentation is wrong (#3)
Browse files Browse the repository at this point in the history
Avoid creating a new document for wrongly indented values. For example
the following creates three documents when it should really complain
about bad indentation at `bar`.

```yaml
a: b
c: > 
  foo
 bar
d: e
```

Also fixes an `errors.As` bug and test cases that had wrong indentation.

Signed-off-by: Charith Ellawala <[email protected]>
  • Loading branch information
charithe authored May 14, 2024
1 parent 0c54559 commit 321c98b
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 21 deletions.
2 changes: 1 addition & 1 deletion internal/errors/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ func (e *syntaxError) As(dest any) bool {
return true
}

return xerrors.As(e, dest)
return false
}

type TypeError struct {
Expand Down
13 changes: 9 additions & 4 deletions parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,7 @@ func (p *parser) parseTag(ctx *context) (*ast.TagNode, error) {
err error
)
switch token.ReservedTagKeyword(tagToken.Value) {
case token.MappingTag,
token.OrderedMapTag:
case token.MappingTag, token.OrderedMapTag:
value, err = p.parseMapping(ctx)
case token.IntegerTag,
token.FloatTag,
Expand All @@ -93,8 +92,7 @@ func (p *parser) parseTag(ctx *context) (*ast.TagNode, error) {
} else {
value = p.parseScalarValue(ctx.currentToken())
}
case token.SequenceTag,
token.SetTag:
case token.SequenceTag, token.SetTag:
err = errors.ErrSyntax(fmt.Sprintf("sorry, currently not supported %s tag", tagToken.Value), tagToken)
default:
// custom tag
Expand Down Expand Up @@ -320,6 +318,7 @@ func (p *parser) parseMappingValue(ctx *context) (ast.Node, error) {
comment := p.parseFootComment(ctx, mapCol)
node.FootComment = comment
}

return node, nil
}

Expand Down Expand Up @@ -691,6 +690,11 @@ func (p *parser) parse(tokens token.Tokens, mode Mode) (*ast.File, error) {
ctx := newContext(tokens, mode)
file := &ast.File{Docs: []*ast.DocumentNode{}}
for ctx.next() {
tok := ctx.currentToken()
if len(file.Docs) > 0 && tok.Position.Column != 1 {
return nil, errors.ErrSyntax("invalid indentation", tok)
}

node, err := p.parseToken(ctx, ctx.currentToken())
if err != nil {
return nil, errors.Wrapf(err, "failed to parse")
Expand All @@ -699,6 +703,7 @@ func (p *parser) parse(tokens token.Tokens, mode Mode) (*ast.File, error) {
if node == nil {
continue
}

if doc, ok := node.(*ast.DocumentNode); ok {
file.Docs = append(file.Docs, doc)
} else {
Expand Down
16 changes: 8 additions & 8 deletions validate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,21 +116,21 @@ name: myDocument
roles:
name: myRole
permissions:
- hello
- how
- are
- you
`,
- hello
- how
- are
- you
`,
ExpectedErr: `[4:7] mapping was used where sequence is expected
1 | ---
2 | name: myDocument
3 | roles:
> 4 | name: myRole
^
5 | permissions:
6 | - hello
7 | - how
8 | `,
6 | - hello
7 | - how
8 | `,
Instance: &struct {
Name string `yaml:"name"`
Roles []struct {
Expand Down
16 changes: 8 additions & 8 deletions yaml_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,11 +212,13 @@ b:
}
}

type ObjectMap map[string]*Object
type ObjectDecl struct {
Name string `yaml:"-"`
*Object `yaml:",inline,anchor"`
}
type (
ObjectMap map[string]*Object
ObjectDecl struct {
Name string `yaml:"-"`
*Object `yaml:",inline,anchor"`
}
)

func (m ObjectMap) MarshalYAML() (interface{}, error) {
newMap := map[string]*ObjectDecl{}
Expand Down Expand Up @@ -740,7 +742,6 @@ hoge:
t.Fatalf("expected:%s but got %s", expected, actual)
}
})

}

func Test_CommentToMapOption(t *testing.T) {
Expand Down Expand Up @@ -1246,7 +1247,6 @@ a: 1 # line
t.Fatalf("expected:\n%s\ngot:\n%s\n", expect, got)
}
})

}
}

Expand Down Expand Up @@ -1275,7 +1275,7 @@ func TestRegisterCustomUnmarshaler(t *testing.T) {
return nil
})
var v T
if err := yaml.Unmarshal([]byte(`"foo: "bar"`), &v); err != nil {
if err := yaml.Unmarshal([]byte(`"foo": "bar"`), &v); err != nil {
t.Fatal(err)
}
if !bytes.Equal(v.Foo, []byte("override")) {
Expand Down

0 comments on commit 321c98b

Please sign in to comment.