From 4fe8126c665748c4dc1e19202fb17a7cba133a6d Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Sun, 18 Jul 2021 08:50:57 -0400 Subject: [PATCH] Add ability to match against script content of data: URI Related commit: - https://github.com/gorhill/uBlock/commit/ebc42ae21e7900fafeaf1041038b94488b1d50e5 --- assets/resources/scriptlets.js | 39 +++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/assets/resources/scriptlets.js b/assets/resources/scriptlets.js index c0df514f5..5655298df 100644 --- a/assets/resources/scriptlets.js +++ b/assets/resources/scriptlets.js @@ -77,16 +77,35 @@ } const magic = String.fromCharCode(Date.now() % 26 + 97) + Math.floor(Math.random() * 982451653 + 982451653).toString(36); - const validate = function() { - const e = document.currentScript; - if ( - e instanceof HTMLScriptElement && - reContext.test(e.src) && - e !== thisScript && - reNeedle.test(e.textContent) - ) { - throw new ReferenceError(magic); + const scriptTexts = new WeakMap(); + const getScriptText = elem => { + let text = elem.textContent; + if ( text.trim() !== '' ) { return text; } + if ( scriptTexts.has(elem) ) { return scriptTexts.get(elem); } + const [ , mime, content ] = + /^data:([^,]*),(.+)$/.exec(elem.src.trim()) || + [ '', '', '' ]; + try { + switch ( true ) { + case mime.endsWith(';base64'): + text = self.atob(content); + break; + default: + text = self.decodeURIComponent(content); + break; + } + } catch(ex) { } + scriptTexts.set(elem, text); + return text; + }; + const validate = ( ) => { + const e = document.currentScript; + if ( e instanceof HTMLScriptElement === false ) { return; } + if ( reContext.test(e.src) === false ) { return; } + if ( e === thisScript ) { return; } + if ( reNeedle.test(getScriptText(e)) === false ) { return; } + throw new ReferenceError(magic); }; Object.defineProperty(owner, prop, { get: function() { @@ -106,7 +125,7 @@ }); const oe = window.onerror; window.onerror = function(msg) { - if ( typeof msg === 'string' && msg.indexOf(magic) !== -1 ) { + if ( typeof msg === 'string' && msg.includes(magic) ) { return true; } if ( oe instanceof Function ) {