Skip to content

Commit

Permalink
AG-28255 add trusted-suppress-native-method scriptlet
Browse files Browse the repository at this point in the history
Merge in ADGUARD-FILTERS/scriptlets from feature/AG-28255 to master

Squashed commit of the following:

commit c65fbdd
Merge: 3e7582a 3f06781
Author: Stanislav Atroschenko <s.atroschenko@adguard.com>
Date:   Mon Mar 25 16:06:36 2024 +0300

    Merge branch 'master' into feature/AG-28255

commit 3e7582a
Author: Stanislav Atroschenko <s.atroschenko@adguard.com>
Date:   Fri Mar 22 21:16:49 2024 +0300

    fix getAbortFunc

commit 12b7134
Author: Stanislav Atroschenko <s.atroschenko@adguard.com>
Date:   Fri Mar 22 20:47:52 2024 +0300

    improve matchMethodCall

commit c60eb64
Author: Stanislav Atroschenko <s.atroschenko@adguard.com>
Date:   Fri Mar 22 15:58:52 2024 +0300

    use getErrorMessage

commit 83bc900
Author: Stanislav Atroschenko <s.atroschenko@adguard.com>
Date:   Thu Mar 21 21:19:13 2024 +0300

    lint doc

commit c77adad
Merge: cf742e3 55ef662
Author: Stanislav Atroschenko <s.atroschenko@adguard.com>
Date:   Thu Mar 21 15:37:53 2024 +0300

    Merge branch 'master' into feature/AG-28255

commit cf742e3
Author: Stanislav Atroschenko <s.atroschenko@adguard.com>
Date:   Thu Mar 21 15:35:30 2024 +0300

    update changelog

commit f587964
Author: Stanislav Atroschenko <s.atroschenko@adguard.com>
Date:   Thu Mar 21 15:30:11 2024 +0300

    rename some more

commit c73b7a5
Author: Stanislav Atroschenko <s.atroschenko@adguard.com>
Date:   Wed Mar 20 22:10:20 2024 +0300

    rename to trusted-

commit 324215d
Author: Stanislav Atroschenko <s.atroschenko@adguard.com>
Date:   Wed Mar 20 18:27:16 2024 +0300

    improve chain end check

commit ec8ba34
Author: Stanislav Atroschenko <s.atroschenko@adguard.com>
Date:   Wed Mar 20 18:20:44 2024 +0300

    improve doc

commit 84332d9
Author: Stanislav Atroschenko <s.atroschenko@adguard.com>
Date:   Wed Mar 20 18:11:02 2024 +0300

    add value matchers tests, fix bugs

commit 89e8111
Merge: 6c707f0 ebe3235
Author: Stanislav Atroschenko <s.atroschenko@adguard.com>
Date:   Wed Mar 20 16:22:12 2024 +0300

    Merge branch 'feature/AG-28255' of ssh://bit.int.agrd.dev:7999/adguard-filters/scriptlets into feature/AG-28255

commit 6c707f0
Author: Stanislav Atroschenko <s.atroschenko@adguard.com>
Date:   Tue Mar 19 22:17:46 2024 +0300

    improve matchValue

commit ebe3235
Author: Slava Leleka <v.leleka@adguard.com>
Date:   Tue Mar 19 22:08:09 2024 +0300

    src/scriptlets/suppress-native-method.ts edited online with Bitbucket

commit 0d7f443
Author: Slava Leleka <v.leleka@adguard.com>
Date:   Tue Mar 19 16:30:28 2024 +0300

    src/helpers/value-matchers.ts edited online with Bitbucket

commit 6eb8d5a
Author: Stanislav Atroschenko <s.atroschenko@adguard.com>
Date:   Tue Mar 19 16:11:01 2024 +0300

    fix misc

commit 46870fb
Author: Stanislav Atroschenko <s.atroschenko@adguard.com>
Date:   Mon Mar 18 19:03:33 2024 +0300

    assert getPropertyInChain type instead of ts-ignoring it

commit 99fd25c
Author: Stanislav Atroschenko <s.atroschenko@adguard.com>
Date:   Mon Mar 18 18:34:09 2024 +0300

    fix typings

