goccy / go-yaml

YAML support for the Go language
MIT License
1.14k stars 132 forks source link

go-yaml does not properly set indent for nodes obtained from in-line JSON #324

Open efd6 opened 1 year ago

efd6 commented 1 year ago

The following program shows that nodes derived from in-line JSON do not properly set their indent, resulting in corrupted output.

https://play.golang.com/p/jxYRN0uVB9J

This returns the following output:

processors:
  - date:
      if: "ctx.event?.timezone == null && ctx._temp_?.raw_date != null"
      target_field: "@timestamp"
      on_failure:
    ppend":
    eld": "error.message", "value": "{{{ _ingest.on_failure_message }}}"}}]

Note that the data is correctly deserialised as can be seen when the data is passed through an any and re-serialised, https://play.golang.com/p/6cCkHpw2MYr.

efd6 commented 1 year ago

A work around for this is to apply a mutating visitor to the AST like so https://play.golang.com/p/i3NZO58U-Rs, which should give an indication where the bug is.

type indentVisitor struct{}

func (v indentVisitor) Visit(n ast.Node) ast.Visitor {
    switch n := n.(type) {
    case *ast.MappingValueNode:
        indent := n.GetToken().Position.IndentLevel
        if n.Key.GetToken().Position.IndentLevel <= indent {
            if n, ok := n.Key.(*ast.StringNode); ok {
                n.Token.Position.IndentLevel = indent + 1
            }
        }
    }
    return v
}