From f10b1003793a54d5d04c819e94cad02c78e10a82 Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Sun, 21 Apr 2019 07:49:44 -0400 Subject: [PATCH] Fix the handling of pseudoclass-based generic cosmetic filters Related issue: - https://github.com/uBlockOrigin/uBlock-issues/issues/464 Regression from: https://github.com/gorhill/uBlock/commit/261ef8c510fd91ead57948d1f7793a7a5e2a25fd?diff=unified#diff-3b15596213ed9ba37fb5b8bb1402a6c2R599 Pseudoclass-based generic cosmetic filters were improperly seen as invalid following the regression. --- src/js/cosmetic-filtering.js | 9 +++++++- src/js/static-ext-filtering.js | 38 +++++++++++++++------------------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/js/cosmetic-filtering.js b/src/js/cosmetic-filtering.js index f03fdf680..dc2217dcb 100644 --- a/src/js/cosmetic-filtering.js +++ b/src/js/cosmetic-filtering.js @@ -596,7 +596,14 @@ FilterContainer.prototype.compileGenericHideSelector = function( // - Bad syntax // - Procedural filters (can't be generic): the compiled version of // a procedural selector is NEVER equal to its raw version. - if ( compiled === undefined || compiled !== selector ) { + // https://github.com/uBlockOrigin/uBlock-issues/issues/464 + // Pseudoclass-based selectors can be compiled, but are also valid + // plain selectors. + if ( + compiled === undefined || + compiled !== selector && + µb.staticExtFilteringEngine.compileSelector.pseudoclass !== true + ) { const who = writer.properties.get('assetKey') || '?'; µb.logger.writeOne({ realm: 'message', diff --git a/src/js/static-ext-filtering.js b/src/js/static-ext-filtering.js index e8c8a9535..fb5670b4d 100644 --- a/src/js/static-ext-filtering.js +++ b/src/js/static-ext-filtering.js @@ -467,7 +467,7 @@ return µb.cosmeticFilteringEngine.discardedCount + µb.scriptletFilteringEngine.discardedCount + µb.htmlFilteringEngine.discardedCount; - } + }, }; //-------------------------------------------------------------------------- @@ -664,6 +664,8 @@ }; const entryPoint = function(raw) { + entryPoint.pseudoclass = false; + const extendedSyntax = reExtendedSyntax.test(raw); if ( isValidCSSSelector(raw) && extendedSyntax === false ) { return raw; @@ -672,18 +674,18 @@ // We rarely reach this point -- majority of selectors are plain // CSS selectors. - let matches, operator; + let matches; - // Supported Adguard/ABP advanced selector syntax: will translate into - // uBO's syntax before further processing. + // Supported Adguard/ABP advanced selector syntax: will translate + // into uBO's syntax before further processing. // Mind unsupported advanced selector syntax, such as ABP's // `-abp-properties`. - // Note: extended selector syntax has been deprecated in ABP, in favor - // of the procedural one (i.e. `:operator(...)`). See - // https://issues.adblockplus.org/ticket/5287 + // Note: extended selector syntax has been deprecated in ABP, in + // favor of the procedural one (i.e. `:operator(...)`). + // See https://issues.adblockplus.org/ticket/5287 if ( extendedSyntax ) { while ( (matches = reExtendedSyntaxParser.exec(raw)) !== null ) { - operator = normalizedExtendedSyntaxOperators.get(matches[1]); + const operator = normalizedExtendedSyntaxOperators.get(matches[1]); if ( operator === undefined ) { return; } raw = raw.slice(0, matches.index) + operator + '(' + matches[3] + ')' + @@ -692,8 +694,7 @@ return entryPoint(raw); } - let selector = raw, - pseudoclass, style; + let selector = raw, pseudoclass, style; // `:style` selector? if ( (matches = reStyleSelector.exec(selector)) !== null ) { @@ -709,23 +710,16 @@ } if ( style !== undefined || pseudoclass !== undefined ) { - if ( isValidCSSSelector(selector) === false ) { - return; - } + if ( isValidCSSSelector(selector) === false ) { return; } if ( pseudoclass !== undefined ) { selector += pseudoclass; } if ( style !== undefined ) { if ( isValidStyleProperty(style) === false ) { return; } - return JSON.stringify({ - raw: raw, - style: [ selector, style ] - }); + return JSON.stringify({ raw, style: [ selector, style ] }); } - return JSON.stringify({ - raw: raw, - pseudoclass: true - }); + entryPoint.pseudoclass = true; + return JSON.stringify({ raw, pseudoclass: true }); } // Procedural selector? @@ -735,6 +729,8 @@ } }; + entryPoint.pseudoclass = false; + return entryPoint; })();