Fix undue invalidation of pseudo element-based cosmetic filters

Regression from:
- 97befd116b

Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/2170
This commit is contained in:
Raymond Hill 2022-07-18 10:27:59 -04:00
parent 0410f62611
commit 9aeadee80a
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
1 changed files with 13 additions and 32 deletions

View File

@ -1351,27 +1351,9 @@ Parser.prototype.SelectorCompiler = class {
// Resulting regex literal: // Resulting regex literal:
// ^(?:[A-Za-z_][\w-]*(?:[.#][A-Za-z_][\w-]*)*(?:\[[A-Za-z_][\w-]*[*^$]?="[^"\]\\]+"\])*|[.#][A-Za-z_][\w-]*(?:[.#][A-Za-z_][\w-]*)*(?:\[[A-Za-z_][\w-]*[*^$]?="[^"\]\\]+"\])*|\[[A-Za-z_][\w-]*[*^$]?="[^"\]\\]+"\](?:\[[A-Za-z_][\w-]*[*^$]?="[^"\]\\]+"\])*)(?:(?:\s+|\s*[>+~]\s*)(?:[A-Za-z_][\w-]*(?:[.#][A-Za-z_][\w-]*)*(?:\[[A-Za-z_][\w-]*[*^$]?="[^"\]\\]+"\])*|[.#][A-Za-z_][\w-]*(?:[.#][A-Za-z_][\w-]*)*(?:\[[A-Za-z_][\w-]*[*^$]?="[^"\]\\]+"\])*|\[[A-Za-z_][\w-]*[*^$]?="[^"\]\\]+"\](?:\[[A-Za-z_][\w-]*[*^$]?="[^"\]\\]+"\])*))*$ // ^(?:[A-Za-z_][\w-]*(?:[.#][A-Za-z_][\w-]*)*(?:\[[A-Za-z_][\w-]*[*^$]?="[^"\]\\]+"\])*|[.#][A-Za-z_][\w-]*(?:[.#][A-Za-z_][\w-]*)*(?:\[[A-Za-z_][\w-]*[*^$]?="[^"\]\\]+"\])*|\[[A-Za-z_][\w-]*[*^$]?="[^"\]\\]+"\](?:\[[A-Za-z_][\w-]*[*^$]?="[^"\]\\]+"\])*)(?:(?:\s+|\s*[>+~]\s*)(?:[A-Za-z_][\w-]*(?:[.#][A-Za-z_][\w-]*)*(?:\[[A-Za-z_][\w-]*[*^$]?="[^"\]\\]+"\])*|[.#][A-Za-z_][\w-]*(?:[.#][A-Za-z_][\w-]*)*(?:\[[A-Za-z_][\w-]*[*^$]?="[^"\]\\]+"\])*|\[[A-Za-z_][\w-]*[*^$]?="[^"\]\\]+"\](?:\[[A-Za-z_][\w-]*[*^$]?="[^"\]\\]+"\])*))*$
// We use an actual stylesheet to validate uncommon CSS selectors // We use an actual stylesheet to validate uncommon CSS selectors and
// which can be used in a CSS declaration. // CSS properties which can be used in a CSS declaration.
this.sheetValidatorRule = null; this.cssValidatorElement = null;
(( ) => {
if ( typeof document !== 'object' ) { return; }
if ( document === null ) { return; }
try {
const styleElement = document.createElement('style');
document.body.append(styleElement);
const sheet = styleElement.sheet;
styleElement.remove();
sheet.insertRule('_z{color:red}');
const rule = sheet.cssRules[0];
this.sheetValidatorRule = rule;
} catch(ex) {
}
})();
// We use another stylsheet to validate CSS properties which can be
// used in a CSS declaration.
this.styleValidatorElement = null;
(( ) => { (( ) => {
if ( typeof document !== 'object' ) { return; } if ( typeof document !== 'object' ) { return; }
if ( document === null ) { return; } if ( document === null ) { return; }
@ -1379,7 +1361,7 @@ Parser.prototype.SelectorCompiler = class {
const styleElement = document.createElement('style'); const styleElement = document.createElement('style');
styleElement.appendChild(document.createTextNode(' ')); styleElement.appendChild(document.createTextNode(' '));
document.body.append(styleElement); document.body.append(styleElement);
this.styleValidatorElement = styleElement; this.cssValidatorElement = styleElement;
} catch(ex) { } catch(ex) {
} }
})(); })();
@ -1402,7 +1384,6 @@ Parser.prototype.SelectorCompiler = class {
this.reDropScope = /^\s*:scope\s*(?=[+>~])/; this.reDropScope = /^\s*:scope\s*(?=[+>~])/;
this.reIsDanglingSelector = /[+>~\s]\s*$/; this.reIsDanglingSelector = /[+>~\s]\s*$/;
this.reIsCombinator = /^\s*[+>~]/; this.reIsCombinator = /^\s*[+>~]/;
this.reUnicodeSpecials = /[\uFFF0-\uFFFF]/;
this.regexToRawValue = new Map(); this.regexToRawValue = new Map();
// https://github.com/gorhill/uBlock/issues/2793 // https://github.com/gorhill/uBlock/issues/2793
this.normalizedOperators = new Map([ this.normalizedOperators = new Map([
@ -1508,14 +1489,14 @@ Parser.prototype.SelectorCompiler = class {
// Forbid multiple and unexpected CSS style declarations. // Forbid multiple and unexpected CSS style declarations.
sheetSelectable(s) { sheetSelectable(s) {
if ( this.reCommonSelector.test(s) ) { return true; } if ( this.reCommonSelector.test(s) ) { return true; }
const rule = this.sheetValidatorRule; if ( this.cssValidatorElement === null ) { return true; }
if ( rule === null ) { return true; }
let valid = false; let valid = false;
try { try {
rule.selectorText = '_z'; this.cssValidatorElement.childNodes[0].nodeValue = `_z + ${s}{color:red;} _z{color:red;}`;
rule.selectorText = `_z + ${s}`; const rules = this.cssValidatorElement.sheet.cssRules;
valid = rule.selectorText !== '_z' && valid = rules.length === 2 &&
this.reUnicodeSpecials.test(rule.selectorText) === false; rules[0].style.cssText !== '' &&
rules[1].style.cssText !== '';
} catch (ex) { } catch (ex) {
} }
return valid; return valid;
@ -1639,11 +1620,11 @@ Parser.prototype.SelectorCompiler = class {
// - opening comment `/*` // - opening comment `/*`
compileStyleProperties(s) { compileStyleProperties(s) {
if ( /image-set\(|url\(|\/\s*\/|\\|\/\*/i.test(s) ) { return; } if ( /image-set\(|url\(|\/\s*\/|\\|\/\*/i.test(s) ) { return; }
if ( this.styleValidatorElement === null ) { return s; } if ( this.cssValidatorElement === null ) { return s; }
let valid = false; let valid = false;
try { try {
this.styleValidatorElement.childNodes[0].nodeValue = `_z{${s}} _z{color:red;}`; this.cssValidatorElement.childNodes[0].nodeValue = `_z{${s}} _z{color:red;}`;
const rules = this.styleValidatorElement.sheet.cssRules; const rules = this.cssValidatorElement.sheet.cssRules;
valid = rules.length >= 2 && valid = rules.length >= 2 &&
rules[0].style.cssText !== '' && rules[0].style.cssText !== '' &&
rules[1].style.cssText !== ''; rules[1].style.cssText !== '';