Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions testdata/parseYaml.golden
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,18 @@
],
[
null
],
[
{
"foo": "bar"
},
{
"baz": "cuux"
}
],
[
{
"a": 1
}
]
]
19 changes: 19 additions & 0 deletions testdata/parseYaml.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,24 @@
|||,

"---",

// A leading comment before the first document-start marker must not
// produce a spurious null document (issue #660).
|||
# Test
---
foo: bar
---
baz: cuux
|||,

// Multiple leading comments and blank lines before the first marker.
|||
# Comment 1
# Comment 2

---
a: 1
|||,
]
]
25 changes: 25 additions & 0 deletions yaml.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"bufio"
"bytes"
"io"
"strings"

"sigs.k8s.io/yaml"
)
Expand Down Expand Up @@ -85,6 +86,21 @@ func NewYAMLReader(r *bufio.Reader) *YAMLReader {

var docStartMarker = []byte("---")

// isCommentOrWhitespace reports whether all non-empty lines in b are either
// blank or YAML comments (start with '#'). Such content is valid YAML
// frontmatter/preamble that precedes the first document-start marker and does
// not constitute a document by itself.
func isCommentOrWhitespace(b []byte) bool {
for _, line := range strings.Split(string(b), "\n") {
trimmed := strings.TrimSpace(line)
if trimmed == "" || strings.HasPrefix(trimmed, "#") {
continue
}
return false
}
return true
}

// Read returns a full YAML document.
func (r *YAMLReader) read() ([]byte, error) {
for {
Expand All @@ -102,6 +118,15 @@ func (r *YAMLReader) read() ([]byte, error) {
if end == len(line) || line[end] == '\n' || line[end] == ' ' || line[end] == '\t' {
r.stream = true
if r.buffer.Len() != 0 {
// Per YAML spec §9.2, comments and blank lines may appear
// before the first document-start marker without forming a
// document. Discard such preamble instead of emitting a
// spurious null document.
if isCommentOrWhitespace(r.buffer.Bytes()) {
r.buffer.Reset()
r.buffer.Write(line)
continue
}
out := append([]byte(nil), r.buffer.Bytes()...)
r.buffer.Reset()
// The document start marker should be included in the next document.
Expand Down