dompurify 2.0.7 → 2.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -12
- package/dist/purify.cjs.js +139 -88
- package/dist/purify.cjs.js.map +1 -1
- package/dist/purify.es.js +139 -88
- package/dist/purify.es.js.map +1 -1
- package/dist/purify.js +139 -88
- package/dist/purify.js.map +1 -1
- package/dist/purify.min.js +1 -1
- package/dist/purify.min.js.map +1 -1
- package/package.json +4 -4
package/dist/purify.es.js
CHANGED
|
@@ -1,39 +1,75 @@
|
|
|
1
|
-
|
|
2
|
-
return x;
|
|
3
|
-
};
|
|
1
|
+
function _toConsumableArray$1(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
|
4
2
|
|
|
5
|
-
var
|
|
3
|
+
var hasOwnProperty = Object.hasOwnProperty;
|
|
4
|
+
var setPrototypeOf = Object.setPrototypeOf;
|
|
5
|
+
var isFrozen = Object.isFrozen;
|
|
6
|
+
var objectKeys = Object.keys;
|
|
7
|
+
var freeze = Object.freeze;
|
|
8
|
+
var seal = Object.seal; // eslint-disable-line import/no-mutable-exports
|
|
6
9
|
|
|
7
|
-
|
|
8
|
-
var
|
|
10
|
+
var _ref = typeof Reflect !== 'undefined' && Reflect;
|
|
11
|
+
var apply = _ref.apply;
|
|
12
|
+
var construct = _ref.construct;
|
|
9
13
|
|
|
10
|
-
|
|
14
|
+
if (!apply) {
|
|
15
|
+
apply = function apply(fun, thisValue, args) {
|
|
16
|
+
return fun.apply(thisValue, args);
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (!freeze) {
|
|
21
|
+
freeze = function freeze(x) {
|
|
22
|
+
return x;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
11
25
|
|
|
12
|
-
|
|
26
|
+
if (!seal) {
|
|
27
|
+
seal = function seal(x) {
|
|
28
|
+
return x;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
13
31
|
|
|
14
|
-
|
|
32
|
+
if (!construct) {
|
|
33
|
+
construct = function construct(Func, args) {
|
|
34
|
+
return new (Function.prototype.bind.apply(Func, [null].concat(_toConsumableArray$1(args))))();
|
|
35
|
+
};
|
|
36
|
+
}
|
|
15
37
|
|
|
16
|
-
var
|
|
17
|
-
|
|
18
|
-
|
|
38
|
+
var arrayForEach = unapply(Array.prototype.forEach);
|
|
39
|
+
var arrayIndexOf = unapply(Array.prototype.indexOf);
|
|
40
|
+
var arrayJoin = unapply(Array.prototype.join);
|
|
41
|
+
var arrayPop = unapply(Array.prototype.pop);
|
|
42
|
+
var arrayPush = unapply(Array.prototype.push);
|
|
43
|
+
var arraySlice = unapply(Array.prototype.slice);
|
|
19
44
|
|
|
20
|
-
var
|
|
45
|
+
var stringToLowerCase = unapply(String.prototype.toLowerCase);
|
|
46
|
+
var stringMatch = unapply(String.prototype.match);
|
|
47
|
+
var stringReplace = unapply(String.prototype.replace);
|
|
48
|
+
var stringIndexOf = unapply(String.prototype.indexOf);
|
|
49
|
+
var stringTrim = unapply(String.prototype.trim);
|
|
21
50
|
|
|
22
|
-
var
|
|
51
|
+
var regExpTest = unapply(RegExp.prototype.test);
|
|
52
|
+
var regExpCreate = unconstruct(RegExp);
|
|
23
53
|
|
|
24
|
-
var
|
|
54
|
+
var typeErrorCreate = unconstruct(TypeError);
|
|
25
55
|
|
|
26
|
-
|
|
56
|
+
function unapply(func) {
|
|
57
|
+
return function (thisArg) {
|
|
58
|
+
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
59
|
+
args[_key - 1] = arguments[_key];
|
|
60
|
+
}
|
|
27
61
|
|
|
28
|
-
|
|
29
|
-
|
|
62
|
+
return apply(func, thisArg, args);
|
|
63
|
+
};
|
|
64
|
+
}
|
|
30
65
|
|
|
31
|
-
|
|
32
|
-
|
|
66
|
+
function unconstruct(func) {
|
|
67
|
+
return function () {
|
|
68
|
+
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
69
|
+
args[_key2] = arguments[_key2];
|
|
70
|
+
}
|
|
33
71
|
|
|
34
|
-
|
|
35
|
-
apply$1 = function apply(fun, thisValue, args) {
|
|
36
|
-
return fun.apply(thisValue, args);
|
|
72
|
+
return construct(func, args);
|
|
37
73
|
};
|
|
38
74
|
}
|
|
39
75
|
|
|
@@ -50,10 +86,10 @@ function addToSet(set, array) {
|
|
|
50
86
|
while (l--) {
|
|
51
87
|
var element = array[l];
|
|
52
88
|
if (typeof element === 'string') {
|
|
53
|
-
var lcElement = element
|
|
89
|
+
var lcElement = stringToLowerCase(element);
|
|
54
90
|
if (lcElement !== element) {
|
|
55
91
|
// Config presets (e.g. tags.js, attrs.js) are immutable.
|
|
56
|
-
if (!
|
|
92
|
+
if (!isFrozen(array)) {
|
|
57
93
|
array[l] = lcElement;
|
|
58
94
|
}
|
|
59
95
|
|
|
@@ -73,7 +109,7 @@ function clone(object) {
|
|
|
73
109
|
|
|
74
110
|
var property = void 0;
|
|
75
111
|
for (property in object) {
|
|
76
|
-
if (apply
|
|
112
|
+
if (apply(hasOwnProperty, object, [property])) {
|
|
77
113
|
newObject[property] = object[property];
|
|
78
114
|
}
|
|
79
115
|
}
|
|
@@ -81,9 +117,24 @@ function clone(object) {
|
|
|
81
117
|
return newObject;
|
|
82
118
|
}
|
|
83
119
|
|
|
84
|
-
var
|
|
85
|
-
|
|
86
|
-
|
|
120
|
+
var html = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'section', 'select', 'shadow', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']);
|
|
121
|
+
|
|
122
|
+
// SVG
|
|
123
|
+
var svg = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'audio', 'canvas', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'video', 'view', 'vkern']);
|
|
124
|
+
|
|
125
|
+
var svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']);
|
|
126
|
+
|
|
127
|
+
var mathMl = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mroot', 'mrow', 'ms', 'mspace', 'msqrt', 'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover']);
|
|
128
|
+
|
|
129
|
+
var text = freeze(['#text']);
|
|
130
|
+
|
|
131
|
+
var html$1 = freeze(['accept', 'action', 'align', 'alt', 'autocomplete', 'background', 'bgcolor', 'border', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'controls', 'coords', 'crossorigin', 'datetime', 'default', 'dir', 'disabled', 'download', 'enctype', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'integrity', 'ismap', 'label', 'lang', 'list', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'name', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'pattern', 'placeholder', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'type', 'usemap', 'valign', 'value', 'width', 'xmlns']);
|
|
132
|
+
|
|
133
|
+
var svg$1 = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dur', 'edgemode', 'elevation', 'end', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'specularconstant', 'specularexponent', 'spreadmethod', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'tabindex', 'targetx', 'targety', 'transform', 'text-anchor', 'text-decoration', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']);
|
|
134
|
+
|
|
135
|
+
var mathMl$1 = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']);
|
|
136
|
+
|
|
137
|
+
var xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);
|
|
87
138
|
|
|
88
139
|
var MUSTACHE_EXPR = seal(/\{\{[\s\S]*|[\s\S]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode
|
|
89
140
|
var ERB_EXPR = seal(/<%[\s\S]*|[\s\S]*%>/gm);
|
|
@@ -99,22 +150,10 @@ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol
|
|
|
99
150
|
|
|
100
151
|
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
|
101
152
|
|
|
102
|
-
var _ref = typeof Reflect !== 'undefined' && Reflect;
|
|
103
|
-
var apply = _ref.apply;
|
|
104
|
-
|
|
105
|
-
var arraySlice = Array.prototype.slice;
|
|
106
|
-
var freeze = Object.freeze;
|
|
107
|
-
|
|
108
153
|
var getGlobal = function getGlobal() {
|
|
109
154
|
return typeof window === 'undefined' ? null : window;
|
|
110
155
|
};
|
|
111
156
|
|
|
112
|
-
if (!apply) {
|
|
113
|
-
apply = function apply(fun, thisValue, args) {
|
|
114
|
-
return fun.apply(thisValue, args);
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
|
|
118
157
|
/**
|
|
119
158
|
* Creates a no-op policy for internal use only.
|
|
120
159
|
* Don't export this function outside this module!
|
|
@@ -165,7 +204,7 @@ function createDOMPurify() {
|
|
|
165
204
|
* Version label, exposed for easier checks
|
|
166
205
|
* if DOMPurify is up to date or not
|
|
167
206
|
*/
|
|
168
|
-
DOMPurify.version = '2.0.
|
|
207
|
+
DOMPurify.version = '2.0.8';
|
|
169
208
|
|
|
170
209
|
/**
|
|
171
210
|
* Array of elements that DOMPurify removed during sanitation.
|
|
@@ -195,7 +234,7 @@ function createDOMPurify() {
|
|
|
195
234
|
Text = window.Text,
|
|
196
235
|
Comment = window.Comment,
|
|
197
236
|
DOMParser = window.DOMParser,
|
|
198
|
-
|
|
237
|
+
trustedTypes = window.trustedTypes;
|
|
199
238
|
|
|
200
239
|
// As per issue #47, the web-components registry is inherited by a
|
|
201
240
|
// new document created via createHTMLDocument. As per the spec
|
|
@@ -211,7 +250,7 @@ function createDOMPurify() {
|
|
|
211
250
|
}
|
|
212
251
|
}
|
|
213
252
|
|
|
214
|
-
var trustedTypesPolicy = _createTrustedTypesPolicy(
|
|
253
|
+
var trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, originalDocument);
|
|
215
254
|
var emptyHTML = trustedTypesPolicy ? trustedTypesPolicy.createHTML('') : '';
|
|
216
255
|
|
|
217
256
|
var _document = document,
|
|
@@ -372,9 +411,7 @@ function createDOMPurify() {
|
|
|
372
411
|
SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true
|
|
373
412
|
KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true
|
|
374
413
|
IN_PLACE = cfg.IN_PLACE || false; // Default false
|
|
375
|
-
|
|
376
414
|
IS_ALLOWED_URI$$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI$$1;
|
|
377
|
-
|
|
378
415
|
if (SAFE_FOR_TEMPLATES) {
|
|
379
416
|
ALLOW_DATA_ATTR = false;
|
|
380
417
|
}
|
|
@@ -463,7 +500,7 @@ function createDOMPurify() {
|
|
|
463
500
|
* @param {Node} node a DOM node
|
|
464
501
|
*/
|
|
465
502
|
var _forceRemove = function _forceRemove(node) {
|
|
466
|
-
DOMPurify.removed
|
|
503
|
+
arrayPush(DOMPurify.removed, { element: node });
|
|
467
504
|
try {
|
|
468
505
|
node.parentNode.removeChild(node);
|
|
469
506
|
} catch (error) {
|
|
@@ -479,12 +516,12 @@ function createDOMPurify() {
|
|
|
479
516
|
*/
|
|
480
517
|
var _removeAttribute = function _removeAttribute(name, node) {
|
|
481
518
|
try {
|
|
482
|
-
DOMPurify.removed
|
|
519
|
+
arrayPush(DOMPurify.removed, {
|
|
483
520
|
attribute: node.getAttributeNode(name),
|
|
484
521
|
from: node
|
|
485
522
|
});
|
|
486
523
|
} catch (error) {
|
|
487
|
-
DOMPurify.removed
|
|
524
|
+
arrayPush(DOMPurify.removed, {
|
|
488
525
|
attribute: null,
|
|
489
526
|
from: node
|
|
490
527
|
});
|
|
@@ -508,17 +545,15 @@ function createDOMPurify() {
|
|
|
508
545
|
dirty = '<remove></remove>' + dirty;
|
|
509
546
|
} else {
|
|
510
547
|
/* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */
|
|
511
|
-
var matches = dirty
|
|
548
|
+
var matches = stringMatch(dirty, /^[\s]+/);
|
|
512
549
|
leadingWhitespace = matches && matches[0];
|
|
513
|
-
if (leadingWhitespace) {
|
|
514
|
-
dirty = dirty.slice(leadingWhitespace.length);
|
|
515
|
-
}
|
|
516
550
|
}
|
|
517
551
|
|
|
552
|
+
var dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty;
|
|
518
553
|
/* Use DOMParser to workaround Firefox bug (see comment below) */
|
|
519
554
|
if (useDOMParser) {
|
|
520
555
|
try {
|
|
521
|
-
doc = new DOMParser().parseFromString(
|
|
556
|
+
doc = new DOMParser().parseFromString(dirtyPayload, 'text/html');
|
|
522
557
|
} catch (error) {}
|
|
523
558
|
}
|
|
524
559
|
|
|
@@ -535,7 +570,7 @@ function createDOMPurify() {
|
|
|
535
570
|
body = _doc.body;
|
|
536
571
|
|
|
537
572
|
body.parentNode.removeChild(body.parentNode.firstElementChild);
|
|
538
|
-
body.outerHTML =
|
|
573
|
+
body.outerHTML = dirtyPayload;
|
|
539
574
|
}
|
|
540
575
|
|
|
541
576
|
if (dirty && leadingWhitespace) {
|
|
@@ -568,7 +603,7 @@ function createDOMPurify() {
|
|
|
568
603
|
(function () {
|
|
569
604
|
try {
|
|
570
605
|
var doc = _initDocument('<x/><title></title><img>');
|
|
571
|
-
if (/<\/title
|
|
606
|
+
if (regExpTest(/<\/title/, doc.querySelector('title').innerHTML)) {
|
|
572
607
|
removeTitle = true;
|
|
573
608
|
}
|
|
574
609
|
} catch (error) {}
|
|
@@ -628,7 +663,7 @@ function createDOMPurify() {
|
|
|
628
663
|
return;
|
|
629
664
|
}
|
|
630
665
|
|
|
631
|
-
hooks[entryPoint]
|
|
666
|
+
arrayForEach(hooks[entryPoint], function (hook) {
|
|
632
667
|
hook.call(DOMPurify, currentNode, data, CONFIG);
|
|
633
668
|
});
|
|
634
669
|
};
|
|
@@ -657,7 +692,7 @@ function createDOMPurify() {
|
|
|
657
692
|
}
|
|
658
693
|
|
|
659
694
|
/* Now let's check the element's type and name */
|
|
660
|
-
var tagName = currentNode.nodeName
|
|
695
|
+
var tagName = stringToLowerCase(currentNode.nodeName);
|
|
661
696
|
|
|
662
697
|
/* Execute a hook if present */
|
|
663
698
|
_executeHook('uponSanitizeElement', currentNode, {
|
|
@@ -686,23 +721,23 @@ function createDOMPurify() {
|
|
|
686
721
|
}
|
|
687
722
|
|
|
688
723
|
/* Remove in case a noscript/noembed XSS is suspected */
|
|
689
|
-
if (tagName === 'noscript' && /<\/noscript/i
|
|
724
|
+
if (tagName === 'noscript' && regExpTest(/<\/noscript/i, currentNode.innerHTML)) {
|
|
690
725
|
_forceRemove(currentNode);
|
|
691
726
|
return true;
|
|
692
727
|
}
|
|
693
728
|
|
|
694
|
-
if (tagName === 'noembed' && /<\/noembed/i
|
|
729
|
+
if (tagName === 'noembed' && regExpTest(/<\/noembed/i, currentNode.innerHTML)) {
|
|
695
730
|
_forceRemove(currentNode);
|
|
696
731
|
return true;
|
|
697
732
|
}
|
|
698
733
|
|
|
699
734
|
/* Convert markup to cover jQuery behavior */
|
|
700
|
-
if (SAFE_FOR_JQUERY && !currentNode.firstElementChild && (!currentNode.content || !currentNode.content.firstElementChild) && /</g
|
|
701
|
-
DOMPurify.removed
|
|
735
|
+
if (SAFE_FOR_JQUERY && !currentNode.firstElementChild && (!currentNode.content || !currentNode.content.firstElementChild) && regExpTest(/</g, currentNode.textContent)) {
|
|
736
|
+
arrayPush(DOMPurify.removed, { element: currentNode.cloneNode() });
|
|
702
737
|
if (currentNode.innerHTML) {
|
|
703
|
-
currentNode.innerHTML = currentNode.innerHTML
|
|
738
|
+
currentNode.innerHTML = stringReplace(currentNode.innerHTML, /</g, '<');
|
|
704
739
|
} else {
|
|
705
|
-
currentNode.innerHTML = currentNode.textContent
|
|
740
|
+
currentNode.innerHTML = stringReplace(currentNode.textContent, /</g, '<');
|
|
706
741
|
}
|
|
707
742
|
}
|
|
708
743
|
|
|
@@ -710,10 +745,10 @@ function createDOMPurify() {
|
|
|
710
745
|
if (SAFE_FOR_TEMPLATES && currentNode.nodeType === 3) {
|
|
711
746
|
/* Get the element's text content */
|
|
712
747
|
content = currentNode.textContent;
|
|
713
|
-
content = content
|
|
714
|
-
content = content
|
|
748
|
+
content = stringReplace(content, MUSTACHE_EXPR$$1, ' ');
|
|
749
|
+
content = stringReplace(content, ERB_EXPR$$1, ' ');
|
|
715
750
|
if (currentNode.textContent !== content) {
|
|
716
|
-
DOMPurify.removed
|
|
751
|
+
arrayPush(DOMPurify.removed, { element: currentNode.cloneNode() });
|
|
717
752
|
currentNode.textContent = content;
|
|
718
753
|
}
|
|
719
754
|
}
|
|
@@ -743,9 +778,9 @@ function createDOMPurify() {
|
|
|
743
778
|
(https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)
|
|
744
779
|
XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)
|
|
745
780
|
We don't need to check the value; it's always URI safe. */
|
|
746
|
-
if (ALLOW_DATA_ATTR && DATA_ATTR$$1
|
|
781
|
+
if (ALLOW_DATA_ATTR && regExpTest(DATA_ATTR$$1, lcName)) {
|
|
747
782
|
// This attribute is safe
|
|
748
|
-
} else if (ALLOW_ARIA_ATTR && ARIA_ATTR$$1
|
|
783
|
+
} else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$$1, lcName)) {
|
|
749
784
|
// This attribute is safe
|
|
750
785
|
/* Otherwise, check the name is permitted */
|
|
751
786
|
} else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) {
|
|
@@ -756,16 +791,16 @@ function createDOMPurify() {
|
|
|
756
791
|
// This attribute is safe
|
|
757
792
|
/* Check no script, data or unknown possibly unsafe URI
|
|
758
793
|
unless we know URI values are safe for that attribute */
|
|
759
|
-
} else if (IS_ALLOWED_URI$$1
|
|
794
|
+
} else if (regExpTest(IS_ALLOWED_URI$$1, stringReplace(value, ATTR_WHITESPACE$$1, ''))) {
|
|
760
795
|
// This attribute is safe
|
|
761
796
|
/* Keep image data URIs alive if src/xlink:href is allowed */
|
|
762
797
|
/* Further prevent gadget XSS for dynamically built script tags */
|
|
763
|
-
} else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && value
|
|
798
|
+
} else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && stringIndexOf(value, 'data:') === 0 && DATA_URI_TAGS[lcTag]) {
|
|
764
799
|
// This attribute is safe
|
|
765
800
|
/* Allow unknown protocols: This provides support for links that
|
|
766
801
|
are handled by protocol handlers which may be unknown ahead of
|
|
767
802
|
time, e.g. fb:, spotify: */
|
|
768
|
-
} else if (ALLOW_UNKNOWN_PROTOCOLS && !IS_SCRIPT_OR_DATA$$1
|
|
803
|
+
} else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA$$1, stringReplace(value, ATTR_WHITESPACE$$1, ''))) {
|
|
769
804
|
// This attribute is safe
|
|
770
805
|
/* Check for binary attributes */
|
|
771
806
|
// eslint-disable-next-line no-negated-condition
|
|
@@ -822,15 +857,20 @@ function createDOMPurify() {
|
|
|
822
857
|
name = _attr.name,
|
|
823
858
|
namespaceURI = _attr.namespaceURI;
|
|
824
859
|
|
|
825
|
-
value = attr.value
|
|
826
|
-
lcName = name
|
|
860
|
+
value = stringTrim(attr.value);
|
|
861
|
+
lcName = stringToLowerCase(name);
|
|
827
862
|
|
|
828
863
|
/* Execute a hook if present */
|
|
829
864
|
hookEvent.attrName = lcName;
|
|
830
865
|
hookEvent.attrValue = value;
|
|
831
866
|
hookEvent.keepAttr = true;
|
|
867
|
+
hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set
|
|
832
868
|
_executeHook('uponSanitizeAttribute', currentNode, hookEvent);
|
|
833
869
|
value = hookEvent.attrValue;
|
|
870
|
+
/* Did the hooks approve of the attribute? */
|
|
871
|
+
if (hookEvent.forceKeepAttr) {
|
|
872
|
+
continue;
|
|
873
|
+
}
|
|
834
874
|
|
|
835
875
|
/* Remove attribute */
|
|
836
876
|
// Safari (iOS + Mac), last tested v8.0.5, crashes if you try to
|
|
@@ -838,10 +878,10 @@ function createDOMPurify() {
|
|
|
838
878
|
// attribute at the time.
|
|
839
879
|
if (lcName === 'name' && currentNode.nodeName === 'IMG' && attributes.id) {
|
|
840
880
|
idAttr = attributes.id;
|
|
841
|
-
attributes =
|
|
881
|
+
attributes = arraySlice(attributes, []);
|
|
842
882
|
_removeAttribute('id', currentNode);
|
|
843
883
|
_removeAttribute(name, currentNode);
|
|
844
|
-
if (attributes
|
|
884
|
+
if (arrayIndexOf(attributes, idAttr) > l) {
|
|
845
885
|
currentNode.setAttribute('id', idAttr.value);
|
|
846
886
|
}
|
|
847
887
|
} else if (
|
|
@@ -865,16 +905,22 @@ function createDOMPurify() {
|
|
|
865
905
|
continue;
|
|
866
906
|
}
|
|
867
907
|
|
|
908
|
+
/* Work around a security issue in jQuery 3.0 */
|
|
909
|
+
if (SAFE_FOR_JQUERY && regExpTest(/\/>/i, value)) {
|
|
910
|
+
_removeAttribute(name, currentNode);
|
|
911
|
+
continue;
|
|
912
|
+
}
|
|
913
|
+
|
|
868
914
|
/* Take care of an mXSS pattern using namespace switches */
|
|
869
|
-
if (/svg|math/i
|
|
915
|
+
if (regExpTest(/svg|math/i, currentNode.namespaceURI) && regExpTest(regExpCreate('</(' + arrayJoin(objectKeys(FORBID_CONTENTS), '|') + ')', 'i'), value)) {
|
|
870
916
|
_removeAttribute(name, currentNode);
|
|
871
917
|
continue;
|
|
872
918
|
}
|
|
873
919
|
|
|
874
920
|
/* Sanitize attribute content to be template-safe */
|
|
875
921
|
if (SAFE_FOR_TEMPLATES) {
|
|
876
|
-
value = value
|
|
877
|
-
value = value
|
|
922
|
+
value = stringReplace(value, MUSTACHE_EXPR$$1, ' ');
|
|
923
|
+
value = stringReplace(value, ERB_EXPR$$1, ' ');
|
|
878
924
|
}
|
|
879
925
|
|
|
880
926
|
/* Is `value` valid for this attribute? */
|
|
@@ -892,7 +938,7 @@ function createDOMPurify() {
|
|
|
892
938
|
currentNode.setAttribute(name, value);
|
|
893
939
|
}
|
|
894
940
|
|
|
895
|
-
DOMPurify.removed
|
|
941
|
+
arrayPop(DOMPurify.removed);
|
|
896
942
|
} catch (error) {}
|
|
897
943
|
}
|
|
898
944
|
|
|
@@ -959,11 +1005,11 @@ function createDOMPurify() {
|
|
|
959
1005
|
if (typeof dirty !== 'string' && !_isNode(dirty)) {
|
|
960
1006
|
// eslint-disable-next-line no-negated-condition
|
|
961
1007
|
if (typeof dirty.toString !== 'function') {
|
|
962
|
-
throw
|
|
1008
|
+
throw typeErrorCreate('toString is not a function');
|
|
963
1009
|
} else {
|
|
964
1010
|
dirty = dirty.toString();
|
|
965
1011
|
if (typeof dirty !== 'string') {
|
|
966
|
-
throw
|
|
1012
|
+
throw typeErrorCreate('dirty is not a string, aborting');
|
|
967
1013
|
}
|
|
968
1014
|
}
|
|
969
1015
|
}
|
|
@@ -991,6 +1037,11 @@ function createDOMPurify() {
|
|
|
991
1037
|
/* Clean up removed elements */
|
|
992
1038
|
DOMPurify.removed = [];
|
|
993
1039
|
|
|
1040
|
+
/* Check if dirty is correctly typed for IN_PLACE */
|
|
1041
|
+
if (typeof dirty === 'string') {
|
|
1042
|
+
IN_PLACE = false;
|
|
1043
|
+
}
|
|
1044
|
+
|
|
994
1045
|
if (IN_PLACE) {
|
|
995
1046
|
/* No special handling necessary for in-place sanitization */
|
|
996
1047
|
} else if (dirty instanceof Node) {
|
|
@@ -1089,8 +1140,8 @@ function createDOMPurify() {
|
|
|
1089
1140
|
|
|
1090
1141
|
/* Sanitize final string template-safe */
|
|
1091
1142
|
if (SAFE_FOR_TEMPLATES) {
|
|
1092
|
-
serializedHTML = serializedHTML
|
|
1093
|
-
serializedHTML = serializedHTML
|
|
1143
|
+
serializedHTML = stringReplace(serializedHTML, MUSTACHE_EXPR$$1, ' ');
|
|
1144
|
+
serializedHTML = stringReplace(serializedHTML, ERB_EXPR$$1, ' ');
|
|
1094
1145
|
}
|
|
1095
1146
|
|
|
1096
1147
|
return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML;
|
|
@@ -1133,8 +1184,8 @@ function createDOMPurify() {
|
|
|
1133
1184
|
_parseConfig({});
|
|
1134
1185
|
}
|
|
1135
1186
|
|
|
1136
|
-
var lcTag = tag
|
|
1137
|
-
var lcName = attr
|
|
1187
|
+
var lcTag = stringToLowerCase(tag);
|
|
1188
|
+
var lcName = stringToLowerCase(attr);
|
|
1138
1189
|
return _isValidAttribute(lcTag, lcName, value);
|
|
1139
1190
|
};
|
|
1140
1191
|
|
|
@@ -1151,7 +1202,7 @@ function createDOMPurify() {
|
|
|
1151
1202
|
}
|
|
1152
1203
|
|
|
1153
1204
|
hooks[entryPoint] = hooks[entryPoint] || [];
|
|
1154
|
-
hooks[entryPoint]
|
|
1205
|
+
arrayPush(hooks[entryPoint], hookFunction);
|
|
1155
1206
|
};
|
|
1156
1207
|
|
|
1157
1208
|
/**
|
|
@@ -1163,7 +1214,7 @@ function createDOMPurify() {
|
|
|
1163
1214
|
*/
|
|
1164
1215
|
DOMPurify.removeHook = function (entryPoint) {
|
|
1165
1216
|
if (hooks[entryPoint]) {
|
|
1166
|
-
hooks[entryPoint]
|
|
1217
|
+
arrayPop(hooks[entryPoint]);
|
|
1167
1218
|
}
|
|
1168
1219
|
};
|
|
1169
1220
|
|