From 5921e50e03bf2f86550ef16b0a72bf6c0bbda8f3 Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Thu, 20 Feb 2025 15:11:36 -0500 Subject: [PATCH] Fix reverse lookup of `##^responseheader(...)` filters Related issue: https://github.com/uBlockOrigin/uBlock-issues/issues/3544 --- src/js/httpheader-filtering.js | 4 +--- src/js/reverselookup-worker.js | 12 ++++++++++-- src/js/reverselookup.js | 10 ++++++---- src/js/static-filtering-parser.js | 6 ++++++ 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/js/httpheader-filtering.js b/src/js/httpheader-filtering.js index 58781fb61..20f83219b 100644 --- a/src/js/httpheader-filtering.js +++ b/src/js/httpheader-filtering.js @@ -19,7 +19,6 @@ Home: https://github.com/gorhill/uBlock */ -import * as sfp from './static-filtering-parser.js'; import { StaticExtFilteringHostnameDB } from './static-ext-filtering-db.js'; import { entityFromDomain } from './uri-utils.js'; import logger from './logger.js'; @@ -83,8 +82,7 @@ httpheaderFilteringEngine.compile = function(parser, writer) { writer.select('HTTPHEADER_FILTERS'); const isException = parser.isException(); - const root = parser.getBranchFromType(sfp.NODE_TYPE_EXT_PATTERN_RESPONSEHEADER); - const headerName = parser.getNodeString(root); + const headerName = parser.getResponseheaderName(); // Tokenless is meaningful only for exception filters. if ( headerName === '' && isException === false ) { return; } diff --git a/src/js/reverselookup-worker.js b/src/js/reverselookup-worker.js index ffdf56686..1cad3cf02 100644 --- a/src/js/reverselookup-worker.js +++ b/src/js/reverselookup-worker.js @@ -120,7 +120,7 @@ const fromExtendedFilter = function(details) { // The longer the needle, the lower the number of false positives. // https://github.com/uBlockOrigin/uBlock-issues/issues/1139 // Mind that there is no guarantee a selector has `\w` characters. - const needle = selector.match(/\w+|\*/g).reduce(function(a, b) { + const needle = (details.needle || selector).match(/\w+|\*/g).reduce(function(a, b) { return a.length > b.length ? a : b; }); @@ -213,6 +213,12 @@ const fromExtendedFilter = function(details) { /* fallthrough */ case 64: { if ( exception !== ((fargs[2] & 0b001) !== 0) ) { break; } + if ( /^responseheader\(.+\)$/.test(selector) ) { + if ( fargs[3] !== needle ) { break; } + if ( hostnameMatches(fargs[1]) === false ) { break; } + found = fargs[1] + prefix + selector; + break; + } const isProcedural = (fargs[2] & 0b010) !== 0; if ( isProcedural === false && fargs[3] !== selector || @@ -236,11 +242,13 @@ const fromExtendedFilter = function(details) { // Scriptlet injection case 32: if ( exception !== ((fargs[2] & 0b001) !== 0) ) { break; } - if ( fargs[3] !== details.compiled ) { break; } + if ( fargs[3] !== details.needle ) { break; } if ( hostnameMatches(fargs[1]) ) { found = fargs[1] + prefix + selector; } break; + default: + break; } if ( found !== undefined ) { if ( response[found] === undefined ) { diff --git a/src/js/reverselookup.js b/src/js/reverselookup.js index e1fa006d4..7a0bfb04c 100644 --- a/src/js/reverselookup.js +++ b/src/js/reverselookup.js @@ -93,7 +93,7 @@ const initWorker = function() { }; for ( const listKey in µb.availableFilterLists ) { - if ( µb.availableFilterLists.hasOwnProperty(listKey) === false ) { + if ( Object.prototype.hasOwnProperty.call(µb.availableFilterLists, listKey) === false ) { continue; } const entry = µb.availableFilterLists[listKey]; @@ -167,9 +167,11 @@ const fromExtendedFilter = async function(details) { nativeCssHas: vAPI.webextFlavor.env.includes('native_css_has'), }); parser.parse(details.rawFilter); - let compiled; + let needle; if ( parser.isScriptletFilter() ) { - compiled = JSON.stringify(parser.getScriptletArgs()); + needle = JSON.stringify(parser.getScriptletArgs()); + } else if ( parser.isResponseheaderFilter() ) { + needle = parser.getResponseheaderName(); } worker.postMessage({ @@ -188,7 +190,7 @@ const fromExtendedFilter = async function(details) { details.url ) === 2, rawFilter: details.rawFilter, - compiled, + needle, }); return new Promise(resolve => { diff --git a/src/js/static-filtering-parser.js b/src/js/static-filtering-parser.js index 73507cc6b..9315460a6 100644 --- a/src/js/static-filtering-parser.js +++ b/src/js/static-filtering-parser.js @@ -2494,6 +2494,12 @@ export class AstFilterParser { return head; } + getResponseheaderName() { + if ( this.isResponseheaderFilter() === false ) { return ''; } + const root = this.getBranchFromType(NODE_TYPE_EXT_PATTERN_RESPONSEHEADER); + return this.getNodeString(root); + } + parseExtPatternHtml(parent) { const beg = this.nodes[parent+NODE_BEG_INDEX]; const end = this.nodes[parent+NODE_END_INDEX];