Browse Source

Fix quadratic complexity in autolinks

close https://github.com/markdown-it/markdown-it/issues/737
pull/745/head
Alex Kocharin 4 years ago
parent
commit
e729b90a1d
  1. 5
      CHANGELOG.md
  2. 32
      lib/rules_inline/autolink.js
  3. 4
      test/pathological.js

5
CHANGELOG.md

@ -11,9 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `[](<foo<bar>)` is no longer a valid link. - `[](<foo<bar>)` is no longer a valid link.
- `[](url (xxx())` is no longer a valid link. - `[](url (xxx())` is no longer a valid link.
- `[](url\ xxx)` is no longer a valid link. - `[](url\ xxx)` is no longer a valid link.
- Fix performance issues when parsing links, #732, #734. - Fix performance issues when parsing links (#732, #734), backticks, (#733, #736),
- Fix performance issues when parsing backticks, #733, #736. emphases (#735), and autolinks (#737).
- Fix performance issues when parsing emphases, #735.
## [12.0.2] - 2020-10-23 ## [12.0.2] - 2020-10-23

32
lib/rules_inline/autolink.js

@ -4,24 +4,31 @@
/*eslint max-len:0*/ /*eslint max-len:0*/
var EMAIL_RE = /^<([a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)>/; var EMAIL_RE = /^([a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)$/;
var AUTOLINK_RE = /^<([a-zA-Z][a-zA-Z0-9+.\-]{1,31}):([^<>\x00-\x20]*)>/; var AUTOLINK_RE = /^([a-zA-Z][a-zA-Z0-9+.\-]{1,31}):([^<>\x00-\x20]*)$/;
module.exports = function autolink(state, silent) { module.exports = function autolink(state, silent) {
var tail, linkMatch, emailMatch, url, fullUrl, token, var url, fullUrl, token, ch, start, max,
pos = state.pos; pos = state.pos;
if (state.src.charCodeAt(pos) !== 0x3C/* < */) { return false; } if (state.src.charCodeAt(pos) !== 0x3C/* < */) { return false; }
tail = state.src.slice(pos); start = state.pos;
max = state.posMax;
if (tail.indexOf('>') < 0) { return false; } for (;;) {
if (++pos >= max) return false;
if (AUTOLINK_RE.test(tail)) { ch = state.src.charCodeAt(pos);
linkMatch = tail.match(AUTOLINK_RE);
url = linkMatch[0].slice(1, -1); if (ch === 0x3C /* < */) return false;
if (ch === 0x3E /* > */) break;
}
url = state.src.slice(start + 1, pos);
if (AUTOLINK_RE.test(url)) {
fullUrl = state.md.normalizeLink(url); fullUrl = state.md.normalizeLink(url);
if (!state.md.validateLink(fullUrl)) { return false; } if (!state.md.validateLink(fullUrl)) { return false; }
@ -39,14 +46,11 @@ module.exports = function autolink(state, silent) {
token.info = 'auto'; token.info = 'auto';
} }
state.pos += linkMatch[0].length; state.pos += url.length + 2;
return true; return true;
} }
if (EMAIL_RE.test(tail)) { if (EMAIL_RE.test(url)) {
emailMatch = tail.match(EMAIL_RE);
url = emailMatch[0].slice(1, -1);
fullUrl = state.md.normalizeLink('mailto:' + url); fullUrl = state.md.normalizeLink('mailto:' + url);
if (!state.md.validateLink(fullUrl)) { return false; } if (!state.md.validateLink(fullUrl)) { return false; }
@ -64,7 +68,7 @@ module.exports = function autolink(state, silent) {
token.info = 'auto'; token.info = 'auto';
} }
state.pos += emailMatch[0].length; state.pos += url.length + 2;
return true; return true;
} }

4
test/pathological.js

@ -126,5 +126,9 @@ describe('Pathological sequences speed', () => {
it('backtick ``\\``\\`` pattern', async () => { it('backtick ``\\``\\`` pattern', async () => {
await test_pattern('``\\'.repeat(50000)); await test_pattern('``\\'.repeat(50000));
}); });
it('autolinks <<<<...<<> pattern', async () => {
await test_pattern('<'.repeat(400000) + '>');
});
}); });
}); });

Loading…
Cancel
Save