(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new error("cannot find module '"+i+"'");throw a.code="module_not_found",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i */ var filtercss = require("cssfilter").filtercss; var getdefaultcsswhitelist = require("cssfilter").getdefaultwhitelist; var _ = require("./util"); function getdefaultwhitelist() { return { a: ["target", "href", "title"], abbr: ["title"], address: [], area: ["shape", "coords", "href", "alt"], article: [], aside: [], audio: [ "autoplay", "controls", "crossorigin", "loop", "muted", "preload", "src", ], b: [], bdi: ["dir"], bdo: ["dir"], big: [], blockquote: ["cite"], br: [], caption: [], center: [], cite: [], code: [], col: ["align", "valign", "span", "width"], colgroup: ["align", "valign", "span", "width"], dd: [], del: ["datetime"], details: ["open"], div: [], dl: [], dt: [], em: [], figcaption: [], figure: [], font: ["color", "size", "face"], footer: [], h1: [], h2: [], h3: [], h4: [], h5: [], h6: [], header: [], hr: [], i: [], img: ["src", "alt", "title", "width", "height"], ins: ["datetime"], li: [], mark: [], nav: [], ol: [], p: [], pre: [], s: [], section: [], small: [], span: [], sub: [], summary: [], sup: [], strong: [], strike: [], table: ["width", "border", "align", "valign"], tbody: ["align", "valign"], td: ["width", "rowspan", "colspan", "align", "valign"], tfoot: ["align", "valign"], th: ["width", "rowspan", "colspan", "align", "valign"], thead: ["align", "valign"], tr: ["rowspan", "align", "valign"], tt: [], u: [], ul: [], video: [ "autoplay", "controls", "crossorigin", "loop", "muted", "playsinline", "poster", "preload", "src", "height", "width", ], }; } var defaultcssfilter = new filtercss(); /** * default ontag function * * @param {string} tag * @param {string} html * @param {object} options * @return {string} */ function ontag(tag, html, options) { // do nothing } /** * default onignoretag function * * @param {string} tag * @param {string} html * @param {object} options * @return {string} */ function onignoretag(tag, html, options) { // do nothing } /** * default ontagattr function * * @param {string} tag * @param {string} name * @param {string} value * @return {string} */ function ontagattr(tag, name, value) { // do nothing } /** * default onignoretagattr function * * @param {string} tag * @param {string} name * @param {string} value * @return {string} */ function onignoretagattr(tag, name, value) { // do nothing } /** * default escapehtml function * * @param {string} html */ function escapehtml(html) { return html.replace(regexp_lt, "<").replace(regexp_gt, ">"); } /** * default safeattrvalue function * * @param {string} tag * @param {string} name * @param {string} value * @param {object} cssfilter * @return {string} */ function safeattrvalue(tag, name, value, cssfilter) { // unescape attribute value firstly value = friendlyattrvalue(value); if (name === "href" || name === "src") { // filter `href` and `src` attribute // only allow the value that starts with `http://` | `https://` | `mailto:` | `/` | `#` value = _.trim(value); if (value === "#") return "#"; if ( !( value.substr(0, 7) === "http://" || value.substr(0, 8) === "https://" || value.substr(0, 7) === "mailto:" || value.substr(0, 4) === "tel:" || value.substr(0, 11) === "data:image/" || value.substr(0, 6) === "ftp://" || value.substr(0, 2) === "./" || value.substr(0, 3) === "../" || value[0] === "#" || value[0] === "/" ) ) { return ""; } } else if (name === "background") { // filter `background` attribute (maybe no use) // `javascript:` regexp_default_on_tag_attr_4.lastindex = 0; if (regexp_default_on_tag_attr_4.test(value)) { return ""; } } else if (name === "style") { // `expression()` regexp_default_on_tag_attr_7.lastindex = 0; if (regexp_default_on_tag_attr_7.test(value)) { return ""; } // `url()` regexp_default_on_tag_attr_8.lastindex = 0; if (regexp_default_on_tag_attr_8.test(value)) { regexp_default_on_tag_attr_4.lastindex = 0; if (regexp_default_on_tag_attr_4.test(value)) { return ""; } } if (cssfilter !== false) { cssfilter = cssfilter || defaultcssfilter; value = cssfilter.process(value); } } // escape `<>"` before returns value = escapeattrvalue(value); return value; } // regexp list var regexp_lt = //g; var regexp_quote = /"/g; var regexp_quote_2 = /"/g; var regexp_attr_value_1 = /&#([a-za-z0-9]*);?/gim; var regexp_attr_value_colon = /:?/gim; var regexp_attr_value_newline = /&newline;?/gim; // var regexp_default_on_tag_attr_3 = /\/\*|\*\//gm; 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):/gi; // var regexp_default_on_tag_attr_5 = /^[\s"'`]*(d\s*a\s*t\s*a\s*)\:/gi; // var regexp_default_on_tag_attr_6 = /^[\s"'`]*(d\s*a\s*t\s*a\s*)\:\s*image\//gi; var regexp_default_on_tag_attr_7 = /e\s*x\s*p\s*r\s*e\s*s\s*s\s*i\s*o\s*n\s*\(.*/gi; var regexp_default_on_tag_attr_8 = /u\s*r\s*l\s*\(.*/gi; /** * escape double quote * * @param {string} str * @return {string} str */ function escapequote(str) { return str.replace(regexp_quote, """); } /** * unescape double quote * * @param {string} str * @return {string} str */ function unescapequote(str) { return str.replace(regexp_quote_2, '"'); } /** * escape html entities * * @param {string} str * @return {string} */ function escapehtmlentities(str) { return str.replace(regexp_attr_value_1, function replaceunicode(str, code) { return code[0] === "x" || code[0] === "x" ? string.fromcharcode(parseint(code.substr(1), 16)) : string.fromcharcode(parseint(code, 10)); }); } /** * escape html5 new danger entities * * @param {string} str * @return {string} */ function escapedangerhtml5entities(str) { return str .replace(regexp_attr_value_colon, ":") .replace(regexp_attr_value_newline, " "); } /** * clear nonprintable characters * * @param {string} str * @return {string} */ function clearnonprintablecharacter(str) { var str2 = ""; for (var i = 0, len = str.length; i < len; i++) { str2 += str.charcodeat(i) < 32 ? " " : str.charat(i); } return _.trim(str2); } /** * get friendly attribute value * * @param {string} str * @return {string} */ function friendlyattrvalue(str) { str = unescapequote(str); str = escapehtmlentities(str); str = escapedangerhtml5entities(str); str = clearnonprintablecharacter(str); return str; } /** * unescape attribute value * * @param {string} str * @return {string} */ function escapeattrvalue(str) { str = escapequote(str); str = escapehtml(str); return str; } /** * `onignoretag` function for removing all the tags that are not in whitelist */ function onignoretagstripall() { return ""; } /** * remove tag body * specify a `tags` list, if the tag is not in the `tags` list then process by the specify function (optional) * * @param {array} tags * @param {function} next */ function striptagbody(tags, next) { if (typeof next !== "function") { next = function () {}; } var isremovealltag = !array.isarray(tags); function isremovetag(tag) { if (isremovealltag) return true; return _.indexof(tags, tag) !== -1; } var removelist = []; var posstart = false; return { onignoretag: function (tag, html, options) { if (isremovetag(tag)) { if (options.isclosing) { var ret = "[/removed]"; var end = options.position + ret.length; removelist.push([ posstart !== false ? posstart : options.position, end, ]); posstart = false; return ret; } else { if (!posstart) { posstart = options.position; } return "[removed]"; } } else { return next(tag, html, options); } }, remove: function (html) { var rethtml = ""; var lastpos = 0; _.foreach(removelist, function (pos) { rethtml += html.slice(lastpos, pos[0]); lastpos = pos[1]; }); rethtml += html.slice(lastpos); return rethtml; }, }; } /** * remove html comments * * @param {string} html * @return {string} */ function stripcommenttag(html) { var rethtml = ""; var lastpos = 0; while (lastpos < html.length) { var i = html.indexof("", i); if (j === -1) { break; } lastpos = j + 3; } return rethtml; } /** * remove invisible characters * * @param {string} html * @return {string} */ function stripblankchar(html) { var chars = html.split(""); chars = chars.filter(function (char) { var c = char.charcodeat(0); if (c === 127) return false; if (c <= 31) { if (c === 10 || c === 13) return true; return false; } return true; }); return chars.join(""); } exports.whitelist = getdefaultwhitelist(); exports.getdefaultwhitelist = getdefaultwhitelist; exports.ontag = ontag; exports.onignoretag = onignoretag; exports.ontagattr = ontagattr; exports.onignoretagattr = onignoretagattr; exports.safeattrvalue = safeattrvalue; exports.escapehtml = escapehtml; exports.escapequote = escapequote; exports.unescapequote = unescapequote; exports.escapehtmlentities = escapehtmlentities; exports.escapedangerhtml5entities = escapedangerhtml5entities; exports.clearnonprintablecharacter = clearnonprintablecharacter; exports.friendlyattrvalue = friendlyattrvalue; exports.escapeattrvalue = escapeattrvalue; exports.onignoretagstripall = onignoretagstripall; exports.striptagbody = striptagbody; exports.stripcommenttag = stripcommenttag; exports.stripblankchar = stripblankchar; exports.cssfilter = defaultcssfilter; exports.getdefaultcsswhitelist = getdefaultcsswhitelist; },{"./util":4,"cssfilter":8}],2:[function(require,module,exports){ /** * xss * * @author zongmin lei */ var default = require("./default"); var parser = require("./parser"); var filterxss = require("./xss"); /** * filter xss function * * @param {string} html * @param {object} options { whitelist, ontag, ontagattr, onignoretag, onignoretagattr, safeattrvalue, escapehtml } * @return {string} */ function filterxss(html, options) { var xss = new filterxss(options); return xss.process(html); } exports = module.exports = filterxss; exports.filterxss = filterxss; exports.filterxss = filterxss; (function () { for (var i in default) { exports[i] = default[i]; } for (var j in parser) { exports[j] = parser[j]; } })(); // using `xss` on the browser, output `filterxss` to the globals if (typeof window !== "undefined") { window.filterxss = module.exports; } // using `xss` on the webworker, output `filterxss` to the globals function isworkerenv() { return ( typeof self !== "undefined" && typeof dedicatedworkerglobalscope !== "undefined" && self instanceof dedicatedworkerglobalscope ); } if (isworkerenv()) { self.filterxss = module.exports; } },{"./default":1,"./parser":3,"./xss":5}],3:[function(require,module,exports){ /** * simple html parser * * @author zongmin lei */ var _ = require("./util"); /** * get tag name * * @param {string} html e.g. '' * @return {string} */ function gettagname(html) { var i = _.spaceindex(html); var tagname; if (i === -1) { tagname = html.slice(1, -1); } else { tagname = html.slice(1, i + 1); } tagname = _.trim(tagname).tolowercase(); if (tagname.slice(0, 1) === "/") tagname = tagname.slice(1); if (tagname.slice(-1) === "/") tagname = tagname.slice(0, -1); return tagname; } /** * is close tag? * * @param {string} html 如:'' * @return {boolean} */ function isclosing(html) { return html.slice(0, 2) === "" || currentpos === len - 1) { rethtml += escapehtml(html.slice(lastpos, tagstart)); currenthtml = html.slice(tagstart, currentpos + 1); currenttagname = gettagname(currenthtml); rethtml += ontag( tagstart, rethtml.length, currenttagname, currenthtml, isclosing(currenthtml) ); lastpos = currentpos + 1; tagstart = false; continue; } if (c === '"' || c === "'") { var i = 1; var ic = html.charat(currentpos - i); while (ic.trim() === "" || ic === "=") { if (ic === "=") { quotestart = c; continue chariterator; } ic = html.charat(currentpos - ++i); } } } else { if (c === quotestart) { quotestart = false; continue; } } } } if (lastpos < len) { rethtml += escapehtml(html.substr(lastpos)); } return rethtml; } var regexp_illegal_attr_name = /[^a-za-z0-9\\_:.-]/gim; /** * parse input attributes and returns processed attributes * * @param {string} html e.g. `href="#" target="_blank"` * @param {function} onattr e.g. `function (name, value)` * @return {string} */ function parseattr(html, onattr) { "use strict"; var lastpos = 0; var lastmarkpos = 0; var retattrs = []; var tmpname = false; var len = html.length; function addattr(name, value) { name = _.trim(name); name = name.replace(regexp_illegal_attr_name, "").tolowercase(); if (name.length < 1) return; var ret = onattr(name, value || ""); if (ret) retattrs.push(ret); } // 逐个分析字符 for (var i = 0; i < len; i++) { var c = html.charat(i); var v, j; if (tmpname === false && c === "=") { tmpname = html.slice(lastpos, i); lastpos = i + 1; lastmarkpos = html.charat(lastpos) === '"' || html.charat(lastpos) === "'" ? lastpos : findnextquotationmark(html, i + 1); continue; } if (tmpname !== false) { if ( i === lastmarkpos ) { j = html.indexof(c, i + 1); if (j === -1) { break; } else { v = _.trim(html.slice(lastmarkpos + 1, j)); addattr(tmpname, v); tmpname = false; i = j; lastpos = i + 1; continue; } } } if (/\s|\n|\t/.test(c)) { html = html.replace(/\s|\n|\t/g, " "); if (tmpname === false) { j = findnextequal(html, i); if (j === -1) { v = _.trim(html.slice(lastpos, i)); addattr(v); tmpname = false; lastpos = i + 1; continue; } else { i = j - 1; continue; } } else { j = findbeforeequal(html, i - 1); if (j === -1) { v = _.trim(html.slice(lastpos, i)); v = stripquotewrap(v); addattr(tmpname, v); tmpname = false; lastpos = i + 1; continue; } else { continue; } } } } if (lastpos < html.length) { if (tmpname === false) { addattr(html.slice(lastpos)); } else { addattr(tmpname, stripquotewrap(_.trim(html.slice(lastpos)))); } } return _.trim(retattrs.join(" ")); } function findnextequal(str, i) { for (; i < str.length; i++) { var c = str[i]; if (c === " ") continue; if (c === "=") return i; return -1; } } function findnextquotationmark(str, i) { for (; i < str.length; i++) { var c = str[i]; if (c === " ") continue; if (c === "'" || c === '"') return i; return -1; } } function findbeforeequal(str, i) { for (; i > 0; i--) { var c = str[i]; if (c === " ") continue; if (c === "=") return i; return -1; } } function isquotewrapstring(text) { if ( (text[0] === '"' && text[text.length - 1] === '"') || (text[0] === "'" && text[text.length - 1] === "'") ) { return true; } else { return false; } } function stripquotewrap(text) { if (isquotewrapstring(text)) { return text.substr(1, text.length - 2); } else { return text; } } exports.parsetag = parsetag; exports.parseattr = parseattr; },{"./util":4}],4:[function(require,module,exports){ module.exports = { indexof: function (arr, item) { var i, j; if (array.prototype.indexof) { return arr.indexof(item); } for (i = 0, j = arr.length; i < j; i++) { if (arr[i] === item) { return i; } } return -1; }, foreach: function (arr, fn, scope) { var i, j; if (array.prototype.foreach) { return arr.foreach(fn, scope); } for (i = 0, j = arr.length; i < j; i++) { fn.call(scope, arr[i], i, arr); } }, trim: function (str) { if (string.prototype.trim) { return str.trim(); } return str.replace(/(^\s*)|(\s*$)/g, ""); }, spaceindex: function (str) { var reg = /\s|\n|\t/; var match = reg.exec(str); return match ? match.index : -1; }, }; },{}],5:[function(require,module,exports){ /** * filter xss * * @author zongmin lei */ var filtercss = require("cssfilter").filtercss; var default = require("./default"); var parser = require("./parser"); var parsetag = parser.parsetag; var parseattr = parser.parseattr; var _ = require("./util"); /** * returns `true` if the input value is `undefined` or `null` * * @param {object} obj * @return {boolean} */ function isnull(obj) { return obj === undefined || obj === null; } /** * get attributes for a tag * * @param {string} html * @return {object} * - {string} html * - {boolean} closing */ function getattrs(html) { var i = _.spaceindex(html); if (i === -1) { return { html: "", closing: html[html.length - 2] === "/", }; } html = _.trim(html.slice(i + 1, -1)); var isclosing = html[html.length - 1] === "/"; if (isclosing) html = _.trim(html.slice(0, -1)); return { html: html, closing: isclosing, }; } /** * shallow copy * * @param {object} obj * @return {object} */ function shallowcopyobject(obj) { var ret = {}; for (var i in obj) { ret[i] = obj[i]; } return ret; } function keystolowercase(obj) { var ret = {}; for (var i in obj) { if (array.isarray(obj[i])) { ret[i.tolowercase()] = obj[i].map(function (item) { return item.tolowercase(); }); } else { ret[i.tolowercase()] = obj[i]; } } return ret; } /** * filterxss class * * @param {object} options * whitelist (or allowlist), ontag, ontagattr, onignoretag, * onignoretagattr, safeattrvalue, escapehtml * stripignoretagbody, allowcommenttag, stripblankchar * css{whitelist, onattr, onignoreattr} `css=false` means don't use `cssfilter` */ function filterxss(options) { options = shallowcopyobject(options || {}); if (options.stripignoretag) { if (options.onignoretag) { console.error( 'notes: cannot use these two options "stripignoretag" and "onignoretag" at the same time' ); } options.onignoretag = default.onignoretagstripall; } if (options.whitelist || options.allowlist) { options.whitelist = keystolowercase(options.whitelist || options.allowlist); } else { options.whitelist = default.whitelist; } options.ontag = options.ontag || default.ontag; options.ontagattr = options.ontagattr || default.ontagattr; options.onignoretag = options.onignoretag || default.onignoretag; options.onignoretagattr = options.onignoretagattr || default.onignoretagattr; options.safeattrvalue = options.safeattrvalue || default.safeattrvalue; options.escapehtml = options.escapehtml || default.escapehtml; this.options = options; if (options.css === false) { this.cssfilter = false; } else { options.css = options.css || {}; this.cssfilter = new filtercss(options.css); } } /** * start process and returns result * * @param {string} html * @return {string} */ filterxss.prototype.process = function (html) { // compatible with the input html = html || ""; html = html.tostring(); if (!html) return ""; var me = this; var options = me.options; var whitelist = options.whitelist; var ontag = options.ontag; var onignoretag = options.onignoretag; var ontagattr = options.ontagattr; var onignoretagattr = options.onignoretagattr; var safeattrvalue = options.safeattrvalue; var escapehtml = options.escapehtml; var cssfilter = me.cssfilter; // remove invisible characters if (options.stripblankchar) { html = default.stripblankchar(html); } // remove html comments if (!options.allowcommenttag) { html = default.stripcommenttag(html); } // if enable stripignoretagbody var stripignoretagbody = false; if (options.stripignoretagbody) { stripignoretagbody = default.striptagbody( options.stripignoretagbody, onignoretag ); onignoretag = stripignoretagbody.onignoretag; } var rethtml = parsetag( html, function (sourceposition, position, tag, html, isclosing) { var info = { sourceposition: sourceposition, position: position, isclosing: isclosing, iswhite: object.prototype.hasownproperty.call(whitelist, tag), }; // call `ontag()` var ret = ontag(tag, html, info); if (!isnull(ret)) return ret; if (info.iswhite) { if (info.isclosing) { return ""; } var attrs = getattrs(html); var whiteattrlist = whitelist[tag]; var attrshtml = parseattr(attrs.html, function (name, value) { // call `ontagattr()` var iswhiteattr = _.indexof(whiteattrlist, name) !== -1; var ret = ontagattr(tag, name, value, iswhiteattr); if (!isnull(ret)) return ret; if (iswhiteattr) { // call `safeattrvalue()` value = safeattrvalue(tag, name, value, cssfilter); if (value) { return name + '="' + value + '"'; } else { return name; } } else { // call `onignoretagattr()` ret = onignoretagattr(tag, name, value, iswhiteattr); if (!isnull(ret)) return ret; return; } }); // build new tag html html = "<" + tag; if (attrshtml) html += " " + attrshtml; if (attrs.closing) html += " /"; html += ">"; return html; } else { // call `onignoretag()` ret = onignoretag(tag, html, info); if (!isnull(ret)) return ret; return escapehtml(html); } }, escapehtml ); // if enable stripignoretagbody if (stripignoretagbody) { rethtml = stripignoretagbody.remove(rethtml); } return rethtml; }; module.exports = filterxss; },{"./default":1,"./parser":3,"./util":4,"cssfilter":8}],6:[function(require,module,exports){ /** * cssfilter * * @author 老雷 */ var default = require('./default'); var parsestyle = require('./parser'); var _ = require('./util'); /** * 返回值是否为空 * * @param {object} obj * @return {boolean} */ function isnull (obj) { return (obj === undefined || obj === null); } /** * 浅拷贝对象 * * @param {object} obj * @return {object} */ function shallowcopyobject (obj) { var ret = {}; for (var i in obj) { ret[i] = obj[i]; } return ret; } /** * 创建css过滤器 * * @param {object} options * - {object} whitelist * - {function} onattr * - {function} onignoreattr * - {function} safeattrvalue */ function filtercss (options) { options = shallowcopyobject(options || {}); options.whitelist = options.whitelist || default.whitelist; options.onattr = options.onattr || default.onattr; options.onignoreattr = options.onignoreattr || default.onignoreattr; options.safeattrvalue = options.safeattrvalue || default.safeattrvalue; this.options = options; } filtercss.prototype.process = function (css) { // 兼容各种奇葩输入 css = css || ''; css = css.tostring(); if (!css) return ''; var me = this; var options = me.options; var whitelist = options.whitelist; var onattr = options.onattr; var onignoreattr = options.onignoreattr; var safeattrvalue = options.safeattrvalue; var retcss = parsestyle(css, function (sourceposition, position, name, value, source) { var check = whitelist[name]; var iswhite = false; if (check === true) iswhite = check; else if (typeof check === 'function') iswhite = check(value); else if (check instanceof regexp) iswhite = check.test(value); if (iswhite !== true) iswhite = false; // 如果过滤后 value 为空则直接忽略 value = safeattrvalue(name, value); if (!value) return; var opts = { position: position, sourceposition: sourceposition, source: source, iswhite: iswhite }; if (iswhite) { var ret = onattr(name, value, opts); if (isnull(ret)) { return name + ':' + value; } else { return ret; } } else { var ret = onignoreattr(name, value, opts); if (!isnull(ret)) { return ret; } } }); return retcss; }; module.exports = filtercss; },{"./default":7,"./parser":9,"./util":10}],7:[function(require,module,exports){ /** * cssfilter * * @author 老雷 */ function getdefaultwhitelist () { // 白名单值说明: // true: 允许该属性 // function: function (val) { } 返回true表示允许该属性,其他值均表示不允许 // regexp: regexp.test(val) 返回true表示允许该属性,其他值均表示不允许 // 除上面列出的值外均表示不允许 var whitelist = {}; whitelist['align-content'] = false; // default: auto whitelist['align-items'] = false; // default: auto whitelist['align-self'] = false; // default: auto whitelist['alignment-adjust'] = false; // default: auto whitelist['alignment-baseline'] = false; // default: baseline whitelist['all'] = false; // default: depending on individual properties whitelist['anchor-point'] = false; // default: none whitelist['animation'] = false; // default: depending on individual properties whitelist['animation-delay'] = false; // default: 0 whitelist['animation-direction'] = false; // default: normal whitelist['animation-duration'] = false; // default: 0 whitelist['animation-fill-mode'] = false; // default: none whitelist['animation-iteration-count'] = false; // default: 1 whitelist['animation-name'] = false; // default: none whitelist['animation-play-state'] = false; // default: running whitelist['animation-timing-function'] = false; // default: ease whitelist['azimuth'] = false; // default: center whitelist['backface-visibility'] = false; // default: visible whitelist['background'] = true; // default: depending on individual properties whitelist['background-attachment'] = true; // default: scroll whitelist['background-clip'] = true; // default: border-box whitelist['background-color'] = true; // default: transparent whitelist['background-image'] = true; // default: none whitelist['background-origin'] = true; // default: padding-box whitelist['background-position'] = true; // default: 0% 0% whitelist['background-repeat'] = true; // default: repeat whitelist['background-size'] = true; // default: auto whitelist['baseline-shift'] = false; // default: baseline whitelist['binding'] = false; // default: none whitelist['bleed'] = false; // default: 6pt whitelist['bookmark-label'] = false; // default: content() whitelist['bookmark-level'] = false; // default: none whitelist['bookmark-state'] = false; // default: open whitelist['border'] = true; // default: depending on individual properties whitelist['border-bottom'] = true; // default: depending on individual properties whitelist['border-bottom-color'] = true; // default: current color whitelist['border-bottom-left-radius'] = true; // default: 0 whitelist['border-bottom-right-radius'] = true; // default: 0 whitelist['border-bottom-style'] = true; // default: none whitelist['border-bottom-width'] = true; // default: medium whitelist['border-collapse'] = true; // default: separate whitelist['border-color'] = true; // default: depending on individual properties whitelist['border-image'] = true; // default: none whitelist['border-image-outset'] = true; // default: 0 whitelist['border-image-repeat'] = true; // default: stretch whitelist['border-image-slice'] = true; // default: 100% whitelist['border-image-source'] = true; // default: none whitelist['border-image-width'] = true; // default: 1 whitelist['border-left'] = true; // default: depending on individual properties whitelist['border-left-color'] = true; // default: current color whitelist['border-left-style'] = true; // default: none whitelist['border-left-width'] = true; // default: medium whitelist['border-radius'] = true; // default: 0 whitelist['border-right'] = true; // default: depending on individual properties whitelist['border-right-color'] = true; // default: current color whitelist['border-right-style'] = true; // default: none whitelist['border-right-width'] = true; // default: medium whitelist['border-spacing'] = true; // default: 0 whitelist['border-style'] = true; // default: depending on individual properties whitelist['border-top'] = true; // default: depending on individual properties whitelist['border-top-color'] = true; // default: current color whitelist['border-top-left-radius'] = true; // default: 0 whitelist['border-top-right-radius'] = true; // default: 0 whitelist['border-top-style'] = true; // default: none whitelist['border-top-width'] = true; // default: medium whitelist['border-width'] = true; // default: depending on individual properties whitelist['bottom'] = false; // default: auto whitelist['box-decoration-break'] = true; // default: slice whitelist['box-shadow'] = true; // default: none whitelist['box-sizing'] = true; // default: content-box whitelist['box-snap'] = true; // default: none whitelist['box-suppress'] = true; // default: show whitelist['break-after'] = true; // default: auto whitelist['break-before'] = true; // default: auto whitelist['break-inside'] = true; // default: auto whitelist['caption-side'] = false; // default: top whitelist['chains'] = false; // default: none whitelist['clear'] = true; // default: none whitelist['clip'] = false; // default: auto whitelist['clip-path'] = false; // default: none whitelist['clip-rule'] = false; // default: nonzero whitelist['color'] = true; // default: implementation dependent whitelist['color-interpolation-filters'] = true; // default: auto whitelist['column-count'] = false; // default: auto whitelist['column-fill'] = false; // default: balance whitelist['column-gap'] = false; // default: normal whitelist['column-rule'] = false; // default: depending on individual properties whitelist['column-rule-color'] = false; // default: current color whitelist['column-rule-style'] = false; // default: medium whitelist['column-rule-width'] = false; // default: medium whitelist['column-span'] = false; // default: none whitelist['column-width'] = false; // default: auto whitelist['columns'] = false; // default: depending on individual properties whitelist['contain'] = false; // default: none whitelist['content'] = false; // default: normal whitelist['counter-increment'] = false; // default: none whitelist['counter-reset'] = false; // default: none whitelist['counter-set'] = false; // default: none whitelist['crop'] = false; // default: auto whitelist['cue'] = false; // default: depending on individual properties whitelist['cue-after'] = false; // default: none whitelist['cue-before'] = false; // default: none whitelist['cursor'] = false; // default: auto whitelist['direction'] = false; // default: ltr whitelist['display'] = true; // default: depending on individual properties whitelist['display-inside'] = true; // default: auto whitelist['display-list'] = true; // default: none whitelist['display-outside'] = true; // default: inline-level whitelist['dominant-baseline'] = false; // default: auto whitelist['elevation'] = false; // default: level whitelist['empty-cells'] = false; // default: show whitelist['filter'] = false; // default: none whitelist['flex'] = false; // default: depending on individual properties whitelist['flex-basis'] = false; // default: auto whitelist['flex-direction'] = false; // default: row whitelist['flex-flow'] = false; // default: depending on individual properties whitelist['flex-grow'] = false; // default: 0 whitelist['flex-shrink'] = false; // default: 1 whitelist['flex-wrap'] = false; // default: nowrap whitelist['float'] = false; // default: none whitelist['float-offset'] = false; // default: 0 0 whitelist['flood-color'] = false; // default: black whitelist['flood-opacity'] = false; // default: 1 whitelist['flow-from'] = false; // default: none whitelist['flow-into'] = false; // default: none whitelist['font'] = true; // default: depending on individual properties whitelist['font-family'] = true; // default: implementation dependent whitelist['font-feature-settings'] = true; // default: normal whitelist['font-kerning'] = true; // default: auto whitelist['font-language-override'] = true; // default: normal whitelist['font-size'] = true; // default: medium whitelist['font-size-adjust'] = true; // default: none whitelist['font-stretch'] = true; // default: normal whitelist['font-style'] = true; // default: normal whitelist['font-synthesis'] = true; // default: weight style whitelist['font-variant'] = true; // default: normal whitelist['font-variant-alternates'] = true; // default: normal whitelist['font-variant-caps'] = true; // default: normal whitelist['font-variant-east-asian'] = true; // default: normal whitelist['font-variant-ligatures'] = true; // default: normal whitelist['font-variant-numeric'] = true; // default: normal whitelist['font-variant-position'] = true; // default: normal whitelist['font-weight'] = true; // default: normal whitelist['grid'] = false; // default: depending on individual properties whitelist['grid-area'] = false; // default: depending on individual properties whitelist['grid-auto-columns'] = false; // default: auto whitelist['grid-auto-flow'] = false; // default: none whitelist['grid-auto-rows'] = false; // default: auto whitelist['grid-column'] = false; // default: depending on individual properties whitelist['grid-column-end'] = false; // default: auto whitelist['grid-column-start'] = false; // default: auto whitelist['grid-row'] = false; // default: depending on individual properties whitelist['grid-row-end'] = false; // default: auto whitelist['grid-row-start'] = false; // default: auto whitelist['grid-template'] = false; // default: depending on individual properties whitelist['grid-template-areas'] = false; // default: none whitelist['grid-template-columns'] = false; // default: none whitelist['grid-template-rows'] = false; // default: none whitelist['hanging-punctuation'] = false; // default: none whitelist['height'] = true; // default: auto whitelist['hyphens'] = false; // default: manual whitelist['icon'] = false; // default: auto whitelist['image-orientation'] = false; // default: auto whitelist['image-resolution'] = false; // default: normal whitelist['ime-mode'] = false; // default: auto whitelist['initial-letters'] = false; // default: normal whitelist['inline-box-align'] = false; // default: last whitelist['justify-content'] = false; // default: auto whitelist['justify-items'] = false; // default: auto whitelist['justify-self'] = false; // default: auto whitelist['left'] = false; // default: auto whitelist['letter-spacing'] = true; // default: normal whitelist['lighting-color'] = true; // default: white whitelist['line-box-contain'] = false; // default: block inline replaced whitelist['line-break'] = false; // default: auto whitelist['line-grid'] = false; // default: match-parent whitelist['line-height'] = false; // default: normal whitelist['line-snap'] = false; // default: none whitelist['line-stacking'] = false; // default: depending on individual properties whitelist['line-stacking-ruby'] = false; // default: exclude-ruby whitelist['line-stacking-shift'] = false; // default: consider-shifts whitelist['line-stacking-strategy'] = false; // default: inline-line-height whitelist['list-style'] = true; // default: depending on individual properties whitelist['list-style-image'] = true; // default: none whitelist['list-style-position'] = true; // default: outside whitelist['list-style-type'] = true; // default: disc whitelist['margin'] = true; // default: depending on individual properties whitelist['margin-bottom'] = true; // default: 0 whitelist['margin-left'] = true; // default: 0 whitelist['margin-right'] = true; // default: 0 whitelist['margin-top'] = true; // default: 0 whitelist['marker-offset'] = false; // default: auto whitelist['marker-side'] = false; // default: list-item whitelist['marks'] = false; // default: none whitelist['mask'] = false; // default: border-box whitelist['mask-box'] = false; // default: see individual properties whitelist['mask-box-outset'] = false; // default: 0 whitelist['mask-box-repeat'] = false; // default: stretch whitelist['mask-box-slice'] = false; // default: 0 fill whitelist['mask-box-source'] = false; // default: none whitelist['mask-box-width'] = false; // default: auto whitelist['mask-clip'] = false; // default: border-box whitelist['mask-image'] = false; // default: none whitelist['mask-origin'] = false; // default: border-box whitelist['mask-position'] = false; // default: center whitelist['mask-repeat'] = false; // default: no-repeat whitelist['mask-size'] = false; // default: border-box whitelist['mask-source-type'] = false; // default: auto whitelist['mask-type'] = false; // default: luminance whitelist['max-height'] = true; // default: none whitelist['max-lines'] = false; // default: none whitelist['max-width'] = true; // default: none whitelist['min-height'] = true; // default: 0 whitelist['min-width'] = true; // default: 0 whitelist['move-to'] = false; // default: normal whitelist['nav-down'] = false; // default: auto whitelist['nav-index'] = false; // default: auto whitelist['nav-left'] = false; // default: auto whitelist['nav-right'] = false; // default: auto whitelist['nav-up'] = false; // default: auto whitelist['object-fit'] = false; // default: fill whitelist['object-position'] = false; // default: 50% 50% whitelist['opacity'] = false; // default: 1 whitelist['order'] = false; // default: 0 whitelist['orphans'] = false; // default: 2 whitelist['outline'] = false; // default: depending on individual properties whitelist['outline-color'] = false; // default: invert whitelist['outline-offset'] = false; // default: 0 whitelist['outline-style'] = false; // default: none whitelist['outline-width'] = false; // default: medium whitelist['overflow'] = false; // default: depending on individual properties whitelist['overflow-wrap'] = false; // default: normal whitelist['overflow-x'] = false; // default: visible whitelist['overflow-y'] = false; // default: visible whitelist['padding'] = true; // default: depending on individual properties whitelist['padding-bottom'] = true; // default: 0 whitelist['padding-left'] = true; // default: 0 whitelist['padding-right'] = true; // default: 0 whitelist['padding-top'] = true; // default: 0 whitelist['page'] = false; // default: auto whitelist['page-break-after'] = false; // default: auto whitelist['page-break-before'] = false; // default: auto whitelist['page-break-inside'] = false; // default: auto whitelist['page-policy'] = false; // default: start whitelist['pause'] = false; // default: implementation dependent whitelist['pause-after'] = false; // default: implementation dependent whitelist['pause-before'] = false; // default: implementation dependent whitelist['perspective'] = false; // default: none whitelist['perspective-origin'] = false; // default: 50% 50% whitelist['pitch'] = false; // default: medium whitelist['pitch-range'] = false; // default: 50 whitelist['play-during'] = false; // default: auto whitelist['position'] = false; // default: static whitelist['presentation-level'] = false; // default: 0 whitelist['quotes'] = false; // default: text whitelist['region-fragment'] = false; // default: auto whitelist['resize'] = false; // default: none whitelist['rest'] = false; // default: depending on individual properties whitelist['rest-after'] = false; // default: none whitelist['rest-before'] = false; // default: none whitelist['richness'] = false; // default: 50 whitelist['right'] = false; // default: auto whitelist['rotation'] = false; // default: 0 whitelist['rotation-point'] = false; // default: 50% 50% whitelist['ruby-align'] = false; // default: auto whitelist['ruby-merge'] = false; // default: separate whitelist['ruby-position'] = false; // default: before whitelist['shape-image-threshold'] = false; // default: 0.0 whitelist['shape-outside'] = false; // default: none whitelist['shape-margin'] = false; // default: 0 whitelist['size'] = false; // default: auto whitelist['speak'] = false; // default: auto whitelist['speak-as'] = false; // default: normal whitelist['speak-header'] = false; // default: once whitelist['speak-numeral'] = false; // default: continuous whitelist['speak-punctuation'] = false; // default: none whitelist['speech-rate'] = false; // default: medium whitelist['stress'] = false; // default: 50 whitelist['string-set'] = false; // default: none whitelist['tab-size'] = false; // default: 8 whitelist['table-layout'] = false; // default: auto whitelist['text-align'] = true; // default: start whitelist['text-align-last'] = true; // default: auto whitelist['text-combine-upright'] = true; // default: none whitelist['text-decoration'] = true; // default: none whitelist['text-decoration-color'] = true; // default: currentcolor whitelist['text-decoration-line'] = true; // default: none whitelist['text-decoration-skip'] = true; // default: objects whitelist['text-decoration-style'] = true; // default: solid whitelist['text-emphasis'] = true; // default: depending on individual properties whitelist['text-emphasis-color'] = true; // default: currentcolor whitelist['text-emphasis-position'] = true; // default: over right whitelist['text-emphasis-style'] = true; // default: none whitelist['text-height'] = true; // default: auto whitelist['text-indent'] = true; // default: 0 whitelist['text-justify'] = true; // default: auto whitelist['text-orientation'] = true; // default: mixed whitelist['text-overflow'] = true; // default: clip whitelist['text-shadow'] = true; // default: none whitelist['text-space-collapse'] = true; // default: collapse whitelist['text-transform'] = true; // default: none whitelist['text-underline-position'] = true; // default: auto whitelist['text-wrap'] = true; // default: normal whitelist['top'] = false; // default: auto whitelist['transform'] = false; // default: none whitelist['transform-origin'] = false; // default: 50% 50% 0 whitelist['transform-style'] = false; // default: flat whitelist['transition'] = false; // default: depending on individual properties whitelist['transition-delay'] = false; // default: 0s whitelist['transition-duration'] = false; // default: 0s whitelist['transition-property'] = false; // default: all whitelist['transition-timing-function'] = false; // default: ease whitelist['unicode-bidi'] = false; // default: normal whitelist['vertical-align'] = false; // default: baseline whitelist['visibility'] = false; // default: visible whitelist['voice-balance'] = false; // default: center whitelist['voice-duration'] = false; // default: auto whitelist['voice-family'] = false; // default: implementation dependent whitelist['voice-pitch'] = false; // default: medium whitelist['voice-range'] = false; // default: medium whitelist['voice-rate'] = false; // default: normal whitelist['voice-stress'] = false; // default: normal whitelist['voice-volume'] = false; // default: medium whitelist['volume'] = false; // default: medium whitelist['white-space'] = false; // default: normal whitelist['widows'] = false; // default: 2 whitelist['width'] = true; // default: auto whitelist['will-change'] = false; // default: auto whitelist['word-break'] = true; // default: normal whitelist['word-spacing'] = true; // default: normal whitelist['word-wrap'] = true; // default: normal whitelist['wrap-flow'] = false; // default: auto whitelist['wrap-through'] = false; // default: wrap whitelist['writing-mode'] = false; // default: horizontal-tb whitelist['z-index'] = false; // default: auto return whitelist; } /** * 匹配到白名单上的一个属性时 * * @param {string} name * @param {string} value * @param {object} options * @return {string} */ function onattr (name, value, options) { // do nothing } /** * 匹配到不在白名单上的一个属性时 * * @param {string} name * @param {string} value * @param {object} options * @return {string} */ function onignoreattr (name, value, options) { // do nothing } var regexp_url_javascript = /javascript\s*\:/img; /** * 过滤属性值 * * @param {string} name * @param {string} value * @return {string} */ function safeattrvalue(name, value) { if (regexp_url_javascript.test(value)) return ''; return value; } exports.whitelist = getdefaultwhitelist(); exports.getdefaultwhitelist = getdefaultwhitelist; exports.onattr = onattr; exports.onignoreattr = onignoreattr; exports.safeattrvalue = safeattrvalue; },{}],8:[function(require,module,exports){ /** * cssfilter * * @author 老雷 */ var default = require('./default'); var filtercss = require('./css'); /** * xss过滤 * * @param {string} css 要过滤的css代码 * @param {object} options 选项:whitelist, onattr, onignoreattr * @return {string} */ function filtercss (html, options) { var xss = new filtercss(options); return xss.process(html); } // 输出 exports = module.exports = filtercss; exports.filtercss = filtercss; for (var i in default) exports[i] = default[i]; // 在浏览器端使用 if (typeof window !== 'undefined') { window.filtercss = module.exports; } },{"./css":6,"./default":7}],9:[function(require,module,exports){ /** * cssfilter * * @author 老雷 */ var _ = require('./util'); /** * 解析style * * @param {string} css * @param {function} onattr 处理属性的函数 * 参数格式: function (sourceposition, position, name, value, source) * @return {string} */ function parsestyle (css, onattr) { css = _.trimright(css); if (css[css.length - 1] !== ';') css += ';'; var csslength = css.length; var isparenthesisopen = false; var lastpos = 0; var i = 0; var retcss = ''; function addnewattr () { // 如果没有正常的闭合圆括号,则直接忽略当前属性 if (!isparenthesisopen) { var source = _.trim(css.slice(lastpos, i)); var j = source.indexof(':'); if (j !== -1) { var name = _.trim(source.slice(0, j)); var value = _.trim(source.slice(j + 1)); // 必须有属性名称 if (name) { var ret = onattr(lastpos, retcss.length, name, value, source); if (ret) retcss += ret + '; '; } } } lastpos = i + 1; } for (; i < csslength; i++) { var c = css[i]; if (c === '/' && css[i + 1] === '*') { // 备注开始 var j = css.indexof('*/', i + 2); // 如果没有正常的备注结束,则后面的部分全部跳过 if (j === -1) break; // 直接将当前位置调到备注结尾,并且初始化状态 i = j + 1; lastpos = i + 1; isparenthesisopen = false; } else if (c === '(') { isparenthesisopen = true; } else if (c === ')') { isparenthesisopen = false; } else if (c === ';') { if (isparenthesisopen) { // 在圆括号里面,忽略 } else { addnewattr(); } } else if (c === '\n') { addnewattr(); } } return _.trim(retcss); } module.exports = parsestyle; },{"./util":10}],10:[function(require,module,exports){ module.exports = { indexof: function (arr, item) { var i, j; if (array.prototype.indexof) { return arr.indexof(item); } for (i = 0, j = arr.length; i < j; i++) { if (arr[i] === item) { return i; } } return -1; }, foreach: function (arr, fn, scope) { var i, j; if (array.prototype.foreach) { return arr.foreach(fn, scope); } for (i = 0, j = arr.length; i < j; i++) { fn.call(scope, arr[i], i, arr); } }, trim: function (str) { if (string.prototype.trim) { return str.trim(); } return str.replace(/(^\s*)|(\s*$)/g, ''); }, trimright: function (str) { if (string.prototype.trimright) { return str.trimright(); } return str.replace(/(\s*$)/g, ''); } }; },{}]},{},[2]);