UNPKG

@glimmer/runtime

Version:

Minimal runtime needed to render Glimmer templates

113 lines (91 loc) 11.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.requiresSanitization = requiresSanitization; exports.sanitizeAttributeValue = sanitizeAttributeValue; var _normalize = require("../dom/normalize"); const badProtocols = ['javascript:', 'vbscript:']; const badTags = ['A', 'BODY', 'LINK', 'IMG', 'IFRAME', 'BASE', 'FORM']; const badTagsForDataURI = ['EMBED']; const badAttributes = ['href', 'src', 'background', 'action']; const badAttributesForDataURI = ['src']; function has(array, item) { return array.indexOf(item) !== -1; } function checkURI(tagName, attribute) { return (tagName === null || has(badTags, tagName)) && has(badAttributes, attribute); } function checkDataURI(tagName, attribute) { if (tagName === null) return false; return has(badTagsForDataURI, tagName) && has(badAttributesForDataURI, attribute); } function requiresSanitization(tagName, attribute) { return checkURI(tagName, attribute) || checkDataURI(tagName, attribute); } let protocolForUrl; if (typeof URL === 'object' && URL !== null && // this is super annoying, TS thinks that URL **must** be a function so `URL.parse` check // thinks it is `never` without this `as unknown as any` typeof URL.parse === 'function') { // In Ember-land the `fastboot` package sets the `URL` global to `require('url')` // ultimately, this should be changed (so that we can either rely on the natural `URL` global // that exists) but for now we have to detect the specific `FastBoot` case first // // a future version of `fastboot` will detect if this legacy URL setup is required (by // inspecting Ember version) and if new enough, it will avoid shadowing the `URL` global // constructor with `require('url')`. let nodeURL = URL; protocolForUrl = url => { let protocol = null; if (typeof url === 'string') { protocol = nodeURL.parse(url).protocol; } return protocol === null ? ':' : protocol; }; } else if (typeof URL === 'function') { protocolForUrl = _url => { try { let url = new URL(_url); return url.protocol; } catch (error) { // any non-fully qualified url string will trigger an error (because there is no // baseURI that we can provide; in that case we **know** that the protocol is // "safe" because it isn't specifically one of the `badProtocols` listed above // (and those protocols can never be the default baseURI) return ':'; } }; } else { // fallback for IE11 support let parsingNode = document.createElement('a'); protocolForUrl = url => { parsingNode.href = url; return parsingNode.protocol; }; } function sanitizeAttributeValue(element, attribute, value) { let tagName = null; if (value === null || value === undefined) { return value; } if ((0, _normalize.isSafeString)(value)) { return value.toHTML(); } if (!element) { tagName = null; } else { tagName = element.tagName.toUpperCase(); } let str = (0, _normalize.normalizeStringValue)(value); if (checkURI(tagName, attribute)) { let protocol = protocolForUrl(str); if (has(badProtocols, protocol)) { return `unsafe:${str}`; } } if (checkDataURI(tagName, attribute)) { return `unsafe:${str}`; } return str; } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL3J1bnRpbWUvbGliL2RvbS9zYW5pdGl6ZWQtdmFsdWVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBRUE7O0FBRUEsTUFBTSxZQUFZLEdBQUcsQ0FBQSxhQUFBLEVBQXJCLFdBQXFCLENBQXJCO0FBRUEsTUFBTSxPQUFPLEdBQUcsQ0FBQSxHQUFBLEVBQUEsTUFBQSxFQUFBLE1BQUEsRUFBQSxLQUFBLEVBQUEsUUFBQSxFQUFBLE1BQUEsRUFBaEIsTUFBZ0IsQ0FBaEI7QUFFQSxNQUFNLGlCQUFpQixHQUFHLENBQTFCLE9BQTBCLENBQTFCO0FBRUEsTUFBTSxhQUFhLEdBQUcsQ0FBQSxNQUFBLEVBQUEsS0FBQSxFQUFBLFlBQUEsRUFBdEIsUUFBc0IsQ0FBdEI7QUFFQSxNQUFNLHVCQUF1QixHQUFHLENBQWhDLEtBQWdDLENBQWhDOztBQUVBLFNBQUEsR0FBQSxDQUFBLEtBQUEsRUFBQSxJQUFBLEVBQStDO0FBQzdDLFNBQU8sS0FBSyxDQUFMLE9BQUEsQ0FBQSxJQUFBLE1BQXdCLENBQS9CLENBQUE7QUFDRDs7QUFFRCxTQUFBLFFBQUEsQ0FBQSxPQUFBLEVBQUEsU0FBQSxFQUE0RDtBQUMxRCxTQUFPLENBQUMsT0FBTyxLQUFQLElBQUEsSUFBb0IsR0FBRyxDQUFBLE9BQUEsRUFBeEIsT0FBd0IsQ0FBeEIsS0FBK0MsR0FBRyxDQUFBLGFBQUEsRUFBekQsU0FBeUQsQ0FBekQ7QUFDRDs7QUFFRCxTQUFBLFlBQUEsQ0FBQSxPQUFBLEVBQUEsU0FBQSxFQUFnRTtBQUM5RCxNQUFJLE9BQU8sS0FBWCxJQUFBLEVBQXNCLE9BQUEsS0FBQTtBQUN0QixTQUFPLEdBQUcsQ0FBQSxpQkFBQSxFQUFILE9BQUcsQ0FBSCxJQUFtQyxHQUFHLENBQUEsdUJBQUEsRUFBN0MsU0FBNkMsQ0FBN0M7QUFDRDs7QUFFSyxTQUFBLG9CQUFBLENBQUEsT0FBQSxFQUFBLFNBQUEsRUFBaUU7QUFDckUsU0FBTyxRQUFRLENBQUEsT0FBQSxFQUFSLFNBQVEsQ0FBUixJQUFnQyxZQUFZLENBQUEsT0FBQSxFQUFuRCxTQUFtRCxDQUFuRDtBQUNEOztBQVVELElBQUEsY0FBQTs7QUFFQSxJQUNFLE9BQUEsR0FBQSxLQUFBLFFBQUEsSUFDQSxHQUFHLEtBREgsSUFBQSxJQUVBO0FBQ0E7QUFDQSxPQUFTLEdBQXVCLENBQWhDLEtBQUEsS0FMRixVQUFBLEVBTUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUksT0FBTyxHQUFYLEdBQUE7O0FBRUEsRUFBQSxjQUFjLEdBQUksR0FBRCxJQUFnQjtBQUMvQixRQUFJLFFBQVEsR0FBWixJQUFBOztBQUVBLFFBQUksT0FBQSxHQUFBLEtBQUosUUFBQSxFQUE2QjtBQUMzQixNQUFBLFFBQVEsR0FBRyxPQUFPLENBQVAsS0FBQSxDQUFBLEdBQUEsRUFBWCxRQUFBO0FBQ0Q7O0FBRUQsV0FBTyxRQUFRLEtBQVIsSUFBQSxHQUFBLEdBQUEsR0FBUCxRQUFBO0FBUEYsR0FBQTtBQWhCRixDQUFBLE1BeUJPLElBQUksT0FBQSxHQUFBLEtBQUosVUFBQSxFQUErQjtBQUNwQyxFQUFBLGNBQWMsR0FBSSxJQUFELElBQWlCO0FBQ2hDLFFBQUk7QUFDRixVQUFJLEdBQUcsR0FBRyxJQUFBLEdBQUEsQ0FBVixJQUFVLENBQVY7QUFFQSxhQUFPLEdBQUcsQ0FBVixRQUFBO0FBSEYsS0FBQSxDQUlFLE9BQUEsS0FBQSxFQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFBLEdBQUE7QUFDRDtBQVhILEdBQUE7QUFESyxDQUFBLE1BY0E7QUFDTDtBQUNBLE1BQUksV0FBVyxHQUFHLFFBQVEsQ0FBUixhQUFBLENBQWxCLEdBQWtCLENBQWxCOztBQUVBLEVBQUEsY0FBYyxHQUFJLEdBQUQsSUFBZ0I7QUFDL0IsSUFBQSxXQUFXLENBQVgsSUFBQSxHQUFBLEdBQUE7QUFDQSxXQUFPLFdBQVcsQ0FBbEIsUUFBQTtBQUZGLEdBQUE7QUFJRDs7QUFFSyxTQUFBLHNCQUFBLENBQUEsT0FBQSxFQUFBLFNBQUEsRUFBQSxLQUFBLEVBR1U7QUFFZCxNQUFJLE9BQU8sR0FBWCxJQUFBOztBQUVBLE1BQUksS0FBSyxLQUFMLElBQUEsSUFBa0IsS0FBSyxLQUEzQixTQUFBLEVBQTJDO0FBQ3pDLFdBQUEsS0FBQTtBQUNEOztBQUVELE1BQUksNkJBQUosS0FBSSxDQUFKLEVBQXlCO0FBQ3ZCLFdBQU8sS0FBSyxDQUFaLE1BQU8sRUFBUDtBQUNEOztBQUVELE1BQUksQ0FBSixPQUFBLEVBQWM7QUFDWixJQUFBLE9BQU8sR0FBUCxJQUFBO0FBREYsR0FBQSxNQUVPO0FBQ0wsSUFBQSxPQUFPLEdBQUcsT0FBTyxDQUFQLE9BQUEsQ0FBVixXQUFVLEVBQVY7QUFDRDs7QUFFRCxNQUFJLEdBQUcsR0FBRyxxQ0FBVixLQUFVLENBQVY7O0FBRUEsTUFBSSxRQUFRLENBQUEsT0FBQSxFQUFaLFNBQVksQ0FBWixFQUFrQztBQUNoQyxRQUFJLFFBQVEsR0FBRyxjQUFjLENBQTdCLEdBQTZCLENBQTdCOztBQUNBLFFBQUksR0FBRyxDQUFBLFlBQUEsRUFBUCxRQUFPLENBQVAsRUFBaUM7QUFDL0IsYUFBTyxVQUFVLEdBQWpCLEVBQUE7QUFDRDtBQUNGOztBQUVELE1BQUksWUFBWSxDQUFBLE9BQUEsRUFBaEIsU0FBZ0IsQ0FBaEIsRUFBc0M7QUFDcEMsV0FBTyxVQUFVLEdBQWpCLEVBQUE7QUFDRDs7QUFFRCxTQUFBLEdBQUE7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE9wdGlvbiB9IGZyb20gJ0BnbGltbWVyL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgU2ltcGxlRWxlbWVudCB9IGZyb20gJ0BzaW1wbGUtZG9tL2ludGVyZmFjZSc7XG5pbXBvcnQgeyBpc1NhZmVTdHJpbmcsIG5vcm1hbGl6ZVN0cmluZ1ZhbHVlIH0gZnJvbSAnLi4vZG9tL25vcm1hbGl6ZSc7XG5cbmNvbnN0IGJhZFByb3RvY29scyA9IFsnamF2YXNjcmlwdDonLCAndmJzY3JpcHQ6J107XG5cbmNvbnN0IGJhZFRhZ3MgPSBbJ0EnLCAnQk9EWScsICdMSU5LJywgJ0lNRycsICdJRlJBTUUnLCAnQkFTRScsICdGT1JNJ107XG5cbmNvbnN0IGJhZFRhZ3NGb3JEYXRhVVJJID0gWydFTUJFRCddO1xuXG5jb25zdCBiYWRBdHRyaWJ1dGVzID0gWydocmVmJywgJ3NyYycsICdiYWNrZ3JvdW5kJywgJ2FjdGlvbiddO1xuXG5jb25zdCBiYWRBdHRyaWJ1dGVzRm9yRGF0YVVSSSA9IFsnc3JjJ107XG5cbmZ1bmN0aW9uIGhhcyhhcnJheTogQXJyYXk8c3RyaW5nPiwgaXRlbTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBhcnJheS5pbmRleE9mKGl0ZW0pICE9PSAtMTtcbn1cblxuZnVuY3Rpb24gY2hlY2tVUkkodGFnTmFtZTogT3B0aW9uPHN0cmluZz4sIGF0dHJpYnV0ZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiAodGFnTmFtZSA9PT0gbnVsbCB8fCBoYXMoYmFkVGFncywgdGFnTmFtZSkpICYmIGhhcyhiYWRBdHRyaWJ1dGVzLCBhdHRyaWJ1dGUpO1xufVxuXG5mdW5jdGlvbiBjaGVja0RhdGFVUkkodGFnTmFtZTogT3B0aW9uPHN0cmluZz4sIGF0dHJpYnV0ZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGlmICh0YWdOYW1lID09PSBudWxsKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiBoYXMoYmFkVGFnc0ZvckRhdGFVUkksIHRhZ05hbWUpICYmIGhhcyhiYWRBdHRyaWJ1dGVzRm9yRGF0YVVSSSwgYXR0cmlidXRlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVzU2FuaXRpemF0aW9uKHRhZ05hbWU6IHN0cmluZywgYXR0cmlidXRlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIGNoZWNrVVJJKHRhZ05hbWUsIGF0dHJpYnV0ZSkgfHwgY2hlY2tEYXRhVVJJKHRhZ05hbWUsIGF0dHJpYnV0ZSk7XG59XG5cbmludGVyZmFjZSBOb2RlVXJsUGFyc2VSZXN1bHQge1xuICBwcm90b2NvbDogc3RyaW5nIHwgbnVsbDtcbn1cblxuaW50ZXJmYWNlIE5vZGVVcmxNb2R1bGUge1xuICBwYXJzZSh1cmw6IHN0cmluZyk6IE5vZGVVcmxQYXJzZVJlc3VsdDtcbn1cblxubGV0IHByb3RvY29sRm9yVXJsOiAodXJsOiBzdHJpbmcpID0+IHN0cmluZztcblxuaWYgKFxuICB0eXBlb2YgVVJMID09PSAnb2JqZWN0JyAmJlxuICBVUkwgIT09IG51bGwgJiZcbiAgLy8gdGhpcyBpcyBzdXBlciBhbm5veWluZywgVFMgdGhpbmtzIHRoYXQgVVJMICoqbXVzdCoqIGJlIGEgZnVuY3Rpb24gc28gYFVSTC5wYXJzZWAgY2hlY2tcbiAgLy8gdGhpbmtzIGl0IGlzIGBuZXZlcmAgd2l0aG91dCB0aGlzIGBhcyB1bmtub3duIGFzIGFueWBcbiAgdHlwZW9mICgoVVJMIGFzIHVua25vd24pIGFzIGFueSkucGFyc2UgPT09ICdmdW5jdGlvbidcbikge1xuICAvLyBJbiBFbWJlci1sYW5kIHRoZSBgZmFzdGJvb3RgIHBhY2thZ2Ugc2V0cyB0aGUgYFVSTGAgZ2xvYmFsIHRvIGByZXF1aXJlKCd1cmwnKWBcbiAgLy8gdWx0aW1hdGVseSwgdGhpcyBzaG91bGQgYmUgY2hhbmdlZCAoc28gdGhhdCB3ZSBjYW4gZWl0aGVyIHJlbHkgb24gdGhlIG5hdHVyYWwgYFVSTGAgZ2xvYmFsXG4gIC8vIHRoYXQgZXhpc3RzKSBidXQgZm9yIG5vdyB3ZSBoYXZlIHRvIGRldGVjdCB0aGUgc3BlY2lmaWMgYEZhc3RCb290YCBjYXNlIGZpcnN0XG4gIC8vXG4gIC8vIGEgZnV0dXJlIHZlcnNpb24gb2YgYGZhc3Rib290YCB3aWxsIGRldGVjdCBpZiB0aGlzIGxlZ2FjeSBVUkwgc2V0dXAgaXMgcmVxdWlyZWQgKGJ5XG4gIC8vIGluc3BlY3RpbmcgRW1iZXIgdmVyc2lvbikgYW5kIGlmIG5ldyBlbm91Z2gsIGl0IHdpbGwgYXZvaWQgc2hhZG93aW5nIHRoZSBgVVJMYCBnbG9iYWxcbiAgLy8gY29uc3RydWN0b3Igd2l0aCBgcmVxdWlyZSgndXJsJylgLlxuICBsZXQgbm9kZVVSTCA9IFVSTCBhcyBOb2RlVXJsTW9kdWxlO1xuXG4gIHByb3RvY29sRm9yVXJsID0gKHVybDogc3RyaW5nKSA9PiB7XG4gICAgbGV0IHByb3RvY29sID0gbnVsbDtcblxuICAgIGlmICh0eXBlb2YgdXJsID09PSAnc3RyaW5nJykge1xuICAgICAgcHJvdG9jb2wgPSBub2RlVVJMLnBhcnNlKHVybCkucHJvdG9jb2w7XG4gICAgfVxuXG4gICAgcmV0dXJuIHByb3RvY29sID09PSBudWxsID8gJzonIDogcHJvdG9jb2w7XG4gIH07XG59IGVsc2UgaWYgKHR5cGVvZiBVUkwgPT09ICdmdW5jdGlvbicpIHtcbiAgcHJvdG9jb2xGb3JVcmwgPSAoX3VybDogc3RyaW5nKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGxldCB1cmwgPSBuZXcgVVJMKF91cmwpO1xuXG4gICAgICByZXR1cm4gdXJsLnByb3RvY29sO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBhbnkgbm9uLWZ1bGx5IHF1YWxpZmllZCB1cmwgc3RyaW5nIHdpbGwgdHJpZ2dlciBhbiBlcnJvciAoYmVjYXVzZSB0aGVyZSBpcyBub1xuICAgICAgLy8gYmFzZVVSSSB0aGF0IHdlIGNhbiBwcm92aWRlOyBpbiB0aGF0IGNhc2Ugd2UgKiprbm93KiogdGhhdCB0aGUgcHJvdG9jb2wgaXNcbiAgICAgIC8vIFwic2FmZVwiIGJlY2F1c2UgaXQgaXNuJ3Qgc3BlY2lmaWNhbGx5IG9uZSBvZiB0aGUgYGJhZFByb3RvY29sc2AgbGlzdGVkIGFib3ZlXG4gICAgICAvLyAoYW5kIHRob3NlIHByb3RvY29scyBjYW4gbmV2ZXIgYmUgdGhlIGRlZmF1bHQgYmFzZVVSSSlcbiAgICAgIHJldHVybiAnOic7XG4gICAgfVxuICB9O1xufSBlbHNlIHtcbiAgLy8gZmFsbGJhY2sgZm9yIElFMTEgc3VwcG9ydFxuICBsZXQgcGFyc2luZ05vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XG5cbiAgcHJvdG9jb2xGb3JVcmwgPSAodXJsOiBzdHJpbmcpID0+IHtcbiAgICBwYXJzaW5nTm9kZS5ocmVmID0gdXJsO1xuICAgIHJldHVybiBwYXJzaW5nTm9kZS5wcm90b2NvbDtcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNhbml0aXplQXR0cmlidXRlVmFsdWUoXG4gIGVsZW1lbnQ6IFNpbXBsZUVsZW1lbnQsXG4gIGF0dHJpYnV0ZTogc3RyaW5nLFxuICB2YWx1ZTogdW5rbm93blxuKTogdW5rbm93biB7XG4gIGxldCB0YWdOYW1lOiBPcHRpb248c3RyaW5nPiA9IG51bGw7XG5cbiAgaWYgKHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICBpZiAoaXNTYWZlU3RyaW5nKHZhbHVlKSkge1xuICAgIHJldHVybiB2YWx1ZS50b0hUTUwoKTtcbiAgfVxuXG4gIGlmICghZWxlbWVudCkge1xuICAgIHRhZ05hbWUgPSBudWxsO1xuICB9IGVsc2Uge1xuICAgIHRhZ05hbWUgPSBlbGVtZW50LnRhZ05hbWUudG9VcHBlckNhc2UoKTtcbiAgfVxuXG4gIGxldCBzdHIgPSBub3JtYWxpemVTdHJpbmdWYWx1ZSh2YWx1ZSk7XG5cbiAgaWYgKGNoZWNrVVJJKHRhZ05hbWUsIGF0dHJpYnV0ZSkpIHtcbiAgICBsZXQgcHJvdG9jb2wgPSBwcm90b2NvbEZvclVybChzdHIpO1xuICAgIGlmIChoYXMoYmFkUHJvdG9jb2xzLCBwcm90b2NvbCkpIHtcbiAgICAgIHJldHVybiBgdW5zYWZlOiR7c3RyfWA7XG4gICAgfVxuICB9XG5cbiAgaWYgKGNoZWNrRGF0YVVSSSh0YWdOYW1lLCBhdHRyaWJ1dGUpKSB7XG4gICAgcmV0dXJuIGB1bnNhZmU6JHtzdHJ9YDtcbiAgfVxuXG4gIHJldHVybiBzdHI7XG59XG4iXSwic291cmNlUm9vdCI6IiJ9