commit 06313dd
Author: Stanislav Atroschenko <s.atroschenko@adguard.com>
Date:   Mon Mar 18 17:30:16 2024 +0300

    add usage examples

... and 21 more commits
  • Loading branch information
stanislav-atr committed Mar 25, 2024
1 parent 3f06781 commit 88c6d95
Show file tree
Hide file tree
Showing 15 changed files with 1,051 additions and 9 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ The format is based on [Keep a Changelog], and this project adheres to [Semantic

### Added

- `trusted-suppress-native-method` scriptlet [#383]
- `json-prune-fetch-response` scriptlet [#361]
- `json-prune-xhr-response` scriptlet [#360]
- `href-sanitizer` scriptlet [#327]
- `no-protected-audience` scriptlet [#395]
- Domain value for setting cookie scriptlets [#389]
- Multiple redirects can be used as scriptlets [#300]:
- Multiple redirects can now be used as scriptlets [#300]:
- `amazon-apstag`
- `didomi-loader`
- `fingerprintjs2`
Expand Down Expand Up @@ -53,6 +54,7 @@ The format is based on [Keep a Changelog], and this project adheres to [Semantic
[#395]: https://github.com/AdguardTeam/Scriptlets/issues/395
[#389]: https://github.com/AdguardTeam/Scriptlets/issues/389
[#388]: https://github.com/AdguardTeam/Scriptlets/issues/388
[#383]: https://github.com/AdguardTeam/Scriptlets/issues/383
[#377]: https://github.com/AdguardTeam/Scriptlets/issues/377
[#361]: https://github.com/AdguardTeam/Scriptlets/issues/361
[#360]: https://github.com/AdguardTeam/Scriptlets/issues/360
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
"@rollup/plugin-json": "^6.0.1",
"@rollup/plugin-node-resolve": "^15.0.1",
"@rollup/plugin-replace": "^5.0.2",
"@types/jest": "^29.5.12",
"@typescript-eslint/eslint-plugin": "^5.52.0",
"@typescript-eslint/parser": "^5.52.0",
"axios": "^1.2.0",
Expand Down
22 changes: 21 additions & 1 deletion src/helpers/create-on-error-handler.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { randomId } from './random-id';

/**
* Generates function which silents global errors on page generated by scriptlet
* If error doesn't belong to our error we transfer it to the native onError handler
*
* @param rid - unique identifier of scriptlet
* @returns window.onerror handler
*/
export function createOnErrorHandler(rid: string): OnErrorEventHandler {
export function createOnErrorHandler(rid: string): OnErrorEventHandlerNonNull {
// eslint-disable-next-line consistent-return
const nativeOnError = window.onerror;
return function onError(error, ...args) {
Expand All @@ -18,3 +20,21 @@ export function createOnErrorHandler(rid: string): OnErrorEventHandler {
return false;
};
}

/**
* Silently aborts currently running script
* TODO use this for other abort scriptlets
*
* @returns abort function
*/
export function getAbortFunc() {
const rid = randomId();
let isErrorHandlerSet = false;
return function abort() {
if (!isErrorHandlerSet) {
window.onerror = createOnErrorHandler(rid);
isErrorHandlerSet = true;
}
throw new ReferenceError(rid);
};
}
1 change: 1 addition & 0 deletions src/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@ export * from './random-id';
export * from './throttle';
export * from './shadow-dom-utils';
export * from './node-text-utils';
export * from './value-matchers';
10 changes: 10 additions & 0 deletions src/helpers/object-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,13 @@ export function setPropertyAccess(
Object.defineProperty(object, property, descriptor);
return true;
}

/**
* Checks whether the value is an arbitrary object
*
* @param value arbitrary value
* @returns true, if value is an arbitrary object
*/
export function isArbitraryObject(value: unknown): value is ArbitraryObject {
return value !== null && typeof value === 'object' && !Array.isArray(value) && !(value instanceof RegExp);
}
4 changes: 4 additions & 0 deletions src/helpers/string-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,10 @@ export function inferValue(value: string): unknown {
return NaN;
}

if (value.startsWith('/') && value.endsWith('/')) {
return toRegExp(value);
}

// Number class constructor works 2 times faster than JSON.parse
// and wont interpret mixed inputs like '123asd' as parseFloat would
const MAX_ALLOWED_NUM = 32767;
Expand Down
133 changes: 133 additions & 0 deletions src/helpers/value-matchers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import { isArbitraryObject } from './object-utils';
import { nativeIsNaN } from './number-utils';

/**
* Matches an arbitrary value by matcher value.
* Supported value types and corresponding matchers:
* - string – exact string, part of the string or regexp pattern. Empty string `""` to match an empty string.
* - number, boolean, null, undefined – exact value,
* - object – partial of the object with the values as mentioned above,
* i.e by another object, that includes property names and values to be matched,
* - array – partial of the array with the values to be included in the incoming array,
* without considering the order of values,
* - function – not supported.
*
* @param value arbitrary value
* @param matcher value matcher
* @returns true, if incoming value matches the matcher value
*/
export function isValueMatched(value: unknown, matcher: unknown): boolean {
if (typeof value === 'function') {
return false;
}

if (nativeIsNaN(value)) {
return nativeIsNaN(matcher);
}

if (
value === null
|| typeof value === 'undefined'
|| typeof value === 'number'
|| typeof value === 'boolean'
) {
return value === matcher;
}

if (typeof value === 'string') {
if (typeof matcher === 'string' || matcher instanceof RegExp) {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
return isStringMatched(value, matcher);
}
return false;
}

if (Array.isArray(value) && Array.isArray(matcher)) {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
return isArrayMatched(value, matcher);
}

if (isArbitraryObject(value) && isArbitraryObject(matcher)) {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
return isObjectMatched(value, matcher);
}

return false;
}

/**
* Matches string by substring or regexp pattern.
*
* @param str incoming string
* @param matcher string matcher
* @returns true, if incoming string includes the matcher or matches the regexp pattern
*/
export function isStringMatched(str: string, matcher: string | RegExp): boolean {
if (typeof matcher === 'string') {
if (matcher === '') {
return str === matcher;
}
return str.includes(matcher);
}

if (matcher instanceof RegExp) {
return matcher.test(str);
}

return false;
}

/**
* Matches incoming object by partial of the object, i.e by another object,
* that includes property names and values to be matched.
*
* @param obj incoming object
* @param matcher object matcher
* @returns true, if incoming object includes all properties and corresponding values from the matcher
*/
export function isObjectMatched(obj: ArbitraryObject, matcher: ArbitraryObject): boolean {
const matcherKeys = Object.keys(matcher);
for (let i = 0; i < matcherKeys.length; i += 1) {
const key = matcherKeys[i];

const value = obj[key];
if (!isValueMatched(value, matcher[key])) {
return false;
}

continue;
}

return true;
}

/**
* Matches array by partial of the array with the values to be included in the incoming array,
* without considering the order of values.
*
* @param array incoming array
* @param matcher array matcher
* @returns true, if incoming array includes all values from the matcher
*/
export function isArrayMatched(array: unknown[], matcher: unknown[]): boolean {
if (array.length === 0) {
return matcher.length === 0;
}

// Empty array matcher matches empty array, which is not the case after the previous check
if (matcher.length === 0) {
return false;
}

for (let i = 0; i < matcher.length; i += 1) {
const matcherValue = matcher[i];
const isMatching = array.some((arrItem) => isValueMatched(arrItem, matcherValue));
if (!isMatching) {
return false;
}

continue;
}

return true;
}
1 change: 1 addition & 0 deletions src/scriptlets/scriptlets-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export * from './trusted-create-element';
export * from './href-sanitizer';
export * from './json-prune-fetch-response';
export * from './no-protected-audience';
export * from './trusted-suppress-native-method';
export * from './json-prune-xhr-response';
// redirects as scriptlets
// https://github.com/AdguardTeam/Scriptlets/issues/300
Expand Down
Loading

0 comments on commit 88c6d95

Please sign in to comment.