mirror of
https://github.com/google/go-jsonnet.git
synced 2025-08-06 14:27:30 +02:00
Resolves a false-positive detection of multi-doc YAML streams (#693)
Fixes #673.
This commit is contained in:
parent
9c0b362ba7
commit
868d9c6f11
@ -1406,8 +1406,6 @@ func builtinParseYAML(i *interpreter, str value) (value, error) {
|
||||
}
|
||||
s := sval.getGoString()
|
||||
|
||||
isYamlStream := strings.Contains(s, "---")
|
||||
|
||||
elems := []interface{}{}
|
||||
d := NewYAMLToJSONDecoder(strings.NewReader(s))
|
||||
for {
|
||||
@ -1421,7 +1419,7 @@ func builtinParseYAML(i *interpreter, str value) (value, error) {
|
||||
elems = append(elems, elem)
|
||||
}
|
||||
|
||||
if isYamlStream {
|
||||
if d.IsStream() {
|
||||
return jsonToValue(i, elems)
|
||||
}
|
||||
return jsonToValue(i, elems[0])
|
||||
|
49
testdata/parseYaml.golden
vendored
49
testdata/parseYaml.golden
vendored
@ -1,10 +1,41 @@
|
||||
{
|
||||
"aaa": { },
|
||||
"foo": "bar",
|
||||
"xxx": [
|
||||
42,
|
||||
"asdf",
|
||||
{ }
|
||||
[
|
||||
{
|
||||
"aaa": { },
|
||||
"foo": "bar",
|
||||
"xxx": [
|
||||
42,
|
||||
"asdf",
|
||||
{ }
|
||||
],
|
||||
"ąę": "ćż"
|
||||
},
|
||||
[
|
||||
{
|
||||
"a": 1
|
||||
},
|
||||
{
|
||||
"a": 2
|
||||
}
|
||||
],
|
||||
"ąę": "ćż"
|
||||
}
|
||||
[
|
||||
{
|
||||
"a": 1
|
||||
},
|
||||
{
|
||||
"a": 2
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"a": 1
|
||||
},
|
||||
{
|
||||
"a": 2
|
||||
}
|
||||
],
|
||||
{
|
||||
"---a": 2,
|
||||
"a": 1,
|
||||
"a---": 3
|
||||
}
|
||||
]
|
||||
|
57
testdata/parseYaml.jsonnet
vendored
57
testdata/parseYaml.jsonnet
vendored
@ -1,11 +1,46 @@
|
||||
std.parseYaml(
|
||||
|||
|
||||
foo: bar
|
||||
aaa: {}
|
||||
ąę: ćż
|
||||
xxx:
|
||||
- 42
|
||||
- asdf
|
||||
- {}
|
||||
|||
|
||||
)
|
||||
[
|
||||
std.parseYaml(text)
|
||||
for text in [
|
||||
// various node types
|
||||
|||
|
||||
foo: bar
|
||||
aaa: {}
|
||||
ąę: ćż
|
||||
xxx:
|
||||
- 42
|
||||
- asdf
|
||||
- {}
|
||||
|||,
|
||||
|
||||
// Returns an array of documents when there is an explicit document(s), i.e.
|
||||
// the text is a "multi-doc" stream
|
||||
|||
|
||||
---
|
||||
a: 1
|
||||
---
|
||||
a: 2
|
||||
|||,
|
||||
|
||||
// The first document in a "multi-doc" stream can be an implicit document.
|
||||
|||
|
||||
a: 1
|
||||
---
|
||||
a: 2
|
||||
|||,
|
||||
|
||||
// Whitespaces are allowed after the document start marker
|
||||
|||
|
||||
---
|
||||
a: 1
|
||||
---
|
||||
a: 2
|
||||
|||,
|
||||
|
||||
// Document start marker needs a following line break or a whitespace.
|
||||
|||
|
||||
a: 1
|
||||
---a: 2
|
||||
a---: 3
|
||||
|||,
|
||||
]
|
||||
]
|
||||
|
16
yaml.go
16
yaml.go
@ -32,7 +32,7 @@ const separator = "---"
|
||||
// separating individual documents. It first converts the YAML
|
||||
// body to JSON, then unmarshals the JSON.
|
||||
type YAMLToJSONDecoder struct {
|
||||
reader Reader
|
||||
reader *YAMLReader
|
||||
}
|
||||
|
||||
// NewYAMLToJSONDecoder decodes YAML documents from the provided
|
||||
@ -50,7 +50,7 @@ func NewYAMLToJSONDecoder(r io.Reader) *YAMLToJSONDecoder {
|
||||
// an error. The decoding rules match json.Unmarshal, not
|
||||
// yaml.Unmarshal.
|
||||
func (d *YAMLToJSONDecoder) Decode(into interface{}) error {
|
||||
bytes, err := d.reader.Read()
|
||||
bytes, err := d.reader.read()
|
||||
if err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
@ -64,6 +64,10 @@ func (d *YAMLToJSONDecoder) Decode(into interface{}) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *YAMLToJSONDecoder) IsStream() bool {
|
||||
return d.reader.isStream()
|
||||
}
|
||||
|
||||
// Reader reads bytes
|
||||
type Reader interface {
|
||||
Read() ([]byte, error)
|
||||
@ -72,6 +76,7 @@ type Reader interface {
|
||||
// YAMLReader reads YAML
|
||||
type YAMLReader struct {
|
||||
reader Reader
|
||||
stream bool
|
||||
}
|
||||
|
||||
// NewYAMLReader creates a new YAMLReader
|
||||
@ -82,7 +87,7 @@ func NewYAMLReader(r *bufio.Reader) *YAMLReader {
|
||||
}
|
||||
|
||||
// Read returns a full YAML document.
|
||||
func (r *YAMLReader) Read() ([]byte, error) {
|
||||
func (r *YAMLReader) read() ([]byte, error) {
|
||||
var buffer bytes.Buffer
|
||||
for {
|
||||
line, err := r.reader.Read()
|
||||
@ -96,6 +101,7 @@ func (r *YAMLReader) Read() ([]byte, error) {
|
||||
i += sep
|
||||
after := line[i:]
|
||||
if len(strings.TrimRightFunc(string(after), unicode.IsSpace)) == 0 {
|
||||
r.stream = true
|
||||
if buffer.Len() != 0 {
|
||||
return buffer.Bytes(), nil
|
||||
}
|
||||
@ -115,6 +121,10 @@ func (r *YAMLReader) Read() ([]byte, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *YAMLReader) isStream() bool {
|
||||
return r.stream
|
||||
}
|
||||
|
||||
// LineReader reads single lines.
|
||||
type LineReader struct {
|
||||
reader *bufio.Reader
|
||||
|
Loading…
Reference in New Issue
Block a user