dompurify 3.2.5 → 3.2.6

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.
@@ -1,4 +1,4 @@
1
- /*! @license DOMPurify 3.2.5 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.5/LICENSE */
1
+ /*! @license DOMPurify 3.2.6 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.6/LICENSE */
2
2
 
3
3
  import { TrustedTypePolicy, TrustedHTML, TrustedTypesWindow } from 'trusted-types/lib';
4
4
 
@@ -1,4 +1,4 @@
1
- /*! @license DOMPurify 3.2.5 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.5/LICENSE */
1
+ /*! @license DOMPurify 3.2.6 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.6/LICENSE */
2
2
 
3
3
  const {
4
4
  entries,
@@ -202,7 +202,7 @@ const ERB_EXPR = seal(/<%[\w\W]*|[\w\W]*%>/gm);
202
202
  const TMPLIT_EXPR = seal(/\$\{[\w\W]*/gm); // eslint-disable-line unicorn/better-regex
203
203
  const DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]+$/); // eslint-disable-line no-useless-escape
204
204
  const ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape
205
- const IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape
205
+ const IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape
206
206
  );
207
207
  const IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i);
208
208
  const ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g // eslint-disable-line no-control-regex
@@ -299,7 +299,7 @@ const _createHooksMap = function _createHooksMap() {
299
299
  function createDOMPurify() {
300
300
  let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();
301
301
  const DOMPurify = root => createDOMPurify(root);
302
- DOMPurify.version = '3.2.5';
302
+ DOMPurify.version = '3.2.6';
303
303
  DOMPurify.removed = [];
304
304
  if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) {
305
305
  // Not running in a browser, provide a factory function
@@ -538,8 +538,8 @@ function createDOMPurify() {
538
538
  URI_SAFE_ATTRIBUTES = objectHasOwnProperty(cfg, 'ADD_URI_SAFE_ATTR') ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR, transformCaseFunc) : DEFAULT_URI_SAFE_ATTRIBUTES;
539
539
  DATA_URI_TAGS = objectHasOwnProperty(cfg, 'ADD_DATA_URI_TAGS') ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS, transformCaseFunc) : DEFAULT_DATA_URI_TAGS;
540
540
  FORBID_CONTENTS = objectHasOwnProperty(cfg, 'FORBID_CONTENTS') ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS;
541
- FORBID_TAGS = objectHasOwnProperty(cfg, 'FORBID_TAGS') ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : {};
542
- FORBID_ATTR = objectHasOwnProperty(cfg, 'FORBID_ATTR') ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : {};
541
+ FORBID_TAGS = objectHasOwnProperty(cfg, 'FORBID_TAGS') ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : clone({});
542
+ FORBID_ATTR = objectHasOwnProperty(cfg, 'FORBID_ATTR') ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : clone({});
543
543
  USE_PROFILES = objectHasOwnProperty(cfg, 'USE_PROFILES') ? cfg.USE_PROFILES : false;
544
544
  ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true
545
545
  ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true
@@ -904,7 +904,7 @@ function createDOMPurify() {
904
904
  allowedTags: ALLOWED_TAGS
905
905
  });
906
906
  /* Detect mXSS attempts abusing namespace confusion */
907
- if (currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\w!]/g, currentNode.innerHTML) && regExpTest(/<[/\w!]/g, currentNode.textContent)) {
907
+ if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\w!]/g, currentNode.innerHTML) && regExpTest(/<[/\w!]/g, currentNode.textContent)) {
908
908
  _forceRemove(currentNode);
909
909
  return true;
910
910
  }
@@ -1056,7 +1056,8 @@ function createDOMPurify() {
1056
1056
  value: attrValue
1057
1057
  } = attr;
1058
1058
  const lcName = transformCaseFunc(name);
1059
- let value = name === 'value' ? attrValue : stringTrim(attrValue);
1059
+ const initValue = attrValue;
1060
+ let value = name === 'value' ? initValue : stringTrim(initValue);
1060
1061
  /* Execute a hook if present */
1061
1062
  hookEvent.attrName = lcName;
1062
1063
  hookEvent.attrValue = value;
@@ -1082,10 +1083,9 @@ function createDOMPurify() {
1082
1083
  if (hookEvent.forceKeepAttr) {
1083
1084
  continue;
1084
1085
  }
1085
- /* Remove attribute */
1086
- _removeAttribute(name, currentNode);
1087
1086
  /* Did the hooks approve of the attribute? */
1088
1087
  if (!hookEvent.keepAttr) {
1088
+ _removeAttribute(name, currentNode);
1089
1089
  continue;
1090
1090
  }
1091
1091
  /* Work around a security issue in jQuery 3.0 */
@@ -1102,6 +1102,7 @@ function createDOMPurify() {
1102
1102
  /* Is `value` valid for this attribute? */
1103
1103
  const lcTag = transformCaseFunc(currentNode.nodeName);
1104
1104
  if (!_isValidAttribute(lcTag, lcName, value)) {
1105
+ _removeAttribute(name, currentNode);
1105
1106
  continue;
1106
1107
  }
1107
1108
  /* Handle attributes that require Trusted Types */
@@ -1122,19 +1123,23 @@ function createDOMPurify() {
1122
1123
  }
1123
1124
  }
1124
1125
  /* Handle invalid data-* attribute set by try-catching it */
1125
- try {
1126
- if (namespaceURI) {
1127
- currentNode.setAttributeNS(namespaceURI, name, value);
1128
- } else {
1129
- /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. "x-schema". */
1130
- currentNode.setAttribute(name, value);
1131
- }
1132
- if (_isClobbered(currentNode)) {
1133
- _forceRemove(currentNode);
1134
- } else {
1135
- arrayPop(DOMPurify.removed);
1126
+ if (value !== initValue) {
1127
+ try {
1128
+ if (namespaceURI) {
1129
+ currentNode.setAttributeNS(namespaceURI, name, value);
1130
+ } else {
1131
+ /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. "x-schema". */
1132
+ currentNode.setAttribute(name, value);
1133
+ }
1134
+ if (_isClobbered(currentNode)) {
1135
+ _forceRemove(currentNode);
1136
+ } else {
1137
+ arrayPop(DOMPurify.removed);
1138
+ }
1139
+ } catch (_) {
1140
+ _removeAttribute(name, currentNode);
1136
1141
  }
1137
- } catch (_) {}
1142
+ }
1138
1143
  }
1139
1144
  /* Execute a hook if present */
1140
1145
  _executeHooks(hooks.afterSanitizeAttributes, currentNode, null);