diff --git a/CHANGELOG.md b/CHANGELOG.md index 20d503bf1..97d496a3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## [Unreleased] + +### Added + +- ability to set proxy trap in `set-constant` scriptlet [#330](https://github.com/AdguardTeam/Scriptlets/issues/330) + ## [v1.9.91] - 2023-11-13 ### Added @@ -284,6 +290,7 @@ prevent inline `onerror` and match `link` tag [#276](https://github.com/AdguardT - `metrika-yandex-tag` [#254](https://github.com/AdguardTeam/Scriptlets/issues/254) - `googlesyndication-adsbygoogle` [#252](https://github.com/AdguardTeam/Scriptlets/issues/252) +[Unreleased]: https://github.com/AdguardTeam/Scriptlets/compare/v1.9.91...HEAD [v1.9.91]: https://github.com/AdguardTeam/Scriptlets/compare/v1.9.83...v1.9.91 [v1.9.83]: https://github.com/AdguardTeam/Scriptlets/compare/v1.9.72...v1.9.83 [v1.9.72]: https://github.com/AdguardTeam/Scriptlets/compare/v1.9.70...v1.9.72 diff --git a/scripts/compatibility-table.json b/scripts/compatibility-table.json index d43ac265f..fe97e1b63 100644 --- a/scripts/compatibility-table.json +++ b/scripts/compatibility-table.json @@ -269,9 +269,6 @@ { "ubo": "spoof-css.js" }, - { - "ubo": "replace-node-text.js (rpnt.js)" - }, { "ubo": "trusted-set-constant.js (trusted-set.js)" }, @@ -316,6 +313,9 @@ }, { "ubo": "trusted-set-session-storage-item.js" + }, + { + "ubo": "trusted-replace-node-text.js (trusted-rpnt.js, replace-node-text.js, rpnt.js)" } ], "redirects": [ @@ -524,4 +524,4 @@ "ubo": "noop-0.5s.mp3" } ] -} \ No newline at end of file +} diff --git a/src/scriptlets/set-constant.js b/src/scriptlets/set-constant.js index b4afcefd9..1ee212567 100644 --- a/src/scriptlets/set-constant.js +++ b/src/scriptlets/set-constant.js @@ -43,7 +43,7 @@ import { * ### Syntax * * ```text - * example.org#%#//scriptlet('set-constant', property, value[, stack]) + * example.org#%#//scriptlet('set-constant', property, value[, stack,[ valueWrapper[, setProxyTrap]]]) * ``` * * - `property` — required, path to a property (joined with `.` if needed). The property must be attached to `window`. @@ -74,6 +74,7 @@ import { * - `asCallback` – function returning callback, that would return value * - `asResolved` – Promise that would resolve with value * - `asRejected` – Promise that would reject with value + * - `setProxyTrap` – optional, boolean, if set to true, proxy trap will be set on the object * * ### Examples * @@ -113,10 +114,19 @@ import { * ✔ document.fifth.catch((reason) => reason === 42) // promise rejects with specified number * ``` * + * ```adblock + * ! Any access to `window.foo.bar` will return `false` and the proxy trap will be set on the `foo` object + * ! It may be required in the case when `foo` object is overwritten by website script + * ! Related to this issue - https://github.com/AdguardTeam/Scriptlets/issues/330 + * example.org#%#//scriptlet('set-constant', 'foo.bar', 'false', '', '', 'true') + * + * ✔ window.foo.bar === false + * ``` + * * @added v1.0.4. */ /* eslint-enable max-len */ -export function setConstant(source, property, value, stack = '', valueWrapper = '') { +export function setConstant(source, property, value, stack = '', valueWrapper = '', setProxyTrap = false) { const uboAliases = [ 'set-constant.js', 'ubo-set-constant.js', @@ -299,7 +309,7 @@ export function setConstant(source, property, value, stack = '', valueWrapper = // Get properties which should be checked and remove first one // because it's current object const propertiesToCheck = property.split('.').slice(1); - if (!isProxyTrapSet) { + if (setProxyTrap && !isProxyTrapSet) { isProxyTrapSet = true; a = new Proxy(a, { get: (target, propertyKey, val) => { diff --git a/tests/scriptlets/set-constant.test.js b/tests/scriptlets/set-constant.test.js index f8d99a3fc..435851a4e 100644 --- a/tests/scriptlets/set-constant.test.js +++ b/tests/scriptlets/set-constant.test.js @@ -486,7 +486,7 @@ if (!isSupported) { // https://github.com/AdguardTeam/Scriptlets/issues/330 test('Check overriden value - array', (assert) => { - runScriptletFromTag('pageData.__banners.0.commercial.mediaUrl', ''); + runScriptletFromTag('pageData.__banners.0.commercial.mediaUrl', '', '', '', 'true'); const done = assert.async(); window.pageData = { __banners: [{ @@ -522,7 +522,7 @@ if (!isSupported) { // https://github.com/AdguardTeam/Scriptlets/issues/330 test('Check overriden - array 2', (assert) => { - runScriptletFromTag('pageData.__banners.0.commercial.mediaUrl', ''); + runScriptletFromTag('pageData.__banners.0.commercial.mediaUrl', '', '', '', 'true'); const done = assert.async(); window.pageData = { __banners: [{ @@ -652,7 +652,7 @@ if (!isSupported) { // https://github.com/AdguardTeam/Scriptlets/issues/330 test('Check overriden value - object', (assert) => { - runScriptletFromTag('foo.prototype.abc.qwerty', 'false'); + runScriptletFromTag('foo.prototype.abc.qwerty', 'false', '', '', 'true'); window.foo = function name() { }; window.foo.prototype = { bar: 1 }; window.foo.prototype.abc = { @@ -665,7 +665,7 @@ if (!isSupported) { // https://github.com/AdguardTeam/Scriptlets/issues/330 test('Override value 2 times - object', (assert) => { - runScriptletFromTag('foo.prototype.abc.qwerty', 'false'); + runScriptletFromTag('foo.prototype.abc.qwerty', 'false', '', '', 'true'); window.foo = function name() { }; window.foo.prototype = { bar: 1 }; window.foo.prototype.abc = { @@ -699,7 +699,7 @@ if (!isSupported) { // https://github.com/AdguardTeam/Scriptlets/issues/330 test('Check overriden value - object + similar object which should not be overriden', (assert) => { - runScriptletFromTag('foo.prototype.abc.qwerty', 'false'); + runScriptletFromTag('foo.prototype.abc.qwerty', 'false', '', '', 'true'); window.foo = function name() { }; window.foo.prototype = { bar: 1 }; window.foo.prototype.abc = { @@ -754,7 +754,7 @@ if (!isSupported) { }); test('Test for reassignment 1', (assert) => { - runScriptletFromTag('zxcv.test.bar.qw', 'trueFunc'); + runScriptletFromTag('zxcv.test.bar.qw', 'trueFunc', '', '', 'true'); const funcOne = () => 1; window.zxcv = {}; // Reassign @@ -772,7 +772,7 @@ if (!isSupported) { }); test('Test for reassignment 2', (assert) => { - runScriptletFromTag('WO.adblock.useAdblocker', 'false'); + runScriptletFromTag('WO.adblock.useAdblocker', 'false', '', '', 'true'); window.WO = window.WO || {}; window.WO.strings = window.WO.strings || {}; @@ -797,7 +797,7 @@ if (!isSupported) { }); test('Check if proxy was not set many times', (assert) => { - runScriptletFromTag('proxy.test.abc', 'trueFunc'); + runScriptletFromTag('proxy.test.abc', 'trueFunc', '', '', 'true'); // Expected number of calls to getOwnPropertyDescriptor const EXPECTED_NUMBER = 4; diff --git a/wiki/compatibility-table.md b/wiki/compatibility-table.md index 1cf693750..4d6acc1c1 100644 --- a/wiki/compatibility-table.md +++ b/wiki/compatibility-table.md @@ -84,7 +84,6 @@ | | | race | | | window.name-defuser.js | | | | spoof-css.js | | -| | replace-node-text.js (rpnt.js) | | | | trusted-set-constant.js (trusted-set.js) | | | | trusted-set-cookie.js | | | | trusted-set-local-storage-item.js | | @@ -100,6 +99,7 @@ | | trusted-prune-inbound-object.js | | | | trusted-prune-outbound-object.js | | | | trusted-set-session-storage-item.js | | +| | trusted-replace-node-text.js (trusted-rpnt.js, replace-node-text.js, rpnt.js) | | ## Redirects compatibility table