Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5096f83

Browse files
committed
fix: Require indentation for ? explicit-key contents (fixes #551)
Adds `explicitKey?: true` to CST BlockMap items
1 parent 22f2c6f commit 5096f83

File tree

3 files changed

+32
-13
lines changed

3 files changed

+32
-13
lines changed

src/parse/cst.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,16 @@ export interface BlockMap {
8181
offset: number
8282
indent: number
8383
items: Array<
84-
| { start: SourceToken[]; key?: never; sep?: never; value?: never }
8584
| {
8685
start: SourceToken[]
86+
explicitKey?: true
87+
key?: never
88+
sep?: never
89+
value?: never
90+
}
91+
| {
92+
start: SourceToken[]
93+
explicitKey?: true
8794
key: Token | null
8895
sep: SourceToken[]
8996
value?: Token

src/parse/parser.ts

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ export class Parser {
325325
it.value = token
326326
} else {
327327
Object.assign(it, { key: token, sep: [] })
328-
this.onKeyLine = !includesToken(it.start, 'explicit-key-ind')
328+
this.onKeyLine = !it.explicitKey
329329
return
330330
}
331331
break
@@ -532,7 +532,7 @@ export class Parser {
532532
const atNextItem =
533533
!this.onKeyLine &&
534534
this.indent === map.indent &&
535-
it.sep &&
535+
(it.sep || it.explicitKey) &&
536536
this.type !== 'seq-item-ind'
537537

538538
// For empty nodes, assign newline-separated not indented empty tokens to following node
@@ -572,24 +572,25 @@ export class Parser {
572572
return
573573

574574
case 'explicit-key-ind':
575-
if (!it.sep && !includesToken(it.start, 'explicit-key-ind')) {
575+
if (!it.sep && !it.explicitKey) {
576576
it.start.push(this.sourceToken)
577+
it.explicitKey = true
577578
} else if (atNextItem || it.value) {
578579
start.push(this.sourceToken)
579-
map.items.push({ start })
580+
map.items.push({ start, explicitKey: true })
580581
} else {
581582
this.stack.push({
582583
type: 'block-map',
583584
offset: this.offset,
584585
indent: this.indent,
585-
items: [{ start: [this.sourceToken] }]
586+
items: [{ start: [this.sourceToken], explicitKey: true }]
586587
})
587588
}
588589
this.onKeyLine = true
589590
return
590591

591592
case 'map-value-ind':
592-
if (includesToken(it.start, 'explicit-key-ind')) {
593+
if (it.explicitKey) {
593594
if (!it.sep) {
594595
if (includesToken(it.start, 'newline')) {
595596
Object.assign(it, { key: null, sep: [this.sourceToken] })
@@ -672,11 +673,7 @@ export class Parser {
672673
default: {
673674
const bv = this.startBlockValue(map)
674675
if (bv) {
675-
if (
676-
atNextItem &&
677-
bv.type !== 'block-seq' &&
678-
includesToken(it.start, 'explicit-key-ind')
679-
) {
676+
if (atNextItem && bv.type !== 'block-seq' && it.explicitKey) {
680677
map.items.push({ start })
681678
}
682679
this.stack.push(bv)
@@ -888,7 +885,7 @@ export class Parser {
888885
type: 'block-map',
889886
offset: this.offset,
890887
indent: this.indent,
891-
items: [{ start }]
888+
items: [{ start, explicitKey: true }]
892889
} as BlockMap
893890
}
894891
case 'map-value-ind': {

tests/doc/parse.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,21 @@ describe('maps with no values', () => {
409409
})
410410
})
411411

412+
describe('odd indentations', () => {
413+
test('Block map with empty explicit key (#551)', () => {
414+
const doc = YAML.parseDocument<YAML.YAMLMap, false>('?\n? a')
415+
expect(doc.contents.items).toMatchObject([
416+
{ key: { value: null }, value: null },
417+
{ key: { value: 'a' }, value: null }
418+
])
419+
})
420+
421+
test('Block map with unindented !!null explicit key', () => {
422+
const doc = YAML.parseDocument<YAML.YAMLMap, false>('?\n!!null')
423+
expect(doc.errors).not.toHaveLength(0)
424+
})
425+
})
426+
412427
describe('Excessive entity expansion attacks', () => {
413428
const root = resolve(__dirname, '../artifacts/pr104')
414429
const src1 = readFileSync(resolve(root, 'case1.yml'), 'utf8')

0 commit comments

Comments
 (0)