mirror of https://github.com/gorhill/uBlock.git
Better detect invalid cosmetic filters
Related issue: - https://github.com/uBlockOrigin/uBlock-issues/issues/2170
This commit is contained in:
parent
019f3f1739
commit
a8ca5127c9
|
@ -19,7 +19,7 @@
|
|||
Home: https://github.com/gorhill/uBlock
|
||||
*/
|
||||
|
||||
/* globals CSSStyleSheet, document */
|
||||
/* globals document */
|
||||
|
||||
'use strict';
|
||||
|
||||
|
@ -1333,20 +1333,17 @@ Parser.prototype.SelectorCompiler = class {
|
|||
[ 'matches-css-before', ':matches-css-before' ],
|
||||
]);
|
||||
this.reSimpleSelector = /^[#.]?[A-Za-z_][\w-]*$/;
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet#browser_compatibility
|
||||
// Firefox does not support constructor for CSSStyleSheet
|
||||
this.stylesheet = (( ) => {
|
||||
this.styleElement = (( ) => {
|
||||
if ( typeof document !== 'object' ) { return null; }
|
||||
if ( document instanceof Object === false ) { return null; }
|
||||
if ( document === null ) { return null; }
|
||||
try {
|
||||
return new CSSStyleSheet();
|
||||
const styleElement = document.createElement('style');
|
||||
styleElement.disabled = true;
|
||||
document.body.append(styleElement);
|
||||
return styleElement;
|
||||
} catch(ex) {
|
||||
}
|
||||
const style = document.createElement('style');
|
||||
document.body.append(style);
|
||||
const stylesheet = style.sheet;
|
||||
style.remove();
|
||||
return stylesheet;
|
||||
return null;
|
||||
})();
|
||||
this.div = (( ) => {
|
||||
if ( typeof document !== 'object' ) { return null; }
|
||||
|
@ -1468,18 +1465,17 @@ Parser.prototype.SelectorCompiler = class {
|
|||
// Forbid multiple and unexpected CSS style declarations.
|
||||
sheetSelectable(s) {
|
||||
if ( this.reSimpleSelector.test(s) ) { return true; }
|
||||
if ( this.stylesheet === null ) { return true; }
|
||||
if ( this.styleElement === null ) { return true; }
|
||||
try {
|
||||
this.stylesheet.insertRule(`${s}{color:red}`);
|
||||
if ( this.stylesheet.cssRules.length !== 1 ) { return false; }
|
||||
const style = this.stylesheet.cssRules[0].style;
|
||||
this.styleElement.textContent = `${s}{color:red}`;
|
||||
const rules = this.styleElement.sheet.cssRules;
|
||||
if ( rules.length !== 1 ) { return false; }
|
||||
const style = rules[0].style;
|
||||
if ( style.length !== 1 ) { return false; }
|
||||
if ( style.getPropertyValue('color') !== 'red' ) { return false; }
|
||||
this.stylesheet.deleteRule(0);
|
||||
if ( style.getPropertyValue('color') === 'red' ) { return true; }
|
||||
} catch (ex) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// https://github.com/uBlockOrigin/uBlock-issues/issues/1806
|
||||
|
@ -1600,17 +1596,15 @@ Parser.prototype.SelectorCompiler = class {
|
|||
// - opening comment `/*`
|
||||
compileStyleProperties(s) {
|
||||
if ( /image-set\(|url\(|\/\s*\/|\\|\/\*/i.test(s) ) { return; }
|
||||
if ( this.stylesheet === null ) { return s; }
|
||||
if ( this.styleElement === null ) { return s; }
|
||||
let valid = false;
|
||||
try {
|
||||
this.stylesheet.insertRule(`a{${s}}`);
|
||||
const rules = this.stylesheet.cssRules;
|
||||
valid = rules.length !== 0 && rules[0].style.cssText !== '';
|
||||
this.styleElement.textContent = `a{${s}} b{color:red;}`;
|
||||
const rules = this.styleElement.sheet.cssRules;
|
||||
valid = rules.length >= 2 &&
|
||||
rules[0].style.cssText !== '' &&
|
||||
rules[1].style.cssText !== '';
|
||||
} catch(ex) {
|
||||
return;
|
||||
}
|
||||
if ( this.stylesheet.cssRules.length !== 0 ) {
|
||||
this.stylesheet.deleteRule(0);
|
||||
}
|
||||
if ( valid ) { return s; }
|
||||
}
|
||||
|
@ -1781,8 +1775,12 @@ Parser.prototype.SelectorCompiler = class {
|
|||
if ( i === n ) { break; }
|
||||
}
|
||||
|
||||
// when there is an explicit action, nothing should be left to parse.
|
||||
if ( action !== undefined && opPrefixBeg < n ) { return; }
|
||||
|
||||
// No task found: then we have a CSS selector.
|
||||
// At least one task found: nothing should be left to parse.
|
||||
// At least one task found: either nothing or a valid plain CSS selector
|
||||
// should be left to parse
|
||||
if ( tasks.length === 0 ) {
|
||||
if ( action === undefined ) {
|
||||
prefix = raw;
|
||||
|
@ -1796,7 +1794,6 @@ Parser.prototype.SelectorCompiler = class {
|
|||
}
|
||||
|
||||
} else if ( opPrefixBeg < n ) {
|
||||
if ( action !== undefined ) { return; }
|
||||
const spath = this.compileSpathExpression(raw.slice(opPrefixBeg));
|
||||
if ( spath === undefined ) { return; }
|
||||
tasks.push([ ':spath', spath ]);
|
||||
|
|
Loading…
Reference in New Issue