Skip to content

Commit a880b42

Browse files
committed
fix: Do not allow seq with single-line collection value on same line with map key (fixes #603)
1 parent 923d67b commit a880b42

File tree

4 files changed

+28
-11
lines changed

4 files changed

+28
-11
lines changed

src/parse/parser.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,21 @@ export class Parser {
675675
default: {
676676
const bv = this.startBlockValue(map)
677677
if (bv) {
678-
if (atMapIndent && bv.type !== 'block-seq') {
678+
if (bv.type === 'block-seq') {
679+
if (
680+
!it.explicitKey &&
681+
it.sep &&
682+
!includesToken(it.sep, 'newline')
683+
) {
684+
yield* this.pop({
685+
type: 'error',
686+
offset: this.offset,
687+
message: 'Unexpected block-seq-ind on same line with key',
688+
source: this.source
689+
})
690+
return
691+
}
692+
} else if (atMapIndent) {
679693
map.items.push({ start })
680694
}
681695
this.stack.push(bv)

tests/doc/errors.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,17 +89,15 @@ describe('block collections', () => {
8989
test('seq item in mapping', () => {
9090
const src = 'foo: "1"\n- bar\n'
9191
const doc = YAML.parseDocument(src)
92-
expect(doc.errors).toMatchObject(
93-
[
94-
'A block sequence may not be used as an implicit map key',
95-
'Implicit keys need to be on a single line',
96-
'Implicit map keys need to be followed by map values'
97-
].map(msg => ({ message: expect.stringContaining(msg) }))
98-
)
92+
expect(doc.errors).toMatchObject([
93+
{ code: 'MULTILINE_IMPLICIT_KEY' },
94+
{ code: 'UNEXPECTED_TOKEN' },
95+
{ code: 'MISSING_CHAR' }
96+
])
9997
expect(doc.contents).toMatchObject({
10098
items: [
10199
{ key: { value: 'foo' }, value: { value: '1' } },
102-
{ key: { items: [{ value: 'bar' }] }, value: null }
100+
{ key: { value: null }, value: null }
103101
]
104102
})
105103
})
@@ -187,6 +185,11 @@ describe('block collections', () => {
187185
`)
188186
expect(doc.errors).toMatchObject([])
189187
})
188+
189+
test('sequence with compact mapping value on same line with mapping key (#603)', () => {
190+
const doc = YAML.parseDocument('abc: - foo: bar')
191+
expect(doc.errors).toMatchObject([{ code: 'UNEXPECTED_TOKEN' }])
192+
})
190193
})
191194

192195
describe('flow collections', () => {

tests/doc/foldFlowLines.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ describe('double-quoted', () => {
175175
const res = YAML.parse(str)
176176
expect(res[0].key2).toBe(key2)
177177
})
178-
178+
179179
test('minimal (#59)', () => {
180180
const str = `"######\\\\P#"`
181181
expect(fold(str, '', FOLD_QUOTED, options)).toBe(`"######\\\\\\\nP#"`)

tests/line-counter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ test('Parse error, no newlines', () => {
1111
test('Parse error with newlines', () => {
1212
const lineCounter = new LineCounter()
1313
const doc = parseDocument('foo:\n bar: - baz\n', { lineCounter })
14-
expect(doc.errors).toMatchObject([{ pos: [14, 17] }])
14+
expect(doc.errors).toMatchObject([{ pos: [12, 13] }, { pos: [14, 17] }])
1515
expect(lineCounter.lineStarts).toMatchObject([0, 5, 18])
1616
expect(lineCounter.linePos(14)).toMatchObject({ line: 2, col: 10 })
1717
expect(lineCounter.linePos(17)).toMatchObject({ line: 2, col: 13 })

0 commit comments

Comments
 (0)