From 439951824af608bd445ec458f837fa39f366d75f Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Sat, 25 Mar 2023 12:35:56 -0400 Subject: [PATCH] Remove addEventListenerLogger, expand addEventListenerDefuser The scriptlet addEventListenerLogger has been removed. The logging of addEventListener() calls can now be done with the addEventListenerDefuser scriptlet, which now supports the following named arguments: "type": the event type to match. Default to '', i.e. match-all. "pattern": the pattern to match against the handler argument Default to '', i.e. match-all. "log": an integer value telling when to log: - 1: log only when both type and pattern matches, i.e. when a call to addEventListener() is defused - 2: log when either the type or pattern matches - 3: log all calls to addEventListener() "debug": an integer value telling when to break into the debugger, useful to inspect the debugger's call stack. - 1: break into the debugger when both type and pattern match, so effectively when defusing is taking place. - 2: break into the debugger when either type or pattern matches. The usage of named arguments is optional, positional arguments are still supported as documented. Named arguments is required to use "log" and/or "debug" arguments. Obviously, do not use "log" or "debug" in any filter list, these are investigative tools for filter list authors. Examples of usage using named arguments: wikipedia.org##+js(aeld, { "type": "/mouse/", "pattern": "/.^/", "log": 2 }) Above filter will log calls to addEventListener() which have the pattern "mouse" in the event type (so "mouseover", "mouseout", etc.) without defusing any of them (because pattern can't match anything). wikipedia.org##+js(aeld, { "type": "/.^/", "log": 2 }) Above filter will log all calls without defusing any of them (because type can't match anything) wikipedia.org##+js(aeld, { "log": 1 }) Above filter will log and defuse all calls to addEventListener(). --- assets/resources/scriptlets.js | 106 +++++++++++++++------------------ 1 file changed, 48 insertions(+), 58 deletions(-) diff --git a/assets/resources/scriptlets.js b/assets/resources/scriptlets.js index 63dab26ee0cd3..4934a2b6f2e1e 100644 --- a/assets/resources/scriptlets.js +++ b/assets/resources/scriptlets.js @@ -365,72 +365,62 @@ builtinScriptlets.push({ }); // https://github.com/uBlockOrigin/uAssets/issues/9123#issuecomment-848255120 function addEventListenerDefuser( - needle1 = '', - needle2 = '' + arg1 = '', + arg2 = '' ) { - if ( typeof needle1 !== 'string' ) { return; } - if ( needle1 === '' ) { - needle1 = '.?'; - } else if ( /^\/.+\/$/.test(needle1) ) { - needle1 = needle1.slice(1,-1); + const details = typeof arg1 !== 'object' + ? { type: arg1, pattern: arg2 } + : arg1; + let { type = '', pattern = '' } = details; + if ( typeof type !== 'string' ) { return; } + if ( typeof pattern !== 'string' ) { return; } + if ( type === '' ) { + type = '^'; + } else if ( /^\/.+\/$/.test(type) ) { + type = type.slice(1,-1); } else { - needle1 = needle1.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + type = type.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } - needle1 = new RegExp(needle1); - if ( needle2 === '' ) { - needle2 = '.?'; - } else if ( /^\/.+\/$/.test(needle2) ) { - needle2 = needle2.slice(1,-1); + const reType = new RegExp(type); + if ( pattern === '' ) { + pattern = '^'; + } else if ( /^\/.+\/$/.test(pattern) ) { + pattern = pattern.slice(1,-1); } else { - needle2 = needle2.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + pattern = pattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } - needle2 = new RegExp(needle2); - self.EventTarget.prototype.addEventListener = new Proxy( - self.EventTarget.prototype.addEventListener, - { - apply: function(target, thisArg, args) { - let type, handler; - try { - type = String(args[0]); - handler = String(args[1]); - } catch(ex) { - } - if ( - needle1.test(type) === false || - needle2.test(handler) === false - ) { - return target.apply(thisArg, args); - } + const rePattern = new RegExp(pattern); + const logfn = console.log.bind(console); + const proto = self.EventTarget.prototype; + proto.addEventListener = new Proxy(proto.addEventListener, { + apply: function(target, thisArg, args) { + let type, handler; + try { + type = String(args[0]); + handler = String(args[1]); + } catch(ex) { } - } - ); -} - - -/// addEventListener-logger.js -builtinScriptlets.push({ - name: 'addEventListener-logger.js', - aliases: [ 'aell.js' ], - fn: addEventListenerLogger, -}); -// https://github.com/uBlockOrigin/uAssets/issues/9123#issuecomment-848255120 -function addEventListenerLogger() { - const log = console.log.bind(console); - self.EventTarget.prototype.addEventListener = new Proxy( - self.EventTarget.prototype.addEventListener, - { - apply: function(target, thisArg, args) { - let type, handler; - try { - type = String(args[0]); - handler = String(args[1]); - } catch(ex) { - } - log('uBO: addEventListener("%s", %s)', type, handler); - return target.apply(thisArg, args); + const matchesType = reType.test(type); + const matchesHandler = rePattern.test(handler); + const matchesEither = matchesType || matchesHandler; + const matchesBoth = matchesType && matchesHandler; + if ( + details.log === 1 && matchesBoth || + details.log === 2 && matchesEither || + details.log === 3 + ) { + logfn(`uBO: addEventListener('${type}', ${handler})`); } + if ( + details.debug === 1 && matchesBoth || + details.debug === 2 && matchesEither + ) { + debugger; // jshint ignore:line + } + if ( matchesBoth ) { return; } + return Reflect.apply(target, thisArg, args); } - ); + }); }