Skip to content

Commit 46fb9b8

Browse files
authored
fix: prevent ReDoS in inline link regex title group (#3902)
The title separator in the link regex used [ \t]* which allowed the title group to be probed at every backtrack position of the greedy href group. On long single-line input containing [text]( patterns without a nearby closing ), this produced O(n²) per regex call and O(n³) in the full inline tokenizer. Change [ \t]* to [ \t]+|\n to require actual whitespace before the title. This matches CommonMark spec requirements and eliminates the backtracking cascade. Before: 18K input takes ~36 seconds (event loop blocked) After: 18K input takes ~45ms
1 parent 5b6faee commit 46fb9b8

File tree

2 files changed

+5
-1
lines changed

2 files changed

+5
-1
lines changed

src/rules.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ const tag = edit(
380380

381381
const _inlineLabel = /(?:\[(?:\\[\s\S]|[^\[\]\\])*\]|\\[\s\S]|`+[^`]*?`+(?!`)|[^\[\]\\`])*?/;
382382

383-
const link = edit(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]*(?:\n[ \t]*)?)(title))?\s*\)/)
383+
const link = edit(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]+(?:\n[ \t]*)?|\n[ \t]*)(title))?\s*\)/)
384384
.replace('label', _inlineLabel)
385385
.replace('href', /<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]*/)
386386
.replace('title', /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module.exports = {
2+
markdown: 'a[b](c'.repeat(1000),
3+
html: `<p>${'a[b](c'.repeat(1000)}</p>\n`,
4+
};

0 commit comments

Comments
 (0)