@@ -67194,6 +67194,7 @@ function composeDoc(options, directives, { offset, start, value, end }, onError)
67194
67194
next: value ?? end?.[0],
67195
67195
offset,
67196
67196
onError,
67197
+ parentIndent: 0,
67197
67198
startOnNewline: true
67198
67199
});
67199
67200
if (props.found) {
@@ -67336,7 +67337,7 @@ var resolveFlowScalar = __nccwpck_require__(261);
67336
67337
67337
67338
function composeScalar(ctx, token, tagToken, onError) {
67338
67339
const { value, type, comment, range } = token.type === 'block-scalar'
67339
- ? resolveBlockScalar.resolveBlockScalar(token, ctx.options.strict , onError)
67340
+ ? resolveBlockScalar.resolveBlockScalar(ctx, token , onError)
67340
67341
: resolveFlowScalar.resolveFlowScalar(token, ctx.options.strict, onError);
67341
67342
const tagName = tagToken
67342
67343
? ctx.directives.tagName(tagToken.source, msg => onError(tagToken, 'TAG_RESOLVE_FAILED', msg))
@@ -67671,6 +67672,7 @@ function resolveBlockMap({ composeNode, composeEmptyNode }, ctx, bm, onError, ta
67671
67672
next: key ?? sep?.[0],
67672
67673
offset,
67673
67674
onError,
67675
+ parentIndent: bm.indent,
67674
67676
startOnNewline: true
67675
67677
});
67676
67678
const implicitKey = !keyProps.found;
@@ -67713,6 +67715,7 @@ function resolveBlockMap({ composeNode, composeEmptyNode }, ctx, bm, onError, ta
67713
67715
next: value,
67714
67716
offset: keyNode.range[2],
67715
67717
onError,
67718
+ parentIndent: bm.indent,
67716
67719
startOnNewline: !key || key.type === 'block-scalar'
67717
67720
});
67718
67721
offset = valueProps.end;
@@ -67771,9 +67774,9 @@ exports.resolveBlockMap = resolveBlockMap;
67771
67774
67772
67775
var Scalar = __nccwpck_require__(9338);
67773
67776
67774
- function resolveBlockScalar(scalar, strict , onError) {
67777
+ function resolveBlockScalar(ctx, scalar , onError) {
67775
67778
const start = scalar.offset;
67776
- const header = parseBlockScalarHeader(scalar, strict, onError);
67779
+ const header = parseBlockScalarHeader(scalar, ctx.options. strict, onError);
67777
67780
if (!header)
67778
67781
return { value: '', type: null, comment: '', range: [start, start, start] };
67779
67782
const type = header.mode === '>' ? Scalar.Scalar.BLOCK_FOLDED : Scalar.Scalar.BLOCK_LITERAL;
@@ -67815,6 +67818,10 @@ function resolveBlockScalar(scalar, strict, onError) {
67815
67818
if (header.indent === 0)
67816
67819
trimIndent = indent.length;
67817
67820
contentStart = i;
67821
+ if (trimIndent === 0 && !ctx.atRoot) {
67822
+ const message = 'Block scalar values in collections must be indented';
67823
+ onError(offset, 'BAD_INDENT', message);
67824
+ }
67818
67825
break;
67819
67826
}
67820
67827
offset += indent.length + content.length + 1;
@@ -67990,6 +67997,7 @@ function resolveBlockSeq({ composeNode, composeEmptyNode }, ctx, bs, onError, ta
67990
67997
next: value,
67991
67998
offset,
67992
67999
onError,
68000
+ parentIndent: bs.indent,
67993
68001
startOnNewline: true
67994
68002
});
67995
68003
if (!props.found) {
@@ -68106,6 +68114,7 @@ function resolveFlowCollection({ composeNode, composeEmptyNode }, ctx, fc, onErr
68106
68114
next: key ?? sep?.[0],
68107
68115
offset,
68108
68116
onError,
68117
+ parentIndent: fc.indent,
68109
68118
startOnNewline: false
68110
68119
});
68111
68120
if (!props.found) {
@@ -68187,6 +68196,7 @@ function resolveFlowCollection({ composeNode, composeEmptyNode }, ctx, fc, onErr
68187
68196
next: value,
68188
68197
offset: keyNode.range[2],
68189
68198
onError,
68199
+ parentIndent: fc.indent,
68190
68200
startOnNewline: false
68191
68201
});
68192
68202
if (valueProps.found) {
@@ -68518,7 +68528,7 @@ exports.resolveFlowScalar = resolveFlowScalar;
68518
68528
"use strict";
68519
68529
68520
68530
68521
- function resolveProps(tokens, { flow, indicator, next, offset, onError, startOnNewline }) {
68531
+ function resolveProps(tokens, { flow, indicator, next, offset, onError, parentIndent, startOnNewline }) {
68522
68532
let spaceBefore = false;
68523
68533
let atNewline = startOnNewline;
68524
68534
let hasSpace = startOnNewline;
@@ -68527,6 +68537,7 @@ function resolveProps(tokens, { flow, indicator, next, offset, onError, startOnN
68527
68537
let hasNewline = false;
68528
68538
let hasNewlineAfterProp = false;
68529
68539
let reqSpace = false;
68540
+ let tab = null;
68530
68541
let anchor = null;
68531
68542
let tag = null;
68532
68543
let comma = null;
@@ -68540,16 +68551,22 @@ function resolveProps(tokens, { flow, indicator, next, offset, onError, startOnN
68540
68551
onError(token.offset, 'MISSING_CHAR', 'Tags and anchors must be separated from the next token by white space');
68541
68552
reqSpace = false;
68542
68553
}
68554
+ if (tab) {
68555
+ if (atNewline && token.type !== 'comment' && token.type !== 'newline') {
68556
+ onError(tab, 'TAB_AS_INDENT', 'Tabs are not allowed as indentation');
68557
+ }
68558
+ tab = null;
68559
+ }
68543
68560
switch (token.type) {
68544
68561
case 'space':
68545
68562
// At the doc level, tabs at line start may be parsed
68546
68563
// as leading white space rather than indentation.
68547
68564
// In a flow collection, only the parser handles indent.
68548
68565
if (!flow &&
68549
- atNewline &&
68550
- indicator !== 'doc-start' &&
68551
- token.source[0] === '\t')
68552
- onError(token, 'TAB_AS_INDENT', 'Tabs are not allowed as indentation');
68566
+ (indicator !== 'doc-start' || next?.type !== 'flow-collection') &&
68567
+ token.source.includes('\t')) {
68568
+ tab = token;
68569
+ }
68553
68570
hasSpace = true;
68554
68571
break;
68555
68572
case 'comment': {
@@ -68609,7 +68626,8 @@ function resolveProps(tokens, { flow, indicator, next, offset, onError, startOnN
68609
68626
if (found)
68610
68627
onError(token, 'UNEXPECTED_TOKEN', `Unexpected ${token.source} in ${flow ?? 'collection'}`);
68611
68628
found = token;
68612
- atNewline = false;
68629
+ atNewline =
68630
+ indicator === 'seq-item-ind' || indicator === 'explicit-key-ind';
68613
68631
hasSpace = false;
68614
68632
break;
68615
68633
case 'comma':
@@ -68635,8 +68653,14 @@ function resolveProps(tokens, { flow, indicator, next, offset, onError, startOnN
68635
68653
next.type !== 'space' &&
68636
68654
next.type !== 'newline' &&
68637
68655
next.type !== 'comma' &&
68638
- (next.type !== 'scalar' || next.source !== ''))
68656
+ (next.type !== 'scalar' || next.source !== '')) {
68639
68657
onError(next.offset, 'MISSING_CHAR', 'Tags and anchors must be separated from the next token by white space');
68658
+ }
68659
+ if (tab &&
68660
+ ((atNewline && tab.indent <= parentIndent) ||
68661
+ next?.type === 'block-map' ||
68662
+ next?.type === 'block-seq'))
68663
+ onError(tab, 'TAB_AS_INDENT', 'Tabs are not allowed as indentation');
68640
68664
return {
68641
68665
comma,
68642
68666
found,
@@ -70649,7 +70673,7 @@ function resolveAsScalar(token, strict = true, onError) {
70649
70673
case 'double-quoted-scalar':
70650
70674
return resolveFlowScalar.resolveFlowScalar(token, strict, _onError);
70651
70675
case 'block-scalar':
70652
- return resolveBlockScalar.resolveBlockScalar(token, strict, _onError);
70676
+ return resolveBlockScalar.resolveBlockScalar({ options: { strict } }, token , _onError);
70653
70677
}
70654
70678
}
70655
70679
return null;
@@ -71234,11 +71258,11 @@ function isEmpty(ch) {
71234
71258
return false;
71235
71259
}
71236
71260
}
71237
- const hexDigits = '0123456789ABCDEFabcdef'.split(' ');
71238
- const tagChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-#;/?:@&=+$_.!~*'()".split('' );
71239
- const invalidFlowScalarChars = ',[]{}'.split(' ');
71240
- const invalidAnchorChars = ' ,[]{}\n\r\t'.split(' ');
71241
- const isNotAnchorChar = (ch) => !ch || invalidAnchorChars.includes (ch);
71261
+ const hexDigits = new Set('0123456789ABCDEFabcdef ');
71262
+ const tagChars = new Set( "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-#;/?:@&=+$_.!~*'()");
71263
+ const flowIndicatorChars = new Set( ',[]{}');
71264
+ const invalidAnchorChars = new Set( ' ,[]{}\n\r\t');
71265
+ const isNotAnchorChar = (ch) => !ch || invalidAnchorChars.has (ch);
71242
71266
/**
71243
71267
* Splits an input string into lexical tokens, i.e. smaller strings that are
71244
71268
* easily identifiable by `tokens.tokenType()`.
@@ -71680,8 +71704,10 @@ class Lexer {
71680
71704
if (indent >= this.indentNext) {
71681
71705
if (this.blockScalarIndent === -1)
71682
71706
this.indentNext = indent;
71683
- else
71684
- this.indentNext += this.blockScalarIndent;
71707
+ else {
71708
+ this.indentNext =
71709
+ this.blockScalarIndent + (this.indentNext === 0 ? 1 : this.indentNext);
71710
+ }
71685
71711
do {
71686
71712
const cs = this.continueScalar(nl + 1);
71687
71713
if (cs === -1)
@@ -71694,14 +71720,25 @@ class Lexer {
71694
71720
nl = this.buffer.length;
71695
71721
}
71696
71722
}
71697
- if (!this.blockScalarKeep) {
71723
+ // Trailing insufficiently indented tabs are invalid.
71724
+ // To catch that during parsing, we include them in the block scalar value.
71725
+ let i = nl + 1;
71726
+ ch = this.buffer[i];
71727
+ while (ch === ' ')
71728
+ ch = this.buffer[++i];
71729
+ if (ch === '\t') {
71730
+ while (ch === '\t' || ch === ' ' || ch === '\r' || ch === '\n')
71731
+ ch = this.buffer[++i];
71732
+ nl = i - 1;
71733
+ }
71734
+ else if (!this.blockScalarKeep) {
71698
71735
do {
71699
71736
let i = nl - 1;
71700
71737
let ch = this.buffer[i];
71701
71738
if (ch === '\r')
71702
71739
ch = this.buffer[--i];
71703
71740
const lastChar = i; // Drop the line if last char not more indented
71704
- while (ch === ' ' || ch === '\t' )
71741
+ while (ch === ' ')
71705
71742
ch = this.buffer[--i];
71706
71743
if (ch === '\n' && i >= this.pos && i + 1 + indent > lastChar)
71707
71744
nl = i;
@@ -71721,7 +71758,7 @@ class Lexer {
71721
71758
while ((ch = this.buffer[++i])) {
71722
71759
if (ch === ':') {
71723
71760
const next = this.buffer[i + 1];
71724
- if (isEmpty(next) || (inFlow && next === ',' ))
71761
+ if (isEmpty(next) || (inFlow && flowIndicatorChars.has( next) ))
71725
71762
break;
71726
71763
end = i;
71727
71764
}
@@ -71736,7 +71773,7 @@ class Lexer {
71736
71773
else
71737
71774
end = i;
71738
71775
}
71739
- if (next === '#' || (inFlow && invalidFlowScalarChars.includes (next)))
71776
+ if (next === '#' || (inFlow && flowIndicatorChars.has (next)))
71740
71777
break;
71741
71778
if (ch === '\n') {
71742
71779
const cs = this.continueScalar(i + 1);
@@ -71746,7 +71783,7 @@ class Lexer {
71746
71783
}
71747
71784
}
71748
71785
else {
71749
- if (inFlow && invalidFlowScalarChars.includes (ch))
71786
+ if (inFlow && flowIndicatorChars.has (ch))
71750
71787
break;
71751
71788
end = i;
71752
71789
}
@@ -71791,7 +71828,7 @@ class Lexer {
71791
71828
case ':': {
71792
71829
const inFlow = this.flowLevel > 0;
71793
71830
const ch1 = this.charAt(1);
71794
- if (isEmpty(ch1) || (inFlow && invalidFlowScalarChars.includes (ch1))) {
71831
+ if (isEmpty(ch1) || (inFlow && flowIndicatorChars.has (ch1))) {
71795
71832
if (!inFlow)
71796
71833
this.indentNext = this.indentValue + 1;
71797
71834
else if (this.flowKey)
@@ -71816,11 +71853,11 @@ class Lexer {
71816
71853
let i = this.pos + 1;
71817
71854
let ch = this.buffer[i];
71818
71855
while (ch) {
71819
- if (tagChars.includes (ch))
71856
+ if (tagChars.has (ch))
71820
71857
ch = this.buffer[++i];
71821
71858
else if (ch === '%' &&
71822
- hexDigits.includes (this.buffer[i + 1]) &&
71823
- hexDigits.includes (this.buffer[i + 2])) {
71859
+ hexDigits.has (this.buffer[i + 1]) &&
71860
+ hexDigits.has (this.buffer[i + 2])) {
71824
71861
ch = this.buffer[(i += 3)];
71825
71862
}
71826
71863
else
@@ -72228,7 +72265,7 @@ class Parser {
72228
72265
}
72229
72266
else {
72230
72267
Object.assign(it, { key: token, sep: [] });
72231
- this.onKeyLine = !includesToken( it.start, 'explicit-key-ind') ;
72268
+ this.onKeyLine = !it.explicitKey ;
72232
72269
return;
72233
72270
}
72234
72271
break;
@@ -72437,9 +72474,9 @@ class Parser {
72437
72474
return;
72438
72475
}
72439
72476
if (this.indent >= map.indent) {
72440
- const atNextItem = !this.onKeyLine &&
72441
- this.indent === map.indent &&
72442
- it.sep &&
72477
+ const atMapIndent = !this.onKeyLine && this.indent === map.indent;
72478
+ const atNextItem = atMapIndent &&
72479
+ ( it.sep || it.explicitKey) &&
72443
72480
this.type !== 'seq-item-ind';
72444
72481
// For empty nodes, assign newline-separated not indented empty tokens to following node
72445
72482
let start = [];
@@ -72480,25 +72517,26 @@ class Parser {
72480
72517
}
72481
72518
return;
72482
72519
case 'explicit-key-ind':
72483
- if (!it.sep && !includesToken( it.start, 'explicit-key-ind') ) {
72520
+ if (!it.sep && !it.explicitKey ) {
72484
72521
it.start.push(this.sourceToken);
72522
+ it.explicitKey = true;
72485
72523
}
72486
72524
else if (atNextItem || it.value) {
72487
72525
start.push(this.sourceToken);
72488
- map.items.push({ start });
72526
+ map.items.push({ start, explicitKey: true });
72489
72527
}
72490
72528
else {
72491
72529
this.stack.push({
72492
72530
type: 'block-map',
72493
72531
offset: this.offset,
72494
72532
indent: this.indent,
72495
- items: [{ start: [this.sourceToken] }]
72533
+ items: [{ start: [this.sourceToken], explicitKey: true }]
72496
72534
});
72497
72535
}
72498
72536
this.onKeyLine = true;
72499
72537
return;
72500
72538
case 'map-value-ind':
72501
- if (includesToken( it.start, 'explicit-key-ind') ) {
72539
+ if (it.explicitKey ) {
72502
72540
if (!it.sep) {
72503
72541
if (includesToken(it.start, 'newline')) {
72504
72542
Object.assign(it, { key: null, sep: [this.sourceToken] });
@@ -72589,9 +72627,7 @@ class Parser {
72589
72627
default: {
72590
72628
const bv = this.startBlockValue(map);
72591
72629
if (bv) {
72592
- if (atNextItem &&
72593
- bv.type !== 'block-seq' &&
72594
- includesToken(it.start, 'explicit-key-ind')) {
72630
+ if (atMapIndent && bv.type !== 'block-seq') {
72595
72631
map.items.push({ start });
72596
72632
}
72597
72633
this.stack.push(bv);
@@ -72812,7 +72848,7 @@ class Parser {
72812
72848
type: 'block-map',
72813
72849
offset: this.offset,
72814
72850
indent: this.indent,
72815
- items: [{ start }]
72851
+ items: [{ start, explicitKey: true }]
72816
72852
};
72817
72853
}
72818
72854
case 'map-value-ind': {
0 commit comments