PageSourceSearch

https://woehrden.de/wp-content/plugins/events-made-easy/js/eme_sethtml.js?ver=3.2.21

js woehrden.de collected 2026-10-02 22:46:18 UTC 2,682 bytes, 54 lines download raw bytes

1// Minimal Element.prototype.setHTML polyfill.
2// Uses the native setHTML (default sanitizer) when available.
3// For browsers without it (as of writing: all of Safari/iOS, plus older
4// Chrome/Firefox), falls back to a DOM-based sanitizer that removes
5// XSS-unsafe elements and attributes (scripts, event handlers, javascript:
6// URLs, <base> hijacking, etc). Since Safari has no native support yet,
7// this fallback is the primary path for a large share of visitors, not
8// just a rare edge case - keep it in sync with the native default
9// Sanitizer's coverage rather than treating it as a stopgap.
10if ( ! ( 'setHTML' in Element.prototype ) ) {
11    const UNSAFE_TAGS = ['SCRIPT', 'IFRAME', 'OBJECT', 'EMBED', 'FRAME', 'APPLET', 'LINK', 'META', 'STYLE', 'BASE'];
12    const UNSAFE_ATTRS = ['srcdoc'];
13    const UNSAFE_SCHEMES = ['javascript:', 'vbscript:', 'data:text/html'];
14    const URL_ATTRS = ['href', 'src', 'action', 'formaction', 'xlink:href'];
15
16    Element.prototype.setHTML = function( input ) {
17        const template = document.createElement( 'template' );
18        template.innerHTML = input;
19        const fragment = template.content;
20
21        const iterator = document.createNodeIterator( fragment, NodeFilter.SHOW_ELEMENT );
22        let currentNode;
23        while ( ( currentNode = iterator.nextNode() ) ) {
24            const tagName = currentNode.tagName;
25            if ( UNSAFE_TAGS.includes( tagName ) ) {
26                currentNode.remove();
27                continue;
28            }
29
30            const attrs = currentNode.attributes;
31            if ( attrs ) {
32                for ( let i = attrs.length - 1; i >= 0; i-- ) {
33                    const attr = attrs[i];
34                    const attrName = attr.name.toLowerCase();
35                    // Browsers ignore ASCII tabs/newlines anywhere in a URL
36                    // before resolving its scheme, so strip them here too -
37                    // otherwise "jav\tascript:" slips past a plain startsWith check.
38                    const attrValue = attr.value.trim().toLowerCase().replace( /[\t\n\r]/g, '' );
39
40                    const isEventHandler = attrName.startsWith( 'on' ) && attrName.length > 2;
41                    const isUnsafeAttr = UNSAFE_ATTRS.includes( attrName );
42                    const isUnsafeUrl = URL_ATTRS.includes( attrName ) &&
43                        UNSAFE_SCHEMES.some( scheme => attrValue.startsWith( scheme ) );
44
45                    if ( isEventHandler || isUnsafeAttr || isUnsafeUrl ) {
46                        currentNode.removeAttribute( attr.name );
47                    }
48                }
49            }
50        }
51
52        this.replaceChildren( fragment );
53    };
54}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.