diff --git a/CHANGELOG.md b/CHANGELOG.md index 40200b2..0240c6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,9 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `[]()` 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 backticks, #733, #736. -- Fix performance issues when parsing emphases, #735. +- Fix performance issues when parsing links (#732, #734), backticks, (#733, #736), + emphases (#735), and autolinks (#737). ## [12.0.2] - 2020-10-23 diff --git a/lib/rules_inline/autolink.js b/lib/rules_inline/autolink.js index 1f0c466..66deb90 100644 --- a/lib/rules_inline/autolink.js +++ b/lib/rules_inline/autolink.js @@ -4,24 +4,31 @@ /*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 AUTOLINK_RE = /^<([a-zA-Z][a-zA-Z0-9+.\-]{1,31}):([^<>\x00-\x20]*)>/; +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]*)$/; module.exports = function autolink(state, silent) { - var tail, linkMatch, emailMatch, url, fullUrl, token, + var url, fullUrl, token, ch, start, max, pos = state.pos; 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)) { - linkMatch = tail.match(AUTOLINK_RE); + ch = state.src.charCodeAt(pos); - 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); if (!state.md.validateLink(fullUrl)) { return false; } @@ -39,14 +46,11 @@ module.exports = function autolink(state, silent) { token.info = 'auto'; } - state.pos += linkMatch[0].length; + state.pos += url.length + 2; return true; } - if (EMAIL_RE.test(tail)) { - emailMatch = tail.match(EMAIL_RE); - - url = emailMatch[0].slice(1, -1); + if (EMAIL_RE.test(url)) { fullUrl = state.md.normalizeLink('mailto:' + url); if (!state.md.validateLink(fullUrl)) { return false; } @@ -64,7 +68,7 @@ module.exports = function autolink(state, silent) { token.info = 'auto'; } - state.pos += emailMatch[0].length; + state.pos += url.length + 2; return true; } diff --git a/test/pathological.js b/test/pathological.js index fbbffdd..af3f90f 100644 --- a/test/pathological.js +++ b/test/pathological.js @@ -126,5 +126,9 @@ describe('Pathological sequences speed', () => { it('backtick ``\\``\\`` pattern', async () => { await test_pattern('``\\'.repeat(50000)); }); + + it('autolinks <<<<...<<> pattern', async () => { + await test_pattern('<'.repeat(400000) + '>'); + }); }); });