Skip to content

Commit

Permalink
merge release/v1.8
Browse files Browse the repository at this point in the history
  • Loading branch information
stanislav-atr committed Dec 28, 2022
2 parents 048e32c + 89185d3 commit 9a4aa4d
Show file tree
Hide file tree
Showing 30 changed files with 539 additions and 67 deletions.
39 changes: 23 additions & 16 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

## Unreleased 1.8.x

### Added
- `throwFunc` and `noopCallbackFunc` prop values for `set-constant` scriptlet

### Changed

- add decimal delay matching for `prevent-setInterval` and `prevent-setTimeout` [#247](https://github.com/AdguardTeam/Scriptlets/issues/247)
- debug logging to include rule text when available

### Fixed

- `prevent-xhr` and `trusted-replace-xhr-response` closure bug on multiple requests [#261](https://github.com/AdguardTeam/Scriptlets/issues/261)
Expand Down Expand Up @@ -38,30 +46,29 @@
- spread of args bug at `getXhrData` call for `trusted-replace-xhr-response`
- request properties array not being served to `getRequestData` and `parseMatchProps` helpers


## v1.7.3

### Added

- [Trusted scriptlets](./README.md#trusted-scriptlets) with extended capabilities:
- trusted-click-element [#23](https://github.com/AdguardTeam/Scriptlets/issues/23)
- trusted-replace-xhr-response [#202](https://github.com/AdguardTeam/Scriptlets/issues/202)
- trusted-replace-fetch-response
- trusted-set-local-storage-item
- trusted-set-cookie
- `trusted-click-element` [#23](https://github.com/AdguardTeam/Scriptlets/issues/23)
- `trusted-replace-xhr-response` [#202](https://github.com/AdguardTeam/Scriptlets/issues/202)
- `trusted-replace-fetch-response`
- `trusted-set-local-storage-item`
- `trusted-set-cookie`

- Scriptlets:
- xml-prune [#249](https://github.com/AdguardTeam/Scriptlets/issues/249)
- `xml-prune` [#249](https://github.com/AdguardTeam/Scriptlets/issues/249)

### Improved
### Changed

- Scriptlets:
- prevent-element-src-loading [#228](https://github.com/AdguardTeam/Scriptlets/issues/228)
- prevent-fetch [#216](https://github.com/AdguardTeam/Scriptlets/issues/216)
- abort-on-stack-trace [#201](https://github.com/AdguardTeam/Scriptlets/issues/201)
- abort-current-inline-script [#251](https://github.com/AdguardTeam/Scriptlets/issues/251)
- set-cookie & set-cookie-reload
- `prevent-element-src-loading` [#228](https://github.com/AdguardTeam/Scriptlets/issues/228)
- `prevent-fetch` [#216](https://github.com/AdguardTeam/Scriptlets/issues/216)
- `abort-on-stack-trace` [#201](https://github.com/AdguardTeam/Scriptlets/issues/201)
- `abort-current-inline-script` [#251](https://github.com/AdguardTeam/Scriptlets/issues/251)
- `set-cookie` & `set-cookie-reload`
- Redirects:
- google-ima3 [#255](https://github.com/AdguardTeam/Scriptlets/issues/255)
- metrika-yandex-tag [#254](https://github.com/AdguardTeam/Scriptlets/issues/254)
- googlesyndication-adsbygoogle [#252](https://github.com/AdguardTeam/Scriptlets/issues/252)
- `google-ima3` [#255](https://github.com/AdguardTeam/Scriptlets/issues/255)
- `metrika-yandex-tag` [#254](https://github.com/AdguardTeam/Scriptlets/issues/254)
- `googlesyndication-adsbygoogle` [#252](https://github.com/AdguardTeam/Scriptlets/issues/252)
26 changes: 23 additions & 3 deletions src/helpers/log-message.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,28 @@
* @param {boolean} [forced=false] to log message unconditionally
*/
export const logMessage = (source, message, forced = false) => {
if (forced || source.verbose) {
// eslint-disable-next-line no-console
console.log(`${source.name}: ${message}`);
const {
name,
ruleText,
verbose,
} = source;

if (!forced && !verbose) {
return;
}

let messageStr = `${name}: ${message}`;

// Extract scriptlet part from rule text
if (ruleText) {
const RULE_MARKER = '#%#//scriptlet';
const markerIdx = ruleText.indexOf(RULE_MARKER);
if (markerIdx > -1) {
const ruleWithoutDomains = ruleText.slice(markerIdx, ruleText.length);
messageStr += `; cannot apply rule: ${ruleWithoutDomains}`;
}
}

// eslint-disable-next-line no-console
console.log(messageStr);
};
14 changes: 14 additions & 0 deletions src/helpers/noop-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
*/
export const noopFunc = () => { };

/**
* Function return noopFunc
* @returns {Function}
*/
export const noopCallbackFunc = () => noopFunc;

/**
* Function returns null
*
Expand Down Expand Up @@ -56,6 +62,14 @@ export const noopArray = () => [];
*/
export const noopObject = () => ({});

/**
* Function throws an error
* @throws
*/
export const throwFunc = () => {
throw new Error();
};

/**
* Function returns Promise.reject()
*
Expand Down
21 changes: 19 additions & 2 deletions src/helpers/prevent-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
isValidMatchNumber,
isValidMatchStr,
} from './string-utils';
import { nativeIsNaN } from './number-utils';

/**
* Checks whether the passed arg is proper callback
Expand All @@ -19,6 +20,18 @@ export const isValidCallback = (callback) => {
|| typeof callback === 'string';
};

/**
* Parses delay argument of setTimeout / setInterval methods into
* rounded down number for number/string values or passes on for other types.
* Needed for prevent-setTimeout and prevent-setInterval
* @param {any} delay
* @returns {any} number as parsed delay or any input type if `delay` is not parsable
*/
export const parseRawDelay = (delay) => {
const parsedDelay = Math.floor(parseInt(delay, 10));
return typeof parsedDelay === 'number' && !nativeIsNaN(parsedDelay) ? parsedDelay : delay;
};

/**
* Checks whether 'callback' and 'delay' are matching
* by given parameters 'matchCallback' and 'matchDelay'.
Expand Down Expand Up @@ -51,16 +64,20 @@ export const isPreventionNeeded = ({
const { isInvertedMatch, matchRegexp } = parseMatchArg(matchCallback);
const { isInvertedDelayMatch, delayMatch } = parseDelayArg(matchDelay);

// Parse delay for decimal, string and non-number values
// https://github.com/AdguardTeam/Scriptlets/issues/247
const parsedDelay = parseRawDelay(delay);

let shouldPrevent = false;
// https://github.com/AdguardTeam/Scriptlets/issues/105
const callbackStr = String(callback);
if (delayMatch === null) {
shouldPrevent = matchRegexp.test(callbackStr) !== isInvertedMatch;
} else if (!matchCallback) {
shouldPrevent = (delay === delayMatch) !== isInvertedDelayMatch;
shouldPrevent = (parsedDelay === delayMatch) !== isInvertedDelayMatch;
} else {
shouldPrevent = matchRegexp.test(callbackStr) !== isInvertedMatch
&& (delay === delayMatch) !== isInvertedDelayMatch;
&& (parsedDelay === delayMatch) !== isInvertedDelayMatch;
}
return shouldPrevent;
};
2 changes: 1 addition & 1 deletion src/scriptlets/adjust-setInterval.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export function adjustSetInterval(source, matchCallback, matchDelay, boost) {
// https://github.com/AdguardTeam/Scriptlets/issues/221
if (!isValidCallback(callback)) {
// eslint-disable-next-line max-len
const message = `Scriptlet can't be applied because of invalid callback: '${String(callback)}'.`;
const message = `Scriptlet can't be applied because of invalid callback: '${String(callback)}'`;
logMessage(source, message);
} else if (matchRegexp.test(callback.toString()) && isDelayMatched(matchDelay, delay)) {
delay *= getBoostMultiplier(boost);
Expand Down
2 changes: 1 addition & 1 deletion src/scriptlets/adjust-setTimeout.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export function adjustSetTimeout(source, matchCallback, matchDelay, boost) {
// https://github.com/AdguardTeam/Scriptlets/issues/221
if (!isValidCallback(callback)) {
// eslint-disable-next-line max-len
const message = `Scriptlet can't be applied because of invalid callback: '${String(callback)}'.`;
const message = `Scriptlet can't be applied because of invalid callback: '${String(callback)}'`;
logMessage(source, message);
} else if (matchRegexp.test(callback.toString()) && isDelayMatched(matchDelay, delay)) {
delay *= getBoostMultiplier(boost);
Expand Down
18 changes: 18 additions & 0 deletions src/scriptlets/prevent-setInterval.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
escapeRegExp,
nativeIsFinite,
isValidMatchNumber,
parseRawDelay,
} from '../helpers/index';

/* eslint-disable max-len */
Expand Down Expand Up @@ -43,6 +44,7 @@ import {
* - `matchDelay` - optional, must be an integer.
* If starts with `!`, scriptlet will not match the delay but all other will be defused.
* If do not start with `!`, the delay passed to the `setInterval` call will be matched.
* Decimal delay values will be rounded down, e.g `10.95` will be matched by `matchDelay` with value `10`.
*
* > If `prevent-setInterval` log looks like `setInterval(undefined, 1000)`,
* it means that no callback was passed to setInterval() and that's not scriptlet issue
Expand Down Expand Up @@ -117,6 +119,21 @@ import {
* window.value = "test -- executed";
* }, 500);
* ```
*
* 5. Prevents `setInterval` calls if the callback contains `value` and delay is a decimal.
* ```
* example.org#%#//scriptlet('prevent-setInterval', 'value', '300')
* ```
*
* For instance, the following calls will be prevented:
* ```javascript
* setInterval(function () {
* window.test = "value";
* }, 300);
* setInterval(function () {
* window.test = "value";
* }, 300 + Math.random());
* ```
*/
/* eslint-enable max-len */
export function preventSetInterval(source, matchCallback, matchDelay) {
Expand Down Expand Up @@ -217,4 +234,5 @@ preventSetInterval.injections = [
escapeRegExp,
nativeIsFinite,
isValidMatchNumber,
parseRawDelay,
];
18 changes: 18 additions & 0 deletions src/scriptlets/prevent-setTimeout.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
isValidStrPattern,
nativeIsFinite,
isValidMatchNumber,
parseRawDelay,
} from '../helpers/index';

/* eslint-disable max-len */
Expand Down Expand Up @@ -43,6 +44,7 @@ import {
* - `matchDelay` - optional, must be an integer.
* If starts with `!`, scriptlet will not match the delay but all other will be defused.
* If do not start with `!`, the delay passed to the `setTimeout` call will be matched.
* Decimal delay values will be rounded down, e.g `10.95` will be matched by `matchDelay` with value `10`.
*
* > If `prevent-setTimeout` log looks like `setTimeout(undefined, 1000)`,
* it means that no callback was passed to setTimeout() and that's not scriptlet issue
Expand Down Expand Up @@ -117,6 +119,21 @@ import {
* window.value = "test -- executed";
* }, 500);
* ```
*
* 5. Prevents `setTimeout` calls if the callback contains `value` and delay is a decimal.
* ```
* example.org#%#//scriptlet('prevent-setTimeout', 'value', '300')
* ```
*
* For instance, the following calls will be prevented:
* ```javascript
* setTimeout(function () {
* window.test = "value";
* }, 300);
* setTimeout(function () {
* window.test = "value";
* }, 300 + Math.random());
* ```
*/
/* eslint-enable max-len */
export function preventSetTimeout(source, matchCallback, matchDelay) {
Expand Down Expand Up @@ -220,4 +237,5 @@ preventSetTimeout.injections = [
isValidStrPattern,
nativeIsFinite,
isValidMatchNumber,
parseRawDelay,
];
10 changes: 10 additions & 0 deletions src/scriptlets/set-constant.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ import {
logMessage,
noopArray,
noopObject,
noopCallbackFunc,
noopFunc,
trueFunc,
falseFunc,
throwFunc,
noopPromiseReject,
noopPromiseResolve,
getPropertyInChain,
Expand Down Expand Up @@ -52,8 +54,10 @@ import {
* - `emptyObj` - empty object
* - `emptyArr` - empty array
* - `noopFunc` - function with empty body
* - `noopCallbackFunc` - function returning noopFunc
* - `trueFunc` - function returning true
* - `falseFunc` - function returning false
* - `throwFunc` - function throwing an error
* - `noopPromiseResolve` - function returning Promise object that is resolved with an empty response
* - `noopPromiseReject` - function returning Promise.reject()
* - `''` - empty string
Expand Down Expand Up @@ -111,10 +115,14 @@ export function setConstant(source, property, value, stack) {
constantValue = emptyObj;
} else if (value === 'noopFunc') {
constantValue = noopFunc;
} else if (value === 'noopCallbackFunc') {
constantValue = noopCallbackFunc;
} else if (value === 'trueFunc') {
constantValue = trueFunc;
} else if (value === 'falseFunc') {
constantValue = falseFunc;
} else if (value === 'throwFunc') {
constantValue = throwFunc;
} else if (value === 'noopPromiseResolve') {
constantValue = noopPromiseResolve;
} else if (value === 'noopPromiseReject') {
Expand Down Expand Up @@ -282,8 +290,10 @@ setConstant.injections = [
noopArray,
noopObject,
noopFunc,
noopCallbackFunc,
trueFunc,
falseFunc,
throwFunc,
noopPromiseReject,
noopPromiseResolve,
getPropertyInChain,
Expand Down
2 changes: 1 addition & 1 deletion src/scriptlets/trusted-replace-fetch-response.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export function trustedReplaceFetchResponse(source, pattern = '', replacement =

// Only allow pattern as empty string for logging purposes
if (pattern === '' && replacement !== '') {
logMessage(source, 'Pattern argument should not be empty string.');
logMessage(source, 'Pattern argument should not be empty string');
return;
}
const shouldLog = pattern === '' && replacement === '';
Expand Down
4 changes: 2 additions & 2 deletions src/scriptlets/trusted-set-cookie-reload.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,11 @@ import {

export function trustedSetCookieReload(source, name, value, offsetExpiresSec = '', path = '/') {
if (typeof name === 'undefined') {
logMessage(source, 'Cookie name should be specified.');
logMessage(source, 'Cookie name should be specified');
return;
}
if (typeof value === 'undefined') {
logMessage(source, 'Cookie value should be specified.');
logMessage(source, 'Cookie value should be specified');
return;
}

Expand Down
4 changes: 2 additions & 2 deletions src/scriptlets/trusted-set-cookie.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ import {

export function trustedSetCookie(source, name, value, offsetExpiresSec = '', path = '/') {
if (typeof name === 'undefined') {
logMessage(source, 'Cookie name should be specified.');
logMessage(source, 'Cookie name should be specified');
return;
}
if (typeof value === 'undefined') {
logMessage(source, 'Cookie value should be specified.');
logMessage(source, 'Cookie value should be specified');
return;
}

Expand Down
4 changes: 2 additions & 2 deletions src/scriptlets/trusted-set-local-storage-item.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ import {

export function trustedSetLocalStorageItem(source, key, value) {
if (typeof key === 'undefined') {
logMessage(source, 'Item key should be specified.');
logMessage(source, 'Item key should be specified');
return;
}

if (typeof value === 'undefined') {
logMessage(source, 'Item value should be specified.');
logMessage(source, 'Item value should be specified');
return;
}

Expand Down
1 change: 1 addition & 0 deletions tests/helpers/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ import './noop.test';
import './number-utils.test';
import './string-utils.test';
import './object-utils.test';
import './log-message.test';
Loading

0 comments on commit 9a4aa4d

Please sign in to comment.