test(fleet): close markdown scanner bypasses
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -475,6 +475,18 @@ function codeSurfaceDiagnostics(path: string, source: string): SurfaceDiagnostic
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (/^(?: {0,3}(?:(?:> ?)|(?:(?:[-+*]|[0-9]{1,9}[.)]) +)))+(`{3,}|~{3,})/.test(line)) {
|
||||||
|
diagnostics.push({ path, line: lineNumber, code: 'fence-context' });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (/^(?: {4,}|\t).*\S/.test(line)) {
|
||||||
|
diagnostics.push({ path, line: lineNumber, code: 'indented-code' });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (/`{2,}/.test(line) && !/^```[a-z-]+$/.test(line)) {
|
||||||
|
diagnostics.push({ path, line: lineNumber, code: 'inline-delimiter' });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const marker = line.match(/^(`{3,}|~{3,})(.*)$/);
|
const marker = line.match(/^(`{3,}|~{3,})(.*)$/);
|
||||||
if (marker !== null) {
|
if (marker !== null) {
|
||||||
block += 1;
|
block += 1;
|
||||||
@@ -495,15 +507,7 @@ function codeSurfaceDiagnostics(path: string, source: string): SurfaceDiagnostic
|
|||||||
inFence = true;
|
inFence = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (/^(?: {1,3}| {0,3}(?:>|[-+*]|[0-9]{1,9}[.)]) )(`{3,}|~{3,})/.test(line)) {
|
if (/<\/?(?:pre|code|script|style|xmp|listing)(?=$|\s|[>/])/i.test(line)) {
|
||||||
diagnostics.push({ path, line: lineNumber, code: 'fence-context' });
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (/^(?: {4}|\t)\S/.test(line)) {
|
|
||||||
diagnostics.push({ path, line: lineNumber, code: 'indented-code' });
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (/<\/?(?:pre|code|script|style|xmp|listing)(?:\s|\/?>)/i.test(line)) {
|
|
||||||
diagnostics.push({ path, line: lineNumber, code: 'raw-code-container' });
|
diagnostics.push({ path, line: lineNumber, code: 'raw-code-container' });
|
||||||
}
|
}
|
||||||
for (const match of line.matchAll(/(?<!`)`([^`\n]+)`(?!`)/g)) {
|
for (const match of line.matchAll(/(?<!`)`([^`\n]+)`(?!`)/g)) {
|
||||||
@@ -698,13 +702,58 @@ describe('closed documentation publication grammar', (): void => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('rejects indented code and raw HTML code containers', (): void => {
|
it('rejects inline delimiter runs instead of silently omitting them', (): void => {
|
||||||
expect(codeSurfaceDiagnostics('fixture.md', ' mosaic fleet verify\n')).toEqual([
|
for (const source of ['``literal``', '```literal```', 'text ``literal`` text']) {
|
||||||
|
expect(codeSurfaceDiagnostics('fixture.md', source)).toContainEqual({
|
||||||
|
path: 'fixture.md',
|
||||||
|
line: 1,
|
||||||
|
code: 'inline-delimiter',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejects every nonblank line with four leading spaces or a leading tab', (): void => {
|
||||||
|
for (const source of [
|
||||||
|
' mosaic fleet verify',
|
||||||
|
' mosaic fleet verify',
|
||||||
|
' \tmosaic fleet verify',
|
||||||
|
'\t mosaic fleet verify',
|
||||||
|
]) {
|
||||||
|
expect(codeSurfaceDiagnostics('fixture.md', source)).toEqual([
|
||||||
{ path: 'fixture.md', line: 1, code: 'indented-code' },
|
{ path: 'fixture.md', line: 1, code: 'indented-code' },
|
||||||
]);
|
]);
|
||||||
expect(codeSurfaceDiagnostics('fixture.md', '<pre>mosaic fleet verify</pre>\n')).toEqual([
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejects raw HTML code-container tag prefixes at every boundary', (): void => {
|
||||||
|
for (const source of [
|
||||||
|
'<pre',
|
||||||
|
'<pre ',
|
||||||
|
'<pre>',
|
||||||
|
'<pre/',
|
||||||
|
'<code',
|
||||||
|
'<code ',
|
||||||
|
'<code>',
|
||||||
|
'<code/',
|
||||||
|
]) {
|
||||||
|
expect(codeSurfaceDiagnostics('fixture.md', source)).toEqual([
|
||||||
{ path: 'fixture.md', line: 1, code: 'raw-code-container' },
|
{ path: 'fixture.md', line: 1, code: 'raw-code-container' },
|
||||||
]);
|
]);
|
||||||
|
}
|
||||||
|
expect(codeSurfaceDiagnostics('fixture.md', '<prelude>prose</prelude>')).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejects nested blockquote and list fence contexts', (): void => {
|
||||||
|
for (const source of [
|
||||||
|
'>> ```fleet-command',
|
||||||
|
'> > ```fleet-command',
|
||||||
|
'> - ```fleet-command',
|
||||||
|
'- > ```fleet-command',
|
||||||
|
]) {
|
||||||
|
expect(codeSurfaceDiagnostics('fixture.md', source)).toEqual([
|
||||||
|
{ path: 'fixture.md', line: 1, code: 'fence-context' },
|
||||||
|
]);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('requires optional metavariables to use bracketed angle notation', (): void => {
|
it('requires optional metavariables to use bracketed angle notation', (): void => {
|
||||||
|
|||||||
Reference in New Issue
Block a user