AutorÃa | Ultima modificación | Ver Log |
/*** --------------------------------------------------------------------------* Bootstrap (v4.6.2): tools/sanitizer.js* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)* --------------------------------------------------------------------------*/const uriAttrs = ['background','cite','href','itemtype','longdesc','poster','src','xlink:href']const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/iexport const DefaultWhitelist = {// Global attributes allowed on any supplied element below.'*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],a: ['target', 'href', 'title', 'rel'],area: [],b: [],br: [],col: [],code: [],div: [],em: [],hr: [],h1: [],h2: [],h3: [],h4: [],h5: [],h6: [],i: [],img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],li: [],ol: [],p: [],pre: [],s: [],small: [],span: [],sub: [],sup: [],strong: [],u: [],ul: []}/*** A pattern that recognizes a commonly useful subset of URLs that are safe.** Shoutout to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts*/const SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i/*** A pattern that matches safe data URLs. Only matches image, video and audio types.** Shoutout to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts*/const DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/ifunction allowedAttribute(attr, allowedAttributeList) {const attrName = attr.nodeName.toLowerCase()if (allowedAttributeList.indexOf(attrName) !== -1) {if (uriAttrs.indexOf(attrName) !== -1) {return Boolean(SAFE_URL_PATTERN.test(attr.nodeValue) || DATA_URL_PATTERN.test(attr.nodeValue))}return true}const regExp = allowedAttributeList.filter(attrRegex => attrRegex instanceof RegExp)// Check if a regular expression validates the attribute.for (let i = 0, len = regExp.length; i < len; i++) {if (regExp[i].test(attrName)) {return true}}return false}export function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) {if (unsafeHtml.length === 0) {return unsafeHtml}if (sanitizeFn && typeof sanitizeFn === 'function') {return sanitizeFn(unsafeHtml)}const domParser = new window.DOMParser()const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html')const whitelistKeys = Object.keys(whiteList)const elements = [].slice.call(createdDocument.body.querySelectorAll('*'))for (let i = 0, len = elements.length; i < len; i++) {const el = elements[i]const elName = el.nodeName.toLowerCase()if (whitelistKeys.indexOf(el.nodeName.toLowerCase()) === -1) {el.parentNode.removeChild(el)continue}const attributeList = [].slice.call(el.attributes)// eslint-disable-next-line unicorn/prefer-spreadconst whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || [])attributeList.forEach(attr => {if (!allowedAttribute(attr, whitelistedAttributes)) {el.removeAttribute(attr.nodeName)}})}return createdDocument.body.innerHTML}