Skip to content

Commit

Permalink
Merge pull request #157 from mjbvz/dev/mjbvz/cat-back
Browse files Browse the repository at this point in the history
Fix catastrophic backtracking for link shorthand
  • Loading branch information
mjbvz authored Oct 30, 2023
2 parents 8e2917c + 1b5257c commit 2d7a3e9
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 8 deletions.
20 changes: 12 additions & 8 deletions src/languageFeatures/documentLinks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -302,19 +302,19 @@ const referenceLinkPattern = new RegExp(
// [text][ref] or [text][]
/**/r`(?<prefix>` + // Start link prefix
/****/r`!?` + // Optional image ref
/****/r`\[((?:` +// Link text
/****/r`\[(?<text>(?:` +// Link text
/******/r`\\.|` + // escaped character, or...
/******/r`[^\[\]\\]|` + // non bracket char, or...
/******/r`\[[^\[\]]*\]` + // matched bracket pair
/****/`)*)\]` + // end link text
/****/r`\[\s*` + // Start of link def
/**/r`)` + // end link prefix
/**/r`((?:[^\\\]]|\\.)*?)\]` + // link def
/**/r`(?<ref>(?:[^\\\]]|\\.)*?)\]` + // link def

/**/r`|` +

// [shorthand]
/****/r`\[\s*((?:\\.|[^\[\]])+?)\s*\]` +
/****/r`\[\s*(?<shorthand>(?:\\.|[^\[\]\\])+?)\s*\]` +
r`)` +
r`(?![\(])`, // Must not be followed by a paren to avoid matching normal links
'gm');
Expand Down Expand Up @@ -510,6 +510,10 @@ export class MdLinkComputer {

*#getReferenceLinksInText(document: ITextDocument, text: string, startingOffset: number, noLinkRanges: NoLinkRanges): Iterable<MdLink> {
for (const match of text.matchAll(referenceLinkPattern)) {
if (!match.groups) {
continue;
}

const linkStartOffset = startingOffset + (match.index ?? 0);
const linkStart = document.positionAt(linkStartOffset);
if (noLinkRanges.contains(linkStart)) {
Expand All @@ -518,17 +522,17 @@ export class MdLinkComputer {

let hrefStart: lsp.Position;
let hrefEnd: lsp.Position;
let reference = match[3];
let reference = match.groups['ref'];
if (reference === '') { // [ref][],
reference = match[2].trim();
reference = match.groups['text'].trim();
if (!reference) {
continue;
}
const offset = linkStartOffset + 1;
hrefStart = document.positionAt(offset);
hrefEnd = document.positionAt(offset + reference.length);
} else if (reference) { // [text][ref]
const text = match[2];
const text = match.groups['text'];
if (!text) {
// Handle the case ![][cat]
if (!match[0].startsWith('!')) {
Expand All @@ -545,8 +549,8 @@ export class MdLinkComputer {
const offset = linkStartOffset + pre.length;
hrefStart = document.positionAt(offset);
hrefEnd = document.positionAt(offset + reference.length);
} else if (match[4]) { // [ref]
reference = match[4].trim();
} else if (match.groups['shorthand']) { // [ref]
reference = match.groups['shorthand'].trim();
if (!reference) {
continue;
}
Expand Down
9 changes: 9 additions & 0 deletions src/test/documentLinks.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,15 @@ suite('Link computer', () => {

assertLinksEqual(links, []);
});

test('Should not catastrophical backtrack on slashes', async () => {
const links = await getLinksForText(joinLines(
`# symbol`,
String.raw`[\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\`,
));

assertLinksEqual(links, []);
});
});


Expand Down

0 comments on commit 2d7a3e9

Please sign in to comment.