]> git.proxmox.com Git - proxmox-widget-toolkit.git/blobdiff - src/Parser.js
bump version to 3.4-2
[proxmox-widget-toolkit.git] / src / Parser.js
index c92126feb1bba10fcdaa5ed78ca179bdbffb4c8c..c70e759e5a083a3482c081da4023221bedd6a972 100644 (file)
@@ -10,19 +10,36 @@ Ext.define('Proxmox.Markdown', {
        if (!input) {
            return input;
        }
+       let _isHTTPLike = value => value.match(/^\s*https?:/i); // URL's protocol ends with :
        let _sanitize;
        _sanitize = (node) => {
            if (node.nodeType === 3) return;
-           if (node.nodeType !== 1 || /^(script|iframe|object|embed|svg)$/i.test(node.tagName)) {
+           if (node.nodeType !== 1 ||
+               /^(script|style|form|select|option|optgroup|map|area|canvas|textarea|applet|font|iframe|audio|video|object|embed|svg)$/i.test(node.tagName)
+           ) {
                // could do node.remove() instead, but it's nicer UX if we keep the (encoded!) html
                node.outerHTML = Ext.String.htmlEncode(node.outerHTML);
                return;
            }
            for (let i=node.attributes.length; i--;) {
                const name = node.attributes[i].name;
+               const value = node.attributes[i].value;
                // TODO: we may want to also disallow class and id attrs
-               if (!/^(class|id|name|href|src|alt|align|valign|disabled|checked|start|type)$/i.test(name)) {
+               if (
+                   !/^(class|id|name|href|src|alt|align|valign|disabled|checked|start|type)$/i.test(name)
+               ) {
                    node.attributes.removeNamedItem(name);
+               } else if ((name === 'href' || name === 'src') && !_isHTTPLike(value)) {
+                   try {
+                       let url = new URL(value, window.location.origin);
+                       if (_isHTTPLike(url.protocol) || (node.tagName === 'img' && url.protocol === 'data:')) {
+                           node.attributes[i].value = url.href;
+                       } else {
+                           node.attributes.removeNamedItem(name);
+                       }
+                   } catch (e) {
+                       node.attributes[i].removeNamedItem(name);
+                   }
                }
            }
            for (let i=node.childNodes.length; i--;) _sanitize(node.childNodes[i]);