diff --git a/lib/index.js b/lib/index.js index c0e409e..b303cc1 100644 --- a/lib/index.js +++ b/lib/index.js @@ -11,6 +11,7 @@ var ParserBlock = require('./parser_block'); var ParserInline = require('./parser_inline'); var LinkifyIt = require('linkify-it'); + var config = { 'default': require('./presets/default'), zero: require('./presets/zero'), @@ -18,6 +19,22 @@ var config = { }; +var replaceEntities = require('./common/utils').replaceEntities; +var BAD_PROTOCOLS = [ 'vbscript', 'javascript', 'file' ]; + +function validateLink(url) { + // Care about digital entities "javascript:alert(1)" + var str = replaceEntities(url); + + str = str.trim().toLowerCase(); + + if (str.indexOf(':') >= 0 && BAD_PROTOCOLS.indexOf(str.split(':')[0]) >= 0) { + return false; + } + return true; +} + + /** * class MarkdownIt * @@ -202,6 +219,22 @@ function MarkdownIt(presetName, options) { **/ this.linkify = new LinkifyIt(); + /** + * MarkdownIt#validateLink(url) -> Boolean + * + * Link validation function. CommonMark allows too much in links. By default + * we disable `javascript:` and `vbscript:` schemas. You can change this + * behaviour. + * + * ```javascript + * var md = require('markdown-it')(); + * // enable everything + * md.validateLink = function () { return true; } + * ``` + **/ + this.validateLink = validateLink; + + // Expose utils & helpers for easy acces from plugins /** diff --git a/lib/parser_inline.js b/lib/parser_inline.js index 1313182..58f8351 100644 --- a/lib/parser_inline.js +++ b/lib/parser_inline.js @@ -7,7 +7,7 @@ var Ruler = require('./ruler'); -var replaceEntities = require('./common/utils').replaceEntities; + //////////////////////////////////////////////////////////////////////////////// // Parser rules @@ -27,40 +27,10 @@ var _rules = [ ]; -var BAD_PROTOCOLS = [ 'vbscript', 'javascript', 'file' ]; - -function validateLink(url) { - // Care about digital entities "javascript:alert(1)" - var str = replaceEntities(url); - - str = str.trim().toLowerCase(); - - if (str.indexOf(':') >= 0 && BAD_PROTOCOLS.indexOf(str.split(':')[0]) >= 0) { - return false; - } - return true; -} - - /** * new ParserInline() **/ function ParserInline() { - /** - * ParserInline#validateLink(url) -> Boolean - * - * Link validation function. CommonMark allows too much in links. By default - * we disable `javascript:` and `vbscript:` schemas. You can change this - * behaviour. - * - * ```javascript - * var md = require('markdown-it')(); - * // enable everything - * md.inline.validateLink = function () { return true; } - * ``` - **/ - this.validateLink = validateLink; - /** * ParserInline#ruler -> Ruler * diff --git a/lib/rules_block/reference.js b/lib/rules_block/reference.js index 60f5c37..73fe5a0 100644 --- a/lib/rules_block/reference.js +++ b/lib/rules_block/reference.js @@ -102,7 +102,7 @@ module.exports = function reference(state, startLine, _endLine, silent) { // ^^^^^^^^^^^ parse this res = parseLinkDestination(str, pos, max); if (!res.ok) { return false; } - if (!state.md.inline.validateLink(res.str)) { return false; } + if (!state.md.validateLink(res.str)) { return false; } href = res.str; pos = res.pos; lines += res.lines; diff --git a/lib/rules_core/linkify.js b/lib/rules_core/linkify.js index a1d19dc..7c99a7c 100644 --- a/lib/rules_core/linkify.js +++ b/lib/rules_core/linkify.js @@ -1,6 +1,6 @@ // Replace link-like texts with link nodes. // -// Currently restricted by `inline.validateLink()` to http/https/ftp +// Currently restricted by `md.validateLink()` to http/https/ftp // 'use strict'; @@ -69,7 +69,7 @@ module.exports = function linkify(state) { for (ln = 0; ln < links.length; ln++) { - if (!state.md.inline.validateLink(links[ln].url)) { continue; } + if (!state.md.validateLink(links[ln].url)) { continue; } pos = links[ln].index; diff --git a/lib/rules_inline/autolink.js b/lib/rules_inline/autolink.js index e747e94..f3fa67b 100644 --- a/lib/rules_inline/autolink.js +++ b/lib/rules_inline/autolink.js @@ -28,7 +28,7 @@ module.exports = function autolink(state, silent) { url = linkMatch[0].slice(1, -1); fullUrl = normalizeLink(url); - if (!state.md.inline.validateLink(url)) { return false; } + if (!state.md.validateLink(url)) { return false; } if (!silent) { token = state.push('link_open', 'a', 1); @@ -51,7 +51,7 @@ module.exports = function autolink(state, silent) { url = emailMatch[0].slice(1, -1); fullUrl = normalizeLink('mailto:' + url); - if (!state.md.inline.validateLink(fullUrl)) { return false; } + if (!state.md.validateLink(fullUrl)) { return false; } if (!silent) { token = state.push('link_open', 'a', 1); diff --git a/lib/rules_inline/image.js b/lib/rules_inline/image.js index 86f591f..e5fad98 100644 --- a/lib/rules_inline/image.js +++ b/lib/rules_inline/image.js @@ -53,7 +53,7 @@ module.exports = function image(state, silent) { // ^^^^^^ parsing link destination start = pos; res = parseLinkDestination(state.src, pos, state.posMax); - if (res.ok && state.md.inline.validateLink(res.str)) { + if (res.ok && state.md.validateLink(res.str)) { href = res.str; pos = res.pos; } else { diff --git a/lib/rules_inline/link.js b/lib/rules_inline/link.js index cc21e67..a5e762c 100644 --- a/lib/rules_inline/link.js +++ b/lib/rules_inline/link.js @@ -51,7 +51,7 @@ module.exports = function link(state, silent) { // ^^^^^^ parsing link destination start = pos; res = parseLinkDestination(state.src, pos, state.posMax); - if (res.ok && state.md.inline.validateLink(res.str)) { + if (res.ok && state.md.validateLink(res.str)) { href = res.str; pos = res.pos; } else { diff --git a/test/misc.js b/test/misc.js index 49ca105..7a4d29a 100644 --- a/test/misc.js +++ b/test/misc.js @@ -221,7 +221,7 @@ describe('Links validation', function () { it('Override validator, disable everything', function () { var md = markdownit({ linkify: true }); - md.inline.validateLink = function () { return false; }; + md.validateLink = function () { return false; }; assert.strictEqual(md.render('foo@example.com'), '

foo@example.com

\n'); assert.strictEqual(md.render('http://example.com'), '

http://example.com

\n');