Browse Source

Moved validateLink() to root class

pull/82/head
Vitaly Puzrin 10 years ago
parent
commit
18d80c6f0b
  1. 33
      lib/index.js
  2. 32
      lib/parser_inline.js
  3. 2
      lib/rules_block/reference.js
  4. 4
      lib/rules_core/linkify.js
  5. 4
      lib/rules_inline/autolink.js
  6. 2
      lib/rules_inline/image.js
  7. 2
      lib/rules_inline/link.js
  8. 2
      test/misc.js

33
lib/index.js

@ -11,6 +11,7 @@ var ParserBlock = require('./parser_block');
var ParserInline = require('./parser_inline'); var ParserInline = require('./parser_inline');
var LinkifyIt = require('linkify-it'); var LinkifyIt = require('linkify-it');
var config = { var config = {
'default': require('./presets/default'), 'default': require('./presets/default'),
zero: require('./presets/zero'), 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 * class MarkdownIt
* *
@ -202,6 +219,22 @@ function MarkdownIt(presetName, options) {
**/ **/
this.linkify = new LinkifyIt(); 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 // Expose utils & helpers for easy acces from plugins
/** /**

32
lib/parser_inline.js

@ -7,7 +7,7 @@
var Ruler = require('./ruler'); var Ruler = require('./ruler');
var replaceEntities = require('./common/utils').replaceEntities;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Parser rules // 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() * new ParserInline()
**/ **/
function 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 * ParserInline#ruler -> Ruler
* *

2
lib/rules_block/reference.js

@ -102,7 +102,7 @@ module.exports = function reference(state, startLine, _endLine, silent) {
// ^^^^^^^^^^^ parse this // ^^^^^^^^^^^ parse this
res = parseLinkDestination(str, pos, max); res = parseLinkDestination(str, pos, max);
if (!res.ok) { return false; } 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; href = res.str;
pos = res.pos; pos = res.pos;
lines += res.lines; lines += res.lines;

4
lib/rules_core/linkify.js

@ -1,6 +1,6 @@
// Replace link-like texts with link nodes. // 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'; 'use strict';
@ -69,7 +69,7 @@ module.exports = function linkify(state) {
for (ln = 0; ln < links.length; ln++) { 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; pos = links[ln].index;

4
lib/rules_inline/autolink.js

@ -28,7 +28,7 @@ module.exports = function autolink(state, silent) {
url = linkMatch[0].slice(1, -1); url = linkMatch[0].slice(1, -1);
fullUrl = normalizeLink(url); fullUrl = normalizeLink(url);
if (!state.md.inline.validateLink(url)) { return false; } if (!state.md.validateLink(url)) { return false; }
if (!silent) { if (!silent) {
token = state.push('link_open', 'a', 1); token = state.push('link_open', 'a', 1);
@ -51,7 +51,7 @@ module.exports = function autolink(state, silent) {
url = emailMatch[0].slice(1, -1); url = emailMatch[0].slice(1, -1);
fullUrl = normalizeLink('mailto:' + url); fullUrl = normalizeLink('mailto:' + url);
if (!state.md.inline.validateLink(fullUrl)) { return false; } if (!state.md.validateLink(fullUrl)) { return false; }
if (!silent) { if (!silent) {
token = state.push('link_open', 'a', 1); token = state.push('link_open', 'a', 1);

2
lib/rules_inline/image.js

@ -53,7 +53,7 @@ module.exports = function image(state, silent) {
// ^^^^^^ parsing link destination // ^^^^^^ parsing link destination
start = pos; start = pos;
res = parseLinkDestination(state.src, pos, state.posMax); 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; href = res.str;
pos = res.pos; pos = res.pos;
} else { } else {

2
lib/rules_inline/link.js

@ -51,7 +51,7 @@ module.exports = function link(state, silent) {
// ^^^^^^ parsing link destination // ^^^^^^ parsing link destination
start = pos; start = pos;
res = parseLinkDestination(state.src, pos, state.posMax); 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; href = res.str;
pos = res.pos; pos = res.pos;
} else { } else {

2
test/misc.js

@ -221,7 +221,7 @@ describe('Links validation', function () {
it('Override validator, disable everything', function () { it('Override validator, disable everything', function () {
var md = markdownit({ linkify: true }); var md = markdownit({ linkify: true });
md.inline.validateLink = function () { return false; }; md.validateLink = function () { return false; };
assert.strictEqual(md.render('foo@example.com'), '<p>foo@example.com</p>\n'); assert.strictEqual(md.render('foo@example.com'), '<p>foo@example.com</p>\n');
assert.strictEqual(md.render('http://example.com'), '<p>http://example.com</p>\n'); assert.strictEqual(md.render('http://example.com'), '<p>http://example.com</p>\n');

Loading…
Cancel
Save