Merge pull request #89 from dead-horse/master

support not escape block code style
This commit is contained in:
fengmk2 2012-09-18 02:01:23 -07:00
commit 293f986d4f
4 changed files with 51 additions and 19 deletions

View File

@ -43,18 +43,37 @@ exports.format_date = function (date, friendly) {
*/
exports.escape = function(html){
var codeReg = /(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm;
var codes = [];
return String(html).replace(/\r\n/g, '\n')
.replace(codeReg, function(code) {
codes.push(code);
return '`uc`';
var codeSpan = /(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm;
var codeBlock = /(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=~0))/g;
var spans = [];
var blocks = [];
var text = String(html).replace(/\r\n/g, '\n')
.replace('/\r/g', '\n');
text = '\n\n' + text + '\n\n';
text = text.replace(codeSpan, function(code) {
spans.push(code);
return '`span`';
});
text += '~0';
return text.replace(codeBlock, function (code) {
blocks.push(code);
return '\n\tblock';
})
.replace(/&(?!\w+;)/g, '&')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/`uc`/g, function() {
return codes.shift();
});
.replace(/`span`/g, function() {
return spans.shift();
})
.replace(/\n\tblock/g, function() {
return blocks.shift();
})
.replace(/~0$/,'')
.replace(/^\n\n/, '')
.replace(/\n\n$/, '');
};

View File

@ -604,6 +604,11 @@ var _DoAnchors = function(text) {
return text;
}
//isUrl in node-validators
var isUrl = function(str) {
return str.match(/^(?:(?:ht|f)tp(?:s?)\:\/\/|~\/|\/)?(?:\w+:\w+@)?(localhost|(?:(?:[-\w\d{1-3}]+\.)+(?:com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|edu|co\.uk|ac\.uk|it|fr|tv|museum|asia|local|travel|[a-z]{2}))|((\b25[0-5]\b|\b[2][0-4][0-9]\b|\b[0-1]?[0-9]?[0-9]\b)(\.(\b25[0-5]\b|\b[2][0-4][0-9]\b|\b[0-1]?[0-9]?[0-9]\b)){3}))(?::[\d]{1,5})?(?:(?:(?:\/(?:[-\w~!$+|.,="'\(\)_\*]|%[a-f\d]{2})+)+|\/)+|\?|#)?(?:(?:\?(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=?(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)(?:&(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=?(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)*)*(?:#(?:[-\w~!$ |\/.,*:;=]|%[a-f\d]{2})*)?$/i) || str.length > 2083;
}
var writeAnchorTag = function(wholeMatch,m1,m2,m3,m4,m5,m6,m7) {
if (m7 == undefined) m7 = "";
var whole_match = m1;
@ -634,9 +639,8 @@ var writeAnchorTag = function(wholeMatch,m1,m2,m3,m4,m5,m6,m7) {
}
}
}
url = decodeURIComponent(url).replace(/"/g,"&quot;");
var urlreg = /(https?|ftp|mms):\/\/([A-z0-9]+[_\-]?[A-z0-9]+\.)*[A-z0-9]+\-?[A-z0-9]+\.[A-z]{2,}(\/.*)*\/?/;
url = urlreg.test(url) ? url : HOST + url;
url = isUrl(url) ? url : HOST + url;
url = escapeCharacters(url,"*_");
var result = "<a href=\"" + url + "\"";
@ -738,9 +742,8 @@ var writeImageTag = function(wholeMatch,m1,m2,m3,m4,m5,m6,m7) {
}
alt_text = alt_text.replace(/"/g,"&quot;");
url = decodeURIComponent(url).replace(/"/g,"&quot;");
var urlreg = /(https?|ftp|mms):\/\/([A-z0-9]+[_\-]?[A-z0-9]+\.)*[A-z0-9]+\-?[A-z0-9]+\.[A-z]{2,}(\/.*)*\/?/;
url = urlreg.test(url) ? url : HOST + url;
url = isUrl(url) ? url : HOST + url;
url = escapeCharacters(url,"*_");
var result = "<img src=\"" + url + "\" alt=\"" + alt_text + "\"";

View File

@ -13,14 +13,24 @@ var should = require('should');
describe('libs/util', function() {
describe('escape', function() {
var text1 = '<script></script> text';
var text2 = 'outside:<>, inside: ```js\n<>\n```\n`<>`\n```\n<>\n```\n`uc` `uc`';
var text2 = 'outside:<>, inside: ```js\n<>\n```\n`<>`\n```\n<>\n```\n`span` `span`';
var text3 = '\t<>\n <>\n';
var text4 = 'abc\n\t<>\n\t<>';
it('escape outside ok', function() {
var result = Util.escape(text1);
result.should.equal('&lt;script&gt;&lt;/script&gt; text');
});
it('not escape inside', function() {
var result = Util.escape(text2);
result.should.equal('outside:&lt;&gt;, inside: ```js\n<>\n```\n`<>`\n```\n<>\n```\n`uc` `uc`');
result.should.equal('outside:&lt;&gt;, inside: ```js\n<>\n```\n`<>`\n```\n<>\n```\n`span` `span`');
});
it('not escape inside block', function() {
var result = Util.escape(text3);
result.should.equal('\t<>\n <>\n');
});
it('escape not inside', function() {
var result = Util.escape(text4);
result.should.equal('abc\n\t&lt;&gt;\n\t&lt;&gt;');
});
});
});

View File

@ -21,7 +21,7 @@ describe('showdown xss test', function () {
it('should escape " in a', function () {
var text = '[illegal url][1]\n\n[1]: http://baidu.com"onmouseover=\'alert(123)\'';
var result = showdown.parse(text);
result.should.equal('<p><a href="http://baidu.com&quot;onmouseover=\'alert(123)\'">illegal url</a></p>');
result.should.equal('<p><a href="http://localhost.cnodejs.org:3000http://baidu.com"onmouseover=\'alert(123)\'">illegal url</a></p>');
});
it('should escape illegal url in img', function () {
@ -33,6 +33,6 @@ describe('showdown xss test', function () {
it('should escape " in img', function () {
var text = '![illegal url][1]\n\n[1]: http://baidu.com"onmouseover=\'alert(123)\'';
var result = showdown.parse(text);
result.should.equal('<p><img src="http://baidu.com&quot;onmouseover=\'alert(123)\'" alt="illegal url" title="" /></p>');
result.should.equal('<p><img src="http://localhost.cnodejs.org:3000http://baidu.com"onmouseover=\'alert(123)\'" alt="illegal url" title="" /></p>');
});
});