Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi-line arrays in square brackets cause YAMLSemanticError #113

Closed
klingtnet opened this issue May 20, 2019 · 4 comments
Closed

Multi-line arrays in square brackets cause YAMLSemanticError #113

klingtnet opened this issue May 20, 2019 · 4 comments

Comments

@klingtnet
Copy link

The library fails to parse multi-line arrays in square brackets. I stumbled upon this issue when speccy used this library for parsing the OpenAPI specification. Following is a minimal example to reproduce the issue:

package.json:

{
  "dependencies": {
    "fs": "0.0.1-security",
    "yaml": "^1.5.1"
  }
}

example.yaml:

---
foo:
  bar:
    enum: [
      "abc",
      "cde"
    ]

test.js:

const fs = require('fs');
const YAML = require('yaml');

const file = fs.readFileSync('./example.yaml', 'utf8');
try {
  YAML.parse(file)
} catch (error) {
  console.log(error)
}
$ node test.js
{ YAMLSemanticError: Insufficient indentation in flow collection
    at FlowCollection.parse (/home/anli/code/industrial-fulfillment-api/node_modules/yaml/dist/cst/FlowCollection.js:77:60)
    at ParseContext._defineProperty (/home/anli/code/industrial-fulfillment-api/node_modules/yaml/dist/cst/ParseContext.js:141:25)
    at CollectionItem.parse (/home/anli/code/industrial-fulfillment-api/node_modules/yaml/dist/cst/CollectionIte



m.js:81:19)
    at ParseContext._defineProperty (/home/anli/code/industrial-fulfillment-api/node_modules/yaml/dist/cst/ParseContext.js:141:25)
    at Collection.parse (/home/anli/code/industrial-fulfillment-api/node_modules/yaml/dist/cst/Collection.js:199:20)
    at ParseContext._defineProperty (/home/anli/code/industrial-fulfillment-api/node_modules/yaml/dist/cst/ParseContext.js:157:29)
    at CollectionItem.parse (/home/anli/code/industrial-fulfillment-api/node_modules/yaml/dist/cst/CollectionItem.js:81:19)
    at ParseContext._defineProperty (/home/anli/code/industrial-fulfillment-api/node_modules/yaml/dist/cst/ParseContext.js:141:25)
    at Collection.parse (/home/anli/code/industrial-fulfillment-api/node_modules/yaml/dist/cst/Collection.js:199:20)
    at ParseContext._defineProperty (/home/anli/code/industrial-fulfillment-api/node_modules/yaml/dist/cst/ParseContext.js:157:29)
  name: 'YAMLSemanticError',
  message: 'Insufficient indentation in flow collection',
  source: 
   FlowCollection {
     context: 
      ParseContext {
        parseNode: [Function],
        atLineStart: false,
        inCollection: false,
        inFlow: false,
        indent: 4,
        lineStart: 16,
        parent: [CollectionItem],
        root: [Document],
        src: '---\nfoo:\n  bar:\n    enum: [\n      "abc",\n      "cde"\n    ]' },
     error: [Circular],
     range: Range { start: 26, end: 58 },
     valueRange: Range { start: 26, end: 58 },
     props: [],
     type: 'FLOW_SEQ',
     value: null,
     items: [ [Object], [QuoteDouble], [Object], [QuoteDouble], [Object] ],
     resolved: YAMLSeq { items: [Array], range: [Array], type: 'FLOW_SEQ' } } }

Ruby parses the YAML without problems:

$ cat example.yaml | ruby -e 'require "yaml"; puts YAML.load($stdin)'
{"foo"=>{"bar"=>{"enum"=>["abc", "cde"]}}}

The same goes for PyYAML:

import yaml

with open('example.yaml') as f:
       print(yaml.parse(f.read()))
@klingtnet klingtnet changed the title Multiline arrays in square brackets fail to parse1 Multi-line arrays in square brackets cause YAMLSemanticError May 20, 2019
@eemeli eemeli closed this as completed in 2fa7f54 May 23, 2019
@eemeli
Copy link
Owner

eemeli commented May 23, 2019

I went through the spec yet again, and it's not completely clear that something like this is in fact valid YAML:

foo: {
  bar: baz
}

The test suite does include a test that makes it clear that this would be wrong:

foo: {
bar: baz
}

... while this is completely fine:

{
bar: baz
}

Tracing through the relevant constructions would indicate that even the terminal ] or } char should be indented as much as the preceding parts, which effectively becomes relevant only when a flow collection is the value of a block sequence or mapping, and starts on the same line as its sequence indicator or its key value.

But that's a bit dumb, and as you figured most other libraries don't actually require that -- or maybe I just made a mistake when reading the spec. In any case, I've hopefully fixed this now, and will let it parse without error at least until someone complains.

Other relevant issues on this: #108, #114.

@klingtnet
Copy link
Author

My issue was about arrays split over multiple-lines (see title) and not maps/dictionaries.

# ...
    enum: [
      "abc",
      "cde"
    ]

@perlpunk
Copy link

@eemeli Most libraries even don't care about flow collection indentation at all.
See the output of this example:

nested:
  a:
    b: [
flow style sequence
]

tested with the yaml-editor:https://gist.github.com/6686d1623cb6fc09757932bfbe3a61b5

I can understand why this:

  foo: [
  ]

looks valid, but not this:

  foo: [
]

The YAML spec (as I understand it) is very consistent there. The closing ] or } is part of the flow collection, and there is no exception for it to be not indented.

But it seems a lot of YAML documentes are out there that use this, so your decision to allow it is probably reasonable.

@eemeli
Copy link
Owner

eemeli commented May 26, 2019

@klingtnet Apologies for any confusion; [] flow sequences are handled by the same code as {} flow mappings, and should now work as intended. I also added a test for the example you gave:

test('eemeli/yaml#113', () => {
const src = source`
---
foo:
bar:
enum: [
"abc",
"cde"
]
`
const doc = parse(src)
const barValue = doc[0].contents[0].items[1].node.items[1].node
expect(barValue.items[1].node).toMatchObject({
error: null,
items: [
{ char: '[' },
{ type: 'QUOTE_DOUBLE' },
{ char: ',' },
{ type: 'QUOTE_DOUBLE' },
{ char: ']' }
],
type: 'FLOW_SEQ'
})
})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants