From 70ac8f1b79c1cee15e9b61e19a9aaec40aa94130 Mon Sep 17 00:00:00 2001 From: Lei Zongmin Date: Tue, 7 May 2013 12:50:56 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E9=A3=8E=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/index.js | 47 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/lib/index.js b/lib/index.js index 846764d..4b45d58 100644 --- a/lib/index.js +++ b/lib/index.js @@ -47,6 +47,18 @@ var defaultWhiteList = { video: ['autoplay', 'controls', 'loop', 'preload', 'src', 'height', 'width'], }; +// 正则表达式 +var REGEXP_LT = //g; +var REGEXP_QUOTE = /"/g; +var REGEXP_ATTR_NAME = /[^a-zA-Z0-9_:\.\-]/img; +var REGEXP_ATTR_VALUE = /&#([a-zA-Z0-9]*);?/img; +var REGEXP_DEFAULT_ON_TAG_ATTR_1 = /\/\*|\*\//mg; +var REGEXP_DEFAULT_ON_TAG_ATTR_2 = /^[\s"'`]*((j\s*a\s*v\s*a|v\s*b|l\s*i\s*v\s*e)\s*s\s*c\s*r\s*i\s*p\s*t\s*|m\s*o\s*c\s*h\s*a):/ig; +var REGEXP_DEFAULT_ON_TAG_ATTR_3 = /\/\*|\*\//mg; +var REGEXP_DEFAULT_ON_TAG_ATTR_4 = /((j\s*a\s*v\s*a|v\s*b|l\s*i\s*v\s*e)\s*s\s*c\s*r\s*i\s*p\s*t\s*|m\s*o\s*c\s*h\s*a):/ig; + + /** * 过滤属性值 * @@ -55,19 +67,23 @@ var defaultWhiteList = { * @param {string} value 属性值 * @return {string} 若不需要修改属性值,不返回任何值 */ -var defaultOnTagAttr = function (tag, attr, value) { +function defaultOnTagAttr (tag, attr, value) { if (attr === 'href' || attr === 'src') { - if (/\/\*|\*\//mg.test(value)) { + REGEXP_DEFAULT_ON_TAG_ATTR_1.lastIndex = 0; + if (REGEXP_DEFAULT_ON_TAG_ATTR_1.test(value)) { return '#'; } - if (/^[\s"'`]*((j\s*a\s*v\s*a|v\s*b|l\s*i\s*v\s*e)\s*s\s*c\s*r\s*i\s*p\s*t\s*|m\s*o\s*c\s*h\s*a):/ig.test(value)) { + REGEXP_DEFAULT_ON_TAG_ATTR_2.lastIndex = 0; + if (REGEXP_DEFAULT_ON_TAG_ATTR_2.test(value)) { return '#'; } } else if (attr === 'style') { - if (/\/\*|\*\//mg.test(value)) { + REGEXP_DEFAULT_ON_TAG_ATTR_3.lastIndex = 0; + if (REGEXP_DEFAULT_ON_TAG_ATTR_3.test(value)) { return '#'; } - if (/((j\s*a\s*v\s*a|v\s*b|l\s*i\s*v\s*e)\s*s\s*c\s*r\s*i\s*p\s*t\s*|m\s*o\s*c\s*h\s*a):/ig.test(value)) { + REGEXP_DEFAULT_ON_TAG_ATTR_4.lastIndex = 0; + if (REGEXP_DEFAULT_ON_TAG_ATTR_4.test(value)) { return ''; } } @@ -84,7 +100,7 @@ var defaultOnTagAttr = function (tag, attr, value) { * isClosing:是否为闭合标签,如 * @return {string} 若不返回任何值,则默认替换<>为<> */ -var defaultOnIgnoreTag = function (tag, html, options) { +function defaultOnIgnoreTag (tag, html, options) { return noTag(html); }; @@ -95,10 +111,12 @@ var defaultOnIgnoreTag = function (tag, html, options) { * @param {string} text * @return {string} */ -var noTag = function (text) { - return text.replace(//g, '>'); +function noTag (text) { + return text.replace(REGEXP_LT, '<').replace(REGEXP_GT, '>'); }; + + /** * XSS过滤 * @@ -106,7 +124,7 @@ var noTag = function (text) { * @param {object} options 选项:whiteList, onTagAttr, onIgnoreTag * @return {string} */ -exports = module.exports = function (html, options) { +function filterXSS (html, options) { 'use strict'; options = options || {}; @@ -123,7 +141,7 @@ exports = module.exports = function (html, options) { /** * 过滤不合法的属性 */ - var filterAttributes = function (tagName, attrs) { + function filterAttributes (tagName, attrs) { tagName = tagName.toLowerCase(); var whites = whiteList[tagName]; var lastPos = 0; @@ -136,13 +154,13 @@ exports = module.exports = function (html, options) { hasSprit = true; return; }; - name = name.replace(/[^a-zA-Z0-9_:\.\-]/img, '').toLowerCase(); + name = name.replace(REGEXP_ATTR_NAME, '').toLowerCase(); if (name.length < 1) return; if (whites.indexOf(name) !== -1) { if (value) { - value = value.trim().replace(/"/g, '"e;'); + value = value.trim().replace(REGEXP_QUOTE, '"e;'); // 转换unicode字符 及过滤不可见字符 - value = value.replace(/&#([a-zA-Z0-9]*);?/img, function (str, code) { + value = value.replace(REGEXP_ATTR_VALUE, function (str, code) { code = parseInt(code); return String.fromCharCode(code); }); @@ -207,7 +225,7 @@ exports = module.exports = function (html, options) { /** * 检查标签是否合法 */ - var addNewTag = function (tag, end) { + function addNewTag (tag, end) { rethtml += noTag(html.slice(lastPos, tagStart)); lastPos = end + 1; var spos = tag.slice(0, 2) === '