dompurify 3.0.8 → 3.0.10

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 CHANGED
@@ -6,11 +6,11 @@
6
6
 
7
7
  DOMPurify is a DOM-only, super-fast, uber-tolerant XSS sanitizer for HTML, MathML and SVG.
8
8
 
9
- It's also very simple to use and get started with. DOMPurify was [started in February 2014](https://github.com/cure53/DOMPurify/commit/a630922616927373485e0e787ab19e73e3691b2b) and, meanwhile, has reached version **v3.0.8**.
9
+ It's also very simple to use and get started with. DOMPurify was [started in February 2014](https://github.com/cure53/DOMPurify/commit/a630922616927373485e0e787ab19e73e3691b2b) and, meanwhile, has reached version **v3.0.10**.
10
10
 
11
11
  DOMPurify is written in JavaScript and works in all modern browsers (Safari (10+), Opera (15+), Edge, Firefox and Chrome - as well as almost anything else using Blink, Gecko or WebKit). It doesn't break on MSIE or other legacy browsers. It simply does nothing.
12
12
 
13
- **Note that [DOMPurify v2.4.7](https://github.com/cure53/DOMPurify/releases/tag/2.4.6) is the latest version supporting MSIE. For important security updates compatible with MSIE, please use the [2.x branch](https://github.com/cure53/DOMPurify/tree/2.x).**
13
+ **Note that [DOMPurify v2.4.8](https://github.com/cure53/DOMPurify/releases/tag/2.4.8) is the latest version supporting MSIE. For important security updates compatible with MSIE, please use the [2.x branch](https://github.com/cure53/DOMPurify/tree/2.x).**
14
14
 
15
15
  Our automated tests cover [19 different browsers](https://github.com/cure53/DOMPurify/blob/main/test/karma.custom-launchers.config.js#L5) right now, more to come. We also cover Node.js v16.x, v17.x, v18.x and v19.x, running DOMPurify on [jsdom](https://github.com/jsdom/jsdom). Older Node versions are known to work as well, but hey... no guarantees.
16
16
 
@@ -413,6 +413,6 @@ Many people helped and help DOMPurify become what it is and need to be acknowled
413
413
 
414
414
  ## Testing powered by
415
415
 
416
- <a target="_blank" href="https://www.browserstack.com/"><img width="200" src="https://www.browserstack.com/images/layout/browserstack-logo-600x315.png"></a><br>
416
+ <a target="_blank" href="https://www.browserstack.com/"><img width="200" src="https://github.com/cure53/DOMPurify/assets/6709482/f70be7eb-8fc4-41ea-9653-9d359235328f"></a><br>
417
417
 
418
418
  And last but not least, thanks to [BrowserStack Open-Source Program](https://www.browserstack.com/open-source) for supporting this project with their services for free and delivering excellent, dedicated and very professional support on top of that.
@@ -1,4 +1,4 @@
1
- /*! @license DOMPurify 3.0.8 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.0.8/LICENSE */
1
+ /*! @license DOMPurify 3.0.10 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.0.10/LICENSE */
2
2
 
3
3
  'use strict';
4
4
 
@@ -47,6 +47,7 @@ const stringMatch = unapply(String.prototype.match);
47
47
  const stringReplace = unapply(String.prototype.replace);
48
48
  const stringIndexOf = unapply(String.prototype.indexOf);
49
49
  const stringTrim = unapply(String.prototype.trim);
50
+ const objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);
50
51
  const regExpTest = unapply(RegExp.prototype.test);
51
52
  const typeErrorCreate = unconstruct(TypeError);
52
53
 
@@ -122,7 +123,8 @@ function addToSet(set, array) {
122
123
  */
123
124
  function cleanArray(array) {
124
125
  for (let index = 0; index < array.length; index++) {
125
- if (getOwnPropertyDescriptor(array, index) === undefined) {
126
+ const isPropertyExist = objectHasOwnProperty(array, index);
127
+ if (!isPropertyExist) {
126
128
  array[index] = null;
127
129
  }
128
130
  }
@@ -138,7 +140,8 @@ function cleanArray(array) {
138
140
  function clone(object) {
139
141
  const newObject = create(null);
140
142
  for (const [property, value] of entries(object)) {
141
- if (getOwnPropertyDescriptor(object, property) !== undefined) {
143
+ const isPropertyExist = objectHasOwnProperty(object, property);
144
+ if (isPropertyExist) {
142
145
  if (Array.isArray(value)) {
143
146
  newObject[property] = cleanArray(value);
144
147
  } else if (value && typeof value === 'object' && value.constructor === Object) {
@@ -171,8 +174,7 @@ function lookupGetter(object, prop) {
171
174
  }
172
175
  object = getPrototypeOf(object);
173
176
  }
174
- function fallbackValue(element) {
175
- console.warn('fallback value for', element);
177
+ function fallbackValue() {
176
178
  return null;
177
179
  }
178
180
  return fallbackValue;
@@ -215,6 +217,7 @@ const ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205
215
217
  );
216
218
 
217
219
  const DOCTYPE_NAME = seal(/^html$/i);
220
+ const CUSTOM_ELEMENT = seal(/^[a-z][a-z\d]*(-[a-z\d]+)+$/i);
218
221
 
219
222
  var EXPRESSIONS = /*#__PURE__*/Object.freeze({
220
223
  __proto__: null,
@@ -226,7 +229,8 @@ var EXPRESSIONS = /*#__PURE__*/Object.freeze({
226
229
  IS_ALLOWED_URI: IS_ALLOWED_URI,
227
230
  IS_SCRIPT_OR_DATA: IS_SCRIPT_OR_DATA,
228
231
  ATTR_WHITESPACE: ATTR_WHITESPACE,
229
- DOCTYPE_NAME: DOCTYPE_NAME
232
+ DOCTYPE_NAME: DOCTYPE_NAME,
233
+ CUSTOM_ELEMENT: CUSTOM_ELEMENT
230
234
  });
231
235
 
232
236
  const getGlobal = function getGlobal() {
@@ -280,7 +284,7 @@ function createDOMPurify() {
280
284
  * Version label, exposed for easier checks
281
285
  * if DOMPurify is up to date or not
282
286
  */
283
- DOMPurify.version = '3.0.8';
287
+ DOMPurify.version = '3.0.10';
284
288
 
285
289
  /**
286
290
  * Array of elements that DOMPurify removed during sanitation.
@@ -351,7 +355,8 @@ function createDOMPurify() {
351
355
  DATA_ATTR,
352
356
  ARIA_ATTR,
353
357
  IS_SCRIPT_OR_DATA,
354
- ATTR_WHITESPACE
358
+ ATTR_WHITESPACE,
359
+ CUSTOM_ELEMENT
355
360
  } = EXPRESSIONS;
356
361
  let {
357
362
  IS_ALLOWED_URI: IS_ALLOWED_URI$1
@@ -542,27 +547,27 @@ function createDOMPurify() {
542
547
  transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? stringToString : stringToLowerCase;
543
548
 
544
549
  /* Set configuration parameters */
545
- ALLOWED_TAGS = 'ALLOWED_TAGS' in cfg ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS;
546
- ALLOWED_ATTR = 'ALLOWED_ATTR' in cfg ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR;
547
- ALLOWED_NAMESPACES = 'ALLOWED_NAMESPACES' in cfg ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES;
548
- URI_SAFE_ATTRIBUTES = 'ADD_URI_SAFE_ATTR' in cfg ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES),
550
+ ALLOWED_TAGS = objectHasOwnProperty(cfg, 'ALLOWED_TAGS') ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS;
551
+ ALLOWED_ATTR = objectHasOwnProperty(cfg, 'ALLOWED_ATTR') ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR;
552
+ ALLOWED_NAMESPACES = objectHasOwnProperty(cfg, 'ALLOWED_NAMESPACES') ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES;
553
+ URI_SAFE_ATTRIBUTES = objectHasOwnProperty(cfg, 'ADD_URI_SAFE_ATTR') ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES),
549
554
  // eslint-disable-line indent
550
555
  cfg.ADD_URI_SAFE_ATTR,
551
556
  // eslint-disable-line indent
552
557
  transformCaseFunc // eslint-disable-line indent
553
558
  ) // eslint-disable-line indent
554
559
  : DEFAULT_URI_SAFE_ATTRIBUTES;
555
- DATA_URI_TAGS = 'ADD_DATA_URI_TAGS' in cfg ? addToSet(clone(DEFAULT_DATA_URI_TAGS),
560
+ DATA_URI_TAGS = objectHasOwnProperty(cfg, 'ADD_DATA_URI_TAGS') ? addToSet(clone(DEFAULT_DATA_URI_TAGS),
556
561
  // eslint-disable-line indent
557
562
  cfg.ADD_DATA_URI_TAGS,
558
563
  // eslint-disable-line indent
559
564
  transformCaseFunc // eslint-disable-line indent
560
565
  ) // eslint-disable-line indent
561
566
  : DEFAULT_DATA_URI_TAGS;
562
- FORBID_CONTENTS = 'FORBID_CONTENTS' in cfg ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;
563
- FORBID_TAGS = 'FORBID_TAGS' in cfg ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : {};
564
- FORBID_ATTR = 'FORBID_ATTR' in cfg ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : {};
565
- USE_PROFILES = 'USE_PROFILES' in cfg ? cfg.USE_PROFILES : false;
567
+ FORBID_CONTENTS = objectHasOwnProperty(cfg, 'FORBID_CONTENTS') ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;
568
+ FORBID_TAGS = objectHasOwnProperty(cfg, 'FORBID_TAGS') ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : {};
569
+ FORBID_ATTR = objectHasOwnProperty(cfg, 'FORBID_ATTR') ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : {};
570
+ USE_PROFILES = objectHasOwnProperty(cfg, 'USE_PROFILES') ? cfg.USE_PROFILES : false;
566
571
  ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true
567
572
  ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true
568
573
  ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false
@@ -906,7 +911,7 @@ function createDOMPurify() {
906
911
  const _createNodeIterator = function _createNodeIterator(root) {
907
912
  return createNodeIterator.call(root.ownerDocument || root, root,
908
913
  // eslint-disable-next-line no-bitwise
909
- NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT, null);
914
+ NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_PROCESSING_INSTRUCTION, null);
910
915
  };
911
916
 
912
917
  /**
@@ -1088,7 +1093,7 @@ function createDOMPurify() {
1088
1093
  * @returns {boolean} Returns true if the tag name meets the basic criteria for a custom element, otherwise false.
1089
1094
  */
1090
1095
  const _isBasicCustomElement = function _isBasicCustomElement(tagName) {
1091
- return tagName.indexOf('-') > 0;
1096
+ return tagName !== 'annotation-xml' && stringMatch(tagName, CUSTOM_ELEMENT);
1092
1097
  };
1093
1098
 
1094
1099
  /**