mirror of
https://github.com/google/go-jsonnet.git
synced 2025-08-07 14:57:24 +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()
|
s := sval.getGoString()
|
||||||
|
|
||||||
isYamlStream := strings.Contains(s, "---")
|
|
||||||
|
|
||||||
elems := []interface{}{}
|
elems := []interface{}{}
|
||||||
d := NewYAMLToJSONDecoder(strings.NewReader(s))
|
d := NewYAMLToJSONDecoder(strings.NewReader(s))
|
||||||
for {
|
for {
|
||||||
@ -1421,7 +1419,7 @@ func builtinParseYAML(i *interpreter, str value) (value, error) {
|
|||||||
elems = append(elems, elem)
|
elems = append(elems, elem)
|
||||||
}
|
}
|
||||||
|
|
||||||
if isYamlStream {
|
if d.IsStream() {
|
||||||
return jsonToValue(i, elems)
|
return jsonToValue(i, elems)
|
||||||
}
|
}
|
||||||
return jsonToValue(i, elems[0])
|
return jsonToValue(i, elems[0])
|
||||||
|
49
testdata/parseYaml.golden
vendored
49
testdata/parseYaml.golden
vendored
@ -1,10 +1,41 @@
|
|||||||
{
|
[
|
||||||
"aaa": { },
|
{
|
||||||
"foo": "bar",
|
"aaa": { },
|
||||||
"xxx": [
|
"foo": "bar",
|
||||||
42,
|
"xxx": [
|
||||||
"asdf",
|
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(
|
[
|
||||||
|||
|
std.parseYaml(text)
|
||||||
foo: bar
|
for text in [
|
||||||
aaa: {}
|
// various node types
|
||||||
ąę: ćż
|
|||
|
||||||
xxx:
|
foo: bar
|
||||||
- 42
|
aaa: {}
|
||||||
- asdf
|
ąę: ćż
|
||||||
- {}
|
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
|
// separating individual documents. It first converts the YAML
|
||||||
// body to JSON, then unmarshals the JSON.
|
// body to JSON, then unmarshals the JSON.
|
||||||
type YAMLToJSONDecoder struct {
|
type YAMLToJSONDecoder struct {
|
||||||
reader Reader
|
reader *YAMLReader
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewYAMLToJSONDecoder decodes YAML documents from the provided
|
// 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
|
// an error. The decoding rules match json.Unmarshal, not
|
||||||
// yaml.Unmarshal.
|
// yaml.Unmarshal.
|
||||||
func (d *YAMLToJSONDecoder) Decode(into interface{}) error {
|
func (d *YAMLToJSONDecoder) Decode(into interface{}) error {
|
||||||
bytes, err := d.reader.Read()
|
bytes, err := d.reader.read()
|
||||||
if err != nil && err != io.EOF {
|
if err != nil && err != io.EOF {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -64,6 +64,10 @@ func (d *YAMLToJSONDecoder) Decode(into interface{}) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *YAMLToJSONDecoder) IsStream() bool {
|
||||||
|
return d.reader.isStream()
|
||||||
|
}
|
||||||
|
|
||||||
// Reader reads bytes
|
// Reader reads bytes
|
||||||
type Reader interface {
|
type Reader interface {
|
||||||
Read() ([]byte, error)
|
Read() ([]byte, error)
|
||||||
@ -72,6 +76,7 @@ type Reader interface {
|
|||||||
// YAMLReader reads YAML
|
// YAMLReader reads YAML
|
||||||
type YAMLReader struct {
|
type YAMLReader struct {
|
||||||
reader Reader
|
reader Reader
|
||||||
|
stream bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewYAMLReader creates a new YAMLReader
|
// NewYAMLReader creates a new YAMLReader
|
||||||
@ -82,7 +87,7 @@ func NewYAMLReader(r *bufio.Reader) *YAMLReader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read returns a full YAML document.
|
// Read returns a full YAML document.
|
||||||
func (r *YAMLReader) Read() ([]byte, error) {
|
func (r *YAMLReader) read() ([]byte, error) {
|
||||||
var buffer bytes.Buffer
|
var buffer bytes.Buffer
|
||||||
for {
|
for {
|
||||||
line, err := r.reader.Read()
|
line, err := r.reader.Read()
|
||||||
@ -96,6 +101,7 @@ func (r *YAMLReader) Read() ([]byte, error) {
|
|||||||
i += sep
|
i += sep
|
||||||
after := line[i:]
|
after := line[i:]
|
||||||
if len(strings.TrimRightFunc(string(after), unicode.IsSpace)) == 0 {
|
if len(strings.TrimRightFunc(string(after), unicode.IsSpace)) == 0 {
|
||||||
|
r.stream = true
|
||||||
if buffer.Len() != 0 {
|
if buffer.Len() != 0 {
|
||||||
return buffer.Bytes(), nil
|
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.
|
// LineReader reads single lines.
|
||||||
type LineReader struct {
|
type LineReader struct {
|
||||||
reader *bufio.Reader
|
reader *bufio.Reader
|
||||||
|
Loading…
Reference in New Issue
Block a user