diff --git a/src/js/resources/href-sanitizer.js b/src/js/resources/href-sanitizer.js index c445f024c..82a9a95c8 100644 --- a/src/js/resources/href-sanitizer.js +++ b/src/js/resources/href-sanitizer.js @@ -91,6 +91,20 @@ function hrefSanitizer( } return ''; }; + const extractParam = (href, source) => { + if ( Boolean(source) === false ) { return href; } + const recursive = source.includes('?', 1); + const end = recursive ? source.indexOf('?', 1) : source.length; + try { + const url = new URL(href, document.location); + let value = url.searchParams.get(source.slice(1, end)); + if ( value === null ) { return href } + if ( recursive ) { return extractParam(value, source.slice(end)); } + return value; + } catch(x) { + } + return href; + }; const extractURL = (elem, source) => { if ( /^\[.*\]$/.test(source) ) { return elem.getAttribute(source.slice(1,-1).trim()) || ''; @@ -101,13 +115,13 @@ function hrefSanitizer( .replace(/[^\x21-\x7e]+$/, '') // remove trailing invalid characters ; } - if ( source.startsWith('?') ) { - const steps = source.replace(/(\S)\?/g, '\\1?').split(/\s+/); - const url = urlSkip(elem.href, false, steps); - if ( url === undefined ) { return; } - return url.replace(/ /g, '%20'); - } - return ''; + if ( source.startsWith('?') === false ) { return ''; } + const steps = source.replace(/(\S)\?/g, '\\1?').split(/\s+/); + const url = steps.length === 1 + ? extractParam(elem.href, source) + : urlSkip(elem.href, false, steps); + if ( url === undefined ) { return; } + return url.replace(/ /g, '%20'); }; const sanitize = ( ) => { let elems = [];