Skip to content

Commit

Permalink
update extended-css to v2.0.10 AG-16443
Browse files Browse the repository at this point in the history
Squashed commit of the following:

commit ac0729e
Author: Slava Leleka <[email protected]>
Date:   Wed Nov 16 18:33:29 2022 +0200

    update tsurlfilter to v1.0.50, extended-css to v2.0.10

commit c07bf36
Author: Slava Leleka <[email protected]>
Date:   Wed Nov 16 18:31:56 2022 +0200

    add one more test

commit 0133318
Author: Slava Leleka <[email protected]>
Date:   Tue Nov 15 20:47:52 2022 +0200

    add more validation tests

commit 3ac03d4
Author: Slava Leleka <[email protected]>
Date:   Tue Nov 15 20:46:15 2022 +0200

    update extended-css to v2.0.9, tsurlfilter to v1.0.49

commit b1b1f30
Author: Slava Leleka <[email protected]>
Date:   Fri Nov 11 22:02:17 2022 +0200

    add todo about SelectorValidationResult

commit a6c3e15
Author: Slava Leleka <[email protected]>
Date:   Fri Nov 11 14:00:08 2022 +0200

    add more css validation tests

commit ae08dfd
Author: Slava Leleka <[email protected]>
Date:   Fri Nov 11 13:58:35 2022 +0200

    update extended-css to v2.0.8, tsurlfilter to v1.0.48

commit 80571fc
Author: Slava Leleka <[email protected]>
Date:   Thu Nov 10 18:59:42 2022 +0200

    use ExtendedCss.validate() for validateCssSelector(), improve error logging

commit c3470c5
Author: Slava Leleka <[email protected]>
Date:   Thu Nov 10 18:31:15 2022 +0200

    update tsurlfilter to v1.0.47

commit 19d3ed3
Author: Slava Leleka <[email protected]>
Date:   Thu Nov 10 18:19:39 2022 +0200

    update extended-css to v2.0.7
  • Loading branch information
slavaleleka committed Nov 17, 2022
1 parent f339bb4 commit 0a3244b
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 36 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
"prepare": "husky install"
},
"dependencies": {
"@adguard/extended-css": "^2.0.5",
"@adguard/extended-css": "^2.0.10",
"@adguard/scriptlets": "^1.6.55",
"@adguard/tsurlfilter": "^1.0.46",
"@adguard/tsurlfilter": "^1.0.50",
"ajv": "^8.11.0",
"child_process": ">=1.0.2",
"filters-downloader": "git+https://github.com/AdguardTeam/FiltersDownloader.git#v1.1.12",
Expand Down
55 changes: 34 additions & 21 deletions src/main/utils/extended-css-validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,48 @@ module.exports = (function () {

const { ExtendedCss } = require('@adguard/extended-css');

// TODO: in future SelectorValidationResult from ExtendedCss may be imported and used instead of it
/**
* Validates css selector
* @typedef {Object} SelectorValidationResult
* @property {boolean} ok selector validation status
* @property {string|null} error reason of invalid selector for invalid selector
* and `null` for valid one
*/

/**
* Validates css selector, uses ExtendedCss.validate() for it.
*
* @param selectorText
* @returns {boolean}
*
* @returns {SelectorValidationResult}
*/
const validateCssSelector = function (selectorText) {
try {
// jsdom is crashing when selector is a script
if (selectorText.indexOf('##script:contains') !== -1
|| selectorText.indexOf('##script:inject') !== -1) {
return false;
}

// skip :before and :after selectors
if (selectorText.match(/[^:\s]([:]{1,2}before(\s|,|$))|[^:\s]([:]{1,2}after(\s|,|$))/ig)) {
return true;
}
// jsdom is crashing when selector is a script
if (selectorText.indexOf('##script:contains') !== -1
|| selectorText.indexOf('##script:inject') !== -1) {
return {
ok: false,
error: 'Selector as a script is not supported.',
};
}

// skip selectors with case-insensitive attribute, for example: div[class^="Abc_123" i]
if (selectorText.match(/\[[a-z\d-_]+[\^$*]?=['"]?[^'"]+['"]?\si]/g)) {
return true;
}
// skip :before and :after selectors
if (selectorText.match(/[^:\s]([:]{1,2}before(\s|,|$))|[^:\s]([:]{1,2}after(\s|,|$))/ig)) {
return {
ok: true,
error: null,
};
}

ExtendedCss.query(selectorText, true);
return true;
} catch (ex) {
return false;
// skip selectors with case-insensitive attribute, for example: div[class^="Abc_123" i]
if (selectorText.match(/\[[a-z\d-_]+[\^$*]?=['"]?[^'"]+['"]?\si]/g)) {
return {
ok: true,
error: null,
};
}

return ExtendedCss.validate(selectorText);
};

return {
Expand Down
7 changes: 4 additions & 3 deletions src/main/validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,12 @@ const validate = function (list, excluded, invalid = [], filterName) { // eslint

// It is impossible to bundle jsdom into tsurlfilter, so we check if rules are valid in the compiler
if (rule instanceof CosmeticRule && rule.getType() === CosmeticRuleType.ElementHiding) {
if (!extendedCssValidator.validateCssSelector(rule.getContent())) {
const validationResult = extendedCssValidator.validateCssSelector(rule.getContent());
if (!validationResult.ok) {
logger.error(`Invalid rule selector in ${filterName}: ${ruleText}`);
// log source rule text to the excluded log
excludeRule(excluded, '! Invalid selector:', ruleText);
invalid.push(`Invalid selector: ${ruleText}`);
excludeRule(excluded, `! ${validationResult.error} in rule:`, ruleText);
invalid.push(`${validationResult.error} in rule: ${ruleText}`);
return false;
}
}
Expand Down
65 changes: 64 additions & 1 deletion src/test/validator.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,55 @@ jest.mock('../main/utils/log');

describe('validator', () => {
it('Test css validation', () => {
let rules = ['example.com##.div'];
let rules;

// valid selectors
rules = ['example.com##.div'];
expect(validator.validate(rules).length).toBeGreaterThan(0);

rules = ['example.com###div-id'];
expect(validator.validate(rules).length).toBeGreaterThan(0);

rules = ['example.com##[style*="border-bottom: none;"]'];
expect(validator.validate(rules).length).toBeGreaterThan(0);

rules = ['example.com##[style^="background-color: rgb(24, 28, 31);"]'];
expect(validator.validate(rules).length).toBeGreaterThan(0);

rules = ['example.com##[data-bind="visible: showCookieWarning"]'];
expect(validator.validate(rules).length).toBeGreaterThan(0);

rules = ['example.com##.ProgressBar-container, .bx-align, .pico-content, .pico-overlay, [style*="z-index: 100000000;"]'];
expect(validator.validate(rules).length).toBeGreaterThan(0);

rules = ['example.com##[onclick^="window.open (\'https://example.com/share?url="]'];
expect(validator.validate(rules).length).toBeGreaterThan(0);

rules = ['example.com##[id^="jsgg"],[style^="height: 90px;"],.ad_text,#ysdiv'];
expect(validator.validate(rules).length).toBeGreaterThan(0);

rules = ['example.com##[style="min-height: 260px;"]:has([id^="adocean"])'];
expect(validator.validate(rules).length).toBeGreaterThan(0);

rules = ['example.com##[style*="border-radius: 3px; margin-bottom: 20px; width: 160px;"]:-abp-has([target="_blank"])'];
expect(validator.validate(rules).length).toBeGreaterThan(0);

// eslint-disable-next-line no-tabs
rules = ['example.com##div[style^=" margin-right: auto; margin-left: auto; text-align: left; padding-top: 0px; padding-bottom: 10px;"]'];
expect(validator.validate(rules).length).toBeGreaterThan(0);

// invalid selectors:
rules = ['example.com##a[href^=/], .container:has(nav) > a[href]:lt($var)'];
expect(validator.validate(rules)).toHaveLength(0);

rules = ['example.com##%'];
expect(validator.validate(rules)).toHaveLength(0);

rules = ['example.com##.4wNET'];
expect(validator.validate(rules)).toHaveLength(0);

rules = ['pasazer.com##.\].slidein.\[.box'];
expect(validator.validate(rules)).toHaveLength(0);
});

it('Test incorrect rules', () => {
Expand All @@ -50,6 +88,26 @@ describe('validator', () => {
rules = [ruleText];
expect(validator.validate(rules).length).toBeGreaterThan(0);

selector = 'body > *:not(div):not(script):matches-css(width:336px)';
ruleText = `example.com##${selector}`;
rules = [ruleText];
expect(validator.validate(rules).length).toBeGreaterThan(0);

selector = 'div[class*=" "]:matches-css(background-image: /^url\(data:image/png;base64,iVBOR/)';
ruleText = `example.com##${selector}`;
rules = [ruleText];
expect(validator.validate(rules)).toHaveLength(1);

selector = 'div[class*=" "]:matches-css(background-image: /^url\\(https:\\/\\/sport\\.wp\\.pl\\//)';
ruleText = `example.com##${selector}`;
rules = [ruleText];
expect(validator.validate(rules)).toHaveLength(1);

selector = '#welcomeMainBanner_welcomeMain div[id*="_containerWrap_"]:has(img[src$="Banner/ad.jpg"]):remove()';
ruleText = `example.com##${selector}`;
rules = [ruleText];
expect(validator.validate(rules)).toHaveLength(1);

selector = '.todaystripe:matches-css-before(display: block)';
ruleText = `w3schools.com##${selector}`;
rules = [ruleText];
Expand Down Expand Up @@ -87,6 +145,11 @@ describe('validator', () => {
ruleText = `w3schools.com##${selector}`;
rules = [ruleText];
expect(validator.validate(rules)).toHaveLength(0);

selector = '.modals.dimmer > .gdpr.visible:upward(1):watch-attr([class])';
ruleText = `w3schools.com##${selector}`;
rules = [ruleText];
expect(validator.validate(rules)).toHaveLength(0);
});

it('Validates with extended css abp pseudo classes', () => {
Expand Down
18 changes: 9 additions & 9 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
# yarn lockfile v1


"@adguard/extended-css@^2.0.5":
version "2.0.5"
resolved "https://registry.yarnpkg.com/@adguard/extended-css/-/extended-css-2.0.5.tgz#4160aa6e199b81bda7f77a811fc35c7ae7d87970"
integrity sha512-8UGgmsEidg1ab12s1slNK78rNuC/t/qKLjYhR9MidDSgpkGG8oGWQGRumKJgaw2oG22N8Stkl/Kd8lEuy8ugiw==
"@adguard/extended-css@^2.0.10":
version "2.0.10"
resolved "https://registry.yarnpkg.com/@adguard/extended-css/-/extended-css-2.0.10.tgz#5858691317454fd5851a2ca0d5d04058381db030"
integrity sha512-RD+Uo7wjNPzuazmUPt+GFYnmJgKH+k93ZlSUeHJmijx9R2ro1DB9c4hJJ/17wmhU0CkvNwLehRK7mu5Fcfynpg==

"@adguard/scriptlets@^1.6.55":
version "1.6.55"
Expand All @@ -15,12 +15,12 @@
"@babel/runtime" "^7.7.2"
js-yaml "^3.13.1"

"@adguard/tsurlfilter@^1.0.46":
version "1.0.46"
resolved "https://registry.yarnpkg.com/@adguard/tsurlfilter/-/tsurlfilter-1.0.46.tgz#2108b52192c56aabe0b1602c8cde5fb740942b45"
integrity sha512-7WT7jRAoeSNJuFUcfYmR7elipyY+i+tiGUDlwiQZFO7OXsqlSMM1iwcrQhC6wIAiDK6her2nOZP8Nc731Fq5lA==
"@adguard/tsurlfilter@^1.0.50":
version "1.0.50"
resolved "https://registry.yarnpkg.com/@adguard/tsurlfilter/-/tsurlfilter-1.0.50.tgz#af4140ef6e8031afd253377fafd88736e3876c71"
integrity sha512-tr1vExHoNnNiIBpNXvxXvlrOka+/GAblR2s+j11OMFYypyDZe5YB2nFhErb33Y0FztFe36bTCxUsSOh+oJIflg==
dependencies:
"@adguard/extended-css" "^2.0.5"
"@adguard/extended-css" "^2.0.10"
"@adguard/scriptlets" "^1.6.55"
ip6addr "^0.2.3"
is-cidr "^4.0.2"
Expand Down

0 comments on commit 0a3244b

Please sign in to comment.