@browserless.io/browserless 2.16.0 → 2.17.0-beta-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -1
- package/bin/browserless.js +6 -4
- package/bin/scaffold/src/hello-world.http.ts +1 -1
- package/build/browserless.js +1 -1
- package/build/config.d.ts +6 -0
- package/build/config.js +6 -0
- package/build/routes/chrome/http/content.post.body.json +38 -8
- package/build/routes/chrome/http/pdf.post.body.json +38 -8
- package/build/routes/chrome/http/scrape.post.body.json +38 -8
- package/build/routes/chrome/http/screenshot.post.body.json +38 -8
- package/build/routes/chromium/http/content.post.body.json +38 -8
- package/build/routes/chromium/http/pdf.post.body.json +38 -8
- package/build/routes/chromium/http/scrape.post.body.json +38 -8
- package/build/routes/chromium/http/screenshot.post.body.json +38 -8
- package/build/server.js +1 -1
- package/extensions/ublock/_locales/be/messages.json +1 -1
- package/extensions/ublock/_locales/br_FR/messages.json +2 -2
- package/extensions/ublock/_locales/bs/messages.json +5 -5
- package/extensions/ublock/_locales/eu/messages.json +1 -1
- package/extensions/ublock/_locales/it/messages.json +21 -21
- package/extensions/ublock/_locales/kn/messages.json +13 -13
- package/extensions/ublock/_locales/lt/messages.json +1 -1
- package/extensions/ublock/_locales/ms/messages.json +9 -9
- package/extensions/ublock/_locales/nb/messages.json +2 -2
- package/extensions/ublock/_locales/no/messages.json +2 -2
- package/extensions/ublock/_locales/sv/messages.json +2 -2
- package/extensions/ublock/_locales/tr/messages.json +4 -4
- package/extensions/ublock/_locales/zh_TW/messages.json +17 -17
- package/extensions/ublock/assets/assets.json +4 -3
- package/extensions/ublock/assets/resources/scriptlets.js +208 -57
- package/extensions/ublock/assets/thirdparties/easylist/easylist.txt +3584 -4032
- package/extensions/ublock/assets/thirdparties/easylist/easyprivacy.txt +3732 -1683
- package/extensions/ublock/assets/thirdparties/pgl.yoyo.org/as/serverlist +27 -205
- package/extensions/ublock/assets/thirdparties/publicsuffix.org/list/effective_tld_names.dat +465 -434
- package/extensions/ublock/assets/thirdparties/urlhaus-filter/urlhaus-filter-online.txt +3232 -1382
- package/extensions/ublock/assets/ublock/badware.min.txt +867 -408
- package/extensions/ublock/assets/ublock/filters.min.txt +1382 -937
- package/extensions/ublock/assets/ublock/privacy.min.txt +43 -56
- package/extensions/ublock/assets/ublock/quick-fixes.min.txt +127 -71
- package/extensions/ublock/assets/ublock/unbreak.min.txt +145 -27
- package/extensions/ublock/js/contentscript-extra.js +25 -0
- package/extensions/ublock/js/contentscript.js +3 -1
- package/extensions/ublock/js/cosmetic-filtering.js +8 -7
- package/extensions/ublock/js/dom.js +8 -4
- package/extensions/ublock/js/epicker-ui.js +1 -1
- package/extensions/ublock/js/s14e-serializer.js +2 -1
- package/extensions/ublock/js/static-filtering-parser.js +255 -254
- package/extensions/ublock/js/storage.js +7 -6
- package/extensions/ublock/js/traffic.js +33 -34
- package/extensions/ublock/manifest.json +1 -1
- package/extensions/ublock/popup-fenix.html +1 -1
- package/package.json +15 -15
- package/src/browserless.ts +1 -1
- package/src/config.ts +9 -0
- package/src/server.ts +1 -1
- package/static/debugger/index.html +1 -1
- package/static/debugger/router.js +1 -0
- package/static/debugger/tracker.js +1 -1
- package/static/docs/swagger.json +40 -10
- package/static/docs/swagger.min.json +39 -9
- package/static/function/client.js +4120 -16782
- package/static/function/index.html +4120 -16782
- package/static/debugger/router.bundle.js +0 -2
- package/static/debugger/router.bundle.js.map +0 -1
- package/static/debugger/router.d.ts +0 -2
|
@@ -57,12 +57,14 @@ function safeSelf() {
|
|
|
57
57
|
'Math_random': Math.random,
|
|
58
58
|
'Object': Object,
|
|
59
59
|
'Object_defineProperty': Object.defineProperty.bind(Object),
|
|
60
|
+
'Object_defineProperties': Object.defineProperties.bind(Object),
|
|
60
61
|
'Object_fromEntries': Object.fromEntries.bind(Object),
|
|
61
62
|
'Object_getOwnPropertyDescriptor': Object.getOwnPropertyDescriptor.bind(Object),
|
|
62
63
|
'RegExp': self.RegExp,
|
|
63
64
|
'RegExp_test': self.RegExp.prototype.test,
|
|
64
65
|
'RegExp_exec': self.RegExp.prototype.exec,
|
|
65
66
|
'Request_clone': self.Request.prototype.clone,
|
|
67
|
+
'String_fromCharCode': String.fromCharCode,
|
|
66
68
|
'XMLHttpRequest': self.XMLHttpRequest,
|
|
67
69
|
'addEventListener': self.EventTarget.prototype.addEventListener,
|
|
68
70
|
'removeEventListener': self.EventTarget.prototype.removeEventListener,
|
|
@@ -210,7 +212,7 @@ builtinScriptlets.push({
|
|
|
210
212
|
function getExceptionToken() {
|
|
211
213
|
const safe = safeSelf();
|
|
212
214
|
const token =
|
|
213
|
-
|
|
215
|
+
safe.String_fromCharCode(Date.now() % 26 + 97) +
|
|
214
216
|
safe.Math_floor(safe.Math_random() * 982451653 + 982451653).toString(36);
|
|
215
217
|
const oe = self.onerror;
|
|
216
218
|
self.onerror = function(msg, ...args) {
|
|
@@ -484,9 +486,8 @@ builtinScriptlets.push({
|
|
|
484
486
|
'safe-self.fn',
|
|
485
487
|
],
|
|
486
488
|
});
|
|
487
|
-
function validateConstantFn(trusted, raw) {
|
|
489
|
+
function validateConstantFn(trusted, raw, extraArgs = {}) {
|
|
488
490
|
const safe = safeSelf();
|
|
489
|
-
const extraArgs = safe.getExtraArgs(Array.from(arguments), 2);
|
|
490
491
|
let value;
|
|
491
492
|
if ( raw === 'undefined' ) {
|
|
492
493
|
value = undefined;
|
|
@@ -586,7 +587,7 @@ function setConstantFn(
|
|
|
586
587
|
};
|
|
587
588
|
if ( trappedProp === '' ) { return; }
|
|
588
589
|
const thisScript = document.currentScript;
|
|
589
|
-
let normalValue = validateConstantFn(trusted, rawValue);
|
|
590
|
+
let normalValue = validateConstantFn(trusted, rawValue, extraArgs);
|
|
590
591
|
if ( rawValue === 'noopFunc' || rawValue === 'trueFunc' || rawValue === 'falseFunc' ) {
|
|
591
592
|
normalValue = cloakFunc(normalValue);
|
|
592
593
|
}
|
|
@@ -714,7 +715,12 @@ function replaceNodeTextFn(
|
|
|
714
715
|
const reNodeName = safe.patternToRegex(nodeName, 'i', true);
|
|
715
716
|
const rePattern = safe.patternToRegex(pattern, 'gms');
|
|
716
717
|
const extraArgs = safe.getExtraArgs(Array.from(arguments), 3);
|
|
717
|
-
const
|
|
718
|
+
const reIncludes = extraArgs.includes || extraArgs.condition
|
|
719
|
+
? safe.patternToRegex(extraArgs.includes || extraArgs.condition, 'ms')
|
|
720
|
+
: null;
|
|
721
|
+
const reExcludes = extraArgs.excludes
|
|
722
|
+
? safe.patternToRegex(extraArgs.excludes, 'ms')
|
|
723
|
+
: null;
|
|
718
724
|
const stop = (takeRecord = true) => {
|
|
719
725
|
if ( takeRecord ) {
|
|
720
726
|
handleMutations(observer.takeRecords());
|
|
@@ -727,8 +733,14 @@ function replaceNodeTextFn(
|
|
|
727
733
|
let sedCount = extraArgs.sedCount || 0;
|
|
728
734
|
const handleNode = node => {
|
|
729
735
|
const before = node.textContent;
|
|
730
|
-
|
|
731
|
-
|
|
736
|
+
if ( reIncludes ) {
|
|
737
|
+
reIncludes.lastIndex = 0;
|
|
738
|
+
if ( safe.RegExp_test.call(reIncludes, before) === false ) { return true; }
|
|
739
|
+
}
|
|
740
|
+
if ( reExcludes ) {
|
|
741
|
+
reExcludes.lastIndex = 0;
|
|
742
|
+
if ( safe.RegExp_test.call(reExcludes, before) ) { return true; }
|
|
743
|
+
}
|
|
732
744
|
rePattern.lastIndex = 0;
|
|
733
745
|
if ( safe.RegExp_test.call(rePattern, before) === false ) { return true; }
|
|
734
746
|
rePattern.lastIndex = 0;
|
|
@@ -764,6 +776,7 @@ function replaceNodeTextFn(
|
|
|
764
776
|
count += 1;
|
|
765
777
|
if ( node === null ) { break; }
|
|
766
778
|
if ( reNodeName.test(node.nodeName) === false ) { continue; }
|
|
779
|
+
if ( node === document.currentScript ) { continue; }
|
|
767
780
|
if ( handleNode(node) ) { continue; }
|
|
768
781
|
stop(); break;
|
|
769
782
|
}
|
|
@@ -1008,6 +1021,8 @@ function setCookieFn(
|
|
|
1008
1021
|
cookieParts.push(`; domain=${options.domain}`);
|
|
1009
1022
|
}
|
|
1010
1023
|
cookieParts.push('; Secure');
|
|
1024
|
+
} else if ( /^__(Host|Secure)-/.test(name) ) {
|
|
1025
|
+
cookieParts.push('; Secure');
|
|
1011
1026
|
}
|
|
1012
1027
|
|
|
1013
1028
|
try {
|
|
@@ -1332,6 +1347,8 @@ function replaceFetchResponseFn(
|
|
|
1332
1347
|
if ( pattern === '*' ) { pattern = '.*'; }
|
|
1333
1348
|
const rePattern = safe.patternToRegex(pattern);
|
|
1334
1349
|
const propNeedles = parsePropertiesToMatch(propsToMatch, 'url');
|
|
1350
|
+
const extraArgs = safe.getExtraArgs(Array.from(arguments), 4);
|
|
1351
|
+
const reIncludes = extraArgs.includes ? safe.patternToRegex(extraArgs.includes) : null;
|
|
1335
1352
|
self.fetch = new Proxy(self.fetch, {
|
|
1336
1353
|
apply: function(target, thisArg, args) {
|
|
1337
1354
|
const fetchPromise = Reflect.apply(target, thisArg, args);
|
|
@@ -1361,6 +1378,9 @@ function replaceFetchResponseFn(
|
|
|
1361
1378
|
return fetchPromise.then(responseBefore => {
|
|
1362
1379
|
const response = responseBefore.clone();
|
|
1363
1380
|
return response.text().then(textBefore => {
|
|
1381
|
+
if ( reIncludes && reIncludes.test(textBefore) === false ) {
|
|
1382
|
+
return responseBefore;
|
|
1383
|
+
}
|
|
1364
1384
|
const textAfter = textBefore.replace(rePattern, replacement);
|
|
1365
1385
|
const outcome = textAfter !== textBefore ? 'match' : 'nomatch';
|
|
1366
1386
|
if ( outcome === 'nomatch' ) { return responseBefore; }
|
|
@@ -1642,6 +1662,8 @@ function addEventListenerDefuser(
|
|
|
1642
1662
|
const debug = shouldDebug(extraArgs);
|
|
1643
1663
|
const targetSelector = extraArgs.elements || undefined;
|
|
1644
1664
|
const elementMatches = elem => {
|
|
1665
|
+
if ( targetSelector === 'window' ) { return elem === window; }
|
|
1666
|
+
if ( targetSelector === 'document' ) { return elem === document; }
|
|
1645
1667
|
if ( elem && elem.matches && elem.matches(targetSelector) ) { return true; }
|
|
1646
1668
|
const elems = Array.from(document.querySelectorAll(targetSelector));
|
|
1647
1669
|
return elems.includes(elem);
|
|
@@ -1651,7 +1673,9 @@ function addEventListenerDefuser(
|
|
|
1651
1673
|
if ( elem instanceof Document ) { return 'document'; }
|
|
1652
1674
|
if ( elem instanceof Element === false ) { return '?'; }
|
|
1653
1675
|
const parts = [];
|
|
1654
|
-
|
|
1676
|
+
// https://github.com/uBlockOrigin/uAssets/discussions/17907#discussioncomment-9871079
|
|
1677
|
+
const id = String(elem.id);
|
|
1678
|
+
if ( id !== '' ) { parts.push(`#${CSS.escape(id)}`); }
|
|
1655
1679
|
for ( let i = 0; i < elem.classList.length; i++ ) {
|
|
1656
1680
|
parts.push(`.${CSS.escape(elem.classList.item(i))}`);
|
|
1657
1681
|
}
|
|
@@ -2055,11 +2079,11 @@ builtinScriptlets.push({
|
|
|
2055
2079
|
});
|
|
2056
2080
|
function noFetchIf(
|
|
2057
2081
|
propsToMatch = '',
|
|
2058
|
-
responseBody = ''
|
|
2082
|
+
responseBody = '',
|
|
2083
|
+
responseType = ''
|
|
2059
2084
|
) {
|
|
2060
|
-
if ( typeof propsToMatch !== 'string' ) { return; }
|
|
2061
2085
|
const safe = safeSelf();
|
|
2062
|
-
const logPrefix = safe.makeLogPrefix('prevent-fetch', propsToMatch, responseBody);
|
|
2086
|
+
const logPrefix = safe.makeLogPrefix('prevent-fetch', propsToMatch, responseBody, responseType);
|
|
2063
2087
|
const needles = [];
|
|
2064
2088
|
for ( const condition of propsToMatch.split(/\s+/) ) {
|
|
2065
2089
|
if ( condition === '' ) { continue; }
|
|
@@ -2074,6 +2098,28 @@ function noFetchIf(
|
|
|
2074
2098
|
}
|
|
2075
2099
|
needles.push({ key, re: safe.patternToRegex(value) });
|
|
2076
2100
|
}
|
|
2101
|
+
const validResponseProps = {
|
|
2102
|
+
ok: [ false, true ],
|
|
2103
|
+
statusText: [ '', 'Not Found' ],
|
|
2104
|
+
type: [ 'basic', 'cors', 'default', 'error', 'opaque' ],
|
|
2105
|
+
};
|
|
2106
|
+
const responseProps = {
|
|
2107
|
+
statusText: { value: 'OK' },
|
|
2108
|
+
};
|
|
2109
|
+
if ( /^\{.*\}$/.test(responseType) ) {
|
|
2110
|
+
try {
|
|
2111
|
+
Object.entries(JSON.parse(responseType)).forEach(([ p, v ]) => {
|
|
2112
|
+
if ( validResponseProps[p] === undefined ) { return; }
|
|
2113
|
+
if ( validResponseProps[p].includes(v) === false ) { return; }
|
|
2114
|
+
responseProps[p] = { value: v };
|
|
2115
|
+
});
|
|
2116
|
+
}
|
|
2117
|
+
catch(ex) {}
|
|
2118
|
+
} else if ( responseType !== '' ) {
|
|
2119
|
+
if ( validResponseProps.type.includes(responseType) ) {
|
|
2120
|
+
responseProps.type = { value: responseType };
|
|
2121
|
+
}
|
|
2122
|
+
}
|
|
2077
2123
|
self.fetch = new Proxy(self.fetch, {
|
|
2078
2124
|
apply: function(target, thisArg, args) {
|
|
2079
2125
|
const details = args[0] instanceof self.Request
|
|
@@ -2111,33 +2157,18 @@ function noFetchIf(
|
|
|
2111
2157
|
if ( proceed ) {
|
|
2112
2158
|
return Reflect.apply(target, thisArg, args);
|
|
2113
2159
|
}
|
|
2114
|
-
let responseType = '';
|
|
2115
|
-
if ( details.mode === undefined || details.mode === 'cors' ) {
|
|
2116
|
-
try {
|
|
2117
|
-
const desURL = new URL(details.url);
|
|
2118
|
-
responseType = desURL.origin !== document.location.origin
|
|
2119
|
-
? 'cors'
|
|
2120
|
-
: 'basic';
|
|
2121
|
-
} catch(ex) {
|
|
2122
|
-
safe.uboErr(logPrefix, `Error: ${ex}`);
|
|
2123
|
-
}
|
|
2124
|
-
}
|
|
2125
2160
|
return generateContentFn(responseBody).then(text => {
|
|
2126
2161
|
safe.uboLog(logPrefix, `Prevented with response "${text}"`);
|
|
2127
2162
|
const response = new Response(text, {
|
|
2128
|
-
statusText: 'OK',
|
|
2129
2163
|
headers: {
|
|
2130
2164
|
'Content-Length': text.length,
|
|
2131
2165
|
}
|
|
2132
2166
|
});
|
|
2133
|
-
|
|
2134
|
-
value: details.url
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
value: responseType
|
|
2139
|
-
});
|
|
2140
|
-
}
|
|
2167
|
+
const props = Object.assign(
|
|
2168
|
+
{ url: { value: details.url } },
|
|
2169
|
+
responseProps
|
|
2170
|
+
);
|
|
2171
|
+
safe.Object_defineProperties(response, props);
|
|
2141
2172
|
return response;
|
|
2142
2173
|
});
|
|
2143
2174
|
}
|
|
@@ -3465,7 +3496,7 @@ function hrefSanitizer(
|
|
|
3465
3496
|
};
|
|
3466
3497
|
const validateURL = text => {
|
|
3467
3498
|
if ( text === '' ) { return ''; }
|
|
3468
|
-
if ( /[
|
|
3499
|
+
if ( /[\x00-\x20\x7f]/.test(text) ) { return ''; }
|
|
3469
3500
|
try {
|
|
3470
3501
|
const url = new URL(text, document.location);
|
|
3471
3502
|
return url.href;
|
|
@@ -3473,17 +3504,26 @@ function hrefSanitizer(
|
|
|
3473
3504
|
}
|
|
3474
3505
|
return '';
|
|
3475
3506
|
};
|
|
3507
|
+
const extractParam = (href, source) => {
|
|
3508
|
+
if ( Boolean(source) === false ) { return href; }
|
|
3509
|
+
const recursive = source.includes('?', 1);
|
|
3510
|
+
const end = recursive ? source.indexOf('?', 1) : source.length;
|
|
3511
|
+
try {
|
|
3512
|
+
const url = new URL(href, document.location);
|
|
3513
|
+
const value = url.searchParams.get(source.slice(1, end));
|
|
3514
|
+
if ( value === null ) { return href }
|
|
3515
|
+
if ( recursive ) { return extractParam(value, source.slice(end)); }
|
|
3516
|
+
return value;
|
|
3517
|
+
} catch(x) {
|
|
3518
|
+
}
|
|
3519
|
+
return href;
|
|
3520
|
+
};
|
|
3476
3521
|
const extractText = (elem, source) => {
|
|
3477
3522
|
if ( /^\[.*\]$/.test(source) ) {
|
|
3478
3523
|
return elem.getAttribute(source.slice(1,-1).trim()) || '';
|
|
3479
3524
|
}
|
|
3480
3525
|
if ( source.startsWith('?') ) {
|
|
3481
|
-
|
|
3482
|
-
const url = new URL(elem.href, document.location);
|
|
3483
|
-
return url.searchParams.get(source.slice(1)) || '';
|
|
3484
|
-
} catch(x) {
|
|
3485
|
-
}
|
|
3486
|
-
return '';
|
|
3526
|
+
return extractParam(elem.href, source);
|
|
3487
3527
|
}
|
|
3488
3528
|
if ( source === 'text' ) {
|
|
3489
3529
|
return elem.textContent
|
|
@@ -3730,10 +3770,10 @@ builtinScriptlets.push({
|
|
|
3730
3770
|
});
|
|
3731
3771
|
function removeNodeText(
|
|
3732
3772
|
nodeName,
|
|
3733
|
-
|
|
3773
|
+
includes,
|
|
3734
3774
|
...extraArgs
|
|
3735
3775
|
) {
|
|
3736
|
-
replaceNodeTextFn(nodeName, '', '', '
|
|
3776
|
+
replaceNodeTextFn(nodeName, '', '', 'includes', includes || '', ...extraArgs);
|
|
3737
3777
|
}
|
|
3738
3778
|
|
|
3739
3779
|
/*******************************************************************************
|
|
@@ -3778,6 +3818,9 @@ function setCookie(
|
|
|
3778
3818
|
'yes', 'y', 'no', 'n',
|
|
3779
3819
|
'necessary', 'required',
|
|
3780
3820
|
'approved', 'disapproved',
|
|
3821
|
+
'hide', 'hidden',
|
|
3822
|
+
'essential', 'nonessential',
|
|
3823
|
+
'dismiss', 'dismissed',
|
|
3781
3824
|
];
|
|
3782
3825
|
const normalized = value.toLowerCase();
|
|
3783
3826
|
const match = /^("?)(.+)\1$/.exec(normalized);
|
|
@@ -4228,10 +4271,14 @@ function trustedSetCookie(
|
|
|
4228
4271
|
const logPrefix = safe.makeLogPrefix('set-cookie', name, value, path);
|
|
4229
4272
|
const time = new Date();
|
|
4230
4273
|
|
|
4231
|
-
if ( value
|
|
4232
|
-
value =
|
|
4233
|
-
}
|
|
4234
|
-
|
|
4274
|
+
if ( value.includes('$now$') ) {
|
|
4275
|
+
value = value.replaceAll('$now$', time.getTime());
|
|
4276
|
+
}
|
|
4277
|
+
if ( value.includes('$currentDate$') ) {
|
|
4278
|
+
value = value.replaceAll('$currentDate$', time.toUTCString());
|
|
4279
|
+
}
|
|
4280
|
+
if ( value.includes('$currentISODate$') ) {
|
|
4281
|
+
value = value.replaceAll('$currentISODate$', time.toISOString());
|
|
4235
4282
|
}
|
|
4236
4283
|
|
|
4237
4284
|
let expires = '';
|
|
@@ -4362,6 +4409,8 @@ function trustedReplaceXhrResponse(
|
|
|
4362
4409
|
if ( pattern === '*' ) { pattern = '.*'; }
|
|
4363
4410
|
const rePattern = safe.patternToRegex(pattern);
|
|
4364
4411
|
const propNeedles = parsePropertiesToMatch(propsToMatch, 'url');
|
|
4412
|
+
const extraArgs = safe.getExtraArgs(Array.from(arguments), 3);
|
|
4413
|
+
const reIncludes = extraArgs.includes ? safe.patternToRegex(extraArgs.includes) : null;
|
|
4365
4414
|
self.XMLHttpRequest = class extends self.XMLHttpRequest {
|
|
4366
4415
|
open(method, url, ...args) {
|
|
4367
4416
|
const outerXhr = this;
|
|
@@ -4399,6 +4448,9 @@ function trustedReplaceXhrResponse(
|
|
|
4399
4448
|
if ( typeof innerResponse !== 'string' ) {
|
|
4400
4449
|
return (xhrDetails.response = innerResponse);
|
|
4401
4450
|
}
|
|
4451
|
+
if ( reIncludes && reIncludes.test(innerResponse) === false ) {
|
|
4452
|
+
return (xhrDetails.response = innerResponse);
|
|
4453
|
+
}
|
|
4402
4454
|
const textBefore = innerResponse;
|
|
4403
4455
|
const textAfter = textBefore.replace(rePattern, replacement);
|
|
4404
4456
|
if ( textAfter !== textBefore ) {
|
|
@@ -4733,24 +4785,29 @@ builtinScriptlets.push({
|
|
|
4733
4785
|
});
|
|
4734
4786
|
function trustedReplaceArgument(
|
|
4735
4787
|
propChain = '',
|
|
4736
|
-
|
|
4788
|
+
argposRaw = '',
|
|
4737
4789
|
argraw = ''
|
|
4738
4790
|
) {
|
|
4739
4791
|
if ( propChain === '' ) { return; }
|
|
4740
|
-
if ( argpos === '' ) { return; }
|
|
4741
|
-
if ( argraw === '' ) { return; }
|
|
4742
4792
|
const safe = safeSelf();
|
|
4743
|
-
const logPrefix = safe.makeLogPrefix('trusted-replace-argument', propChain,
|
|
4793
|
+
const logPrefix = safe.makeLogPrefix('trusted-replace-argument', propChain, argposRaw, argraw);
|
|
4794
|
+
const argpos = parseInt(argposRaw, 10) || 0;
|
|
4744
4795
|
const extraArgs = safe.getExtraArgs(Array.from(arguments), 3);
|
|
4745
|
-
const normalValue = validateConstantFn(true, argraw);
|
|
4796
|
+
const normalValue = validateConstantFn(true, argraw, extraArgs);
|
|
4746
4797
|
const reCondition = extraArgs.condition
|
|
4747
4798
|
? safe.patternToRegex(extraArgs.condition)
|
|
4748
4799
|
: /^/;
|
|
4749
4800
|
const reflector = proxyApplyFn(propChain, function(...args) {
|
|
4801
|
+
if ( argposRaw === '' ) {
|
|
4802
|
+
safe.uboLog(logPrefix, `Arguments:\n${args.join('\n')}`);
|
|
4803
|
+
return reflector(...args);
|
|
4804
|
+
}
|
|
4750
4805
|
const arglist = args[args.length-1];
|
|
4751
4806
|
if ( Array.isArray(arglist) === false ) { return reflector(...args); }
|
|
4752
4807
|
const argBefore = arglist[argpos];
|
|
4753
|
-
if (
|
|
4808
|
+
if ( safe.RegExp_test.call(reCondition, argBefore) === false ) {
|
|
4809
|
+
return reflector(...args);
|
|
4810
|
+
}
|
|
4754
4811
|
arglist[argpos] = normalValue;
|
|
4755
4812
|
safe.uboLog(logPrefix, `Replaced argument:\nBefore: ${JSON.stringify(argBefore)}\nAfter: ${normalValue}`);
|
|
4756
4813
|
return reflector(...args);
|
|
@@ -4781,20 +4838,114 @@ function trustedReplaceOutboundText(
|
|
|
4781
4838
|
const extraArgs = safe.getExtraArgs(args);
|
|
4782
4839
|
const reCondition = safe.patternToRegex(extraArgs.condition || '');
|
|
4783
4840
|
const reflector = proxyApplyFn(propChain, function(...args) {
|
|
4784
|
-
const
|
|
4841
|
+
const encodedTextBefore = reflector(...args);
|
|
4842
|
+
let textBefore = encodedTextBefore;
|
|
4843
|
+
if ( extraArgs.encoding === 'base64' ) {
|
|
4844
|
+
try { textBefore = self.atob(encodedTextBefore); }
|
|
4845
|
+
catch(ex) { return encodedTextBefore; }
|
|
4846
|
+
}
|
|
4785
4847
|
if ( pattern === '' ) {
|
|
4786
|
-
safe.uboLog(logPrefix, '
|
|
4787
|
-
return
|
|
4848
|
+
safe.uboLog(logPrefix, 'Decoded outbound text:\n', textBefore);
|
|
4849
|
+
return encodedTextBefore;
|
|
4788
4850
|
}
|
|
4789
4851
|
reCondition.lastIndex = 0;
|
|
4790
|
-
if ( reCondition.test(textBefore) === false ) { return
|
|
4852
|
+
if ( reCondition.test(textBefore) === false ) { return encodedTextBefore; }
|
|
4791
4853
|
const textAfter = textBefore.replace(rePattern, replacement);
|
|
4792
|
-
if ( textAfter === textBefore ) { return
|
|
4854
|
+
if ( textAfter === textBefore ) { return encodedTextBefore; }
|
|
4793
4855
|
safe.uboLog(logPrefix, 'Matched and replaced');
|
|
4794
4856
|
if ( safe.logLevel > 1 ) {
|
|
4795
|
-
safe.uboLog(logPrefix, 'Modified outbound text:\n', textAfter);
|
|
4857
|
+
safe.uboLog(logPrefix, 'Modified decoded outbound text:\n', textAfter);
|
|
4858
|
+
}
|
|
4859
|
+
let encodedTextAfter = textAfter;
|
|
4860
|
+
if ( extraArgs.encoding === 'base64' ) {
|
|
4861
|
+
encodedTextAfter = self.btoa(textAfter);
|
|
4862
|
+
}
|
|
4863
|
+
return encodedTextAfter;
|
|
4864
|
+
});
|
|
4865
|
+
}
|
|
4866
|
+
|
|
4867
|
+
/*******************************************************************************
|
|
4868
|
+
*
|
|
4869
|
+
* Reference:
|
|
4870
|
+
* https://github.com/AdguardTeam/Scriptlets/blob/5a92d79489/wiki/about-trusted-scriptlets.md#trusted-suppress-native-method
|
|
4871
|
+
*
|
|
4872
|
+
* This is a first version with current limitations:
|
|
4873
|
+
* - Does not support matching arguments which are object or array
|
|
4874
|
+
* - Does not support `stack` parameter
|
|
4875
|
+
*
|
|
4876
|
+
* If `signatureStr` parameter is not declared, the scriptlet will log all calls
|
|
4877
|
+
* to `methodPath` along with the arguments passed and will not prevent the
|
|
4878
|
+
* trapped method.
|
|
4879
|
+
*
|
|
4880
|
+
* */
|
|
4881
|
+
|
|
4882
|
+
builtinScriptlets.push({
|
|
4883
|
+
name: 'trusted-suppress-native-method.js',
|
|
4884
|
+
requiresTrust: true,
|
|
4885
|
+
fn: trustedSuppressNativeMethod,
|
|
4886
|
+
dependencies: [
|
|
4887
|
+
'proxy-apply.fn',
|
|
4888
|
+
'safe-self.fn',
|
|
4889
|
+
],
|
|
4890
|
+
});
|
|
4891
|
+
function trustedSuppressNativeMethod(
|
|
4892
|
+
methodPath = '',
|
|
4893
|
+
signature = '',
|
|
4894
|
+
how = '',
|
|
4895
|
+
stack = ''
|
|
4896
|
+
) {
|
|
4897
|
+
if ( methodPath === '' ) { return; }
|
|
4898
|
+
if ( stack !== '' ) { return; }
|
|
4899
|
+
const safe = safeSelf();
|
|
4900
|
+
const logPrefix = safe.makeLogPrefix('trusted-suppress-native-method', methodPath, signature, how);
|
|
4901
|
+
const signatureArgs = signature.split(/\s*\|\s*/).map(v => {
|
|
4902
|
+
if ( /^".*"$/.test(v) ) {
|
|
4903
|
+
return { type: 'pattern', re: safe.patternToRegex(v.slice(1, -1)) };
|
|
4904
|
+
}
|
|
4905
|
+
if ( v === 'false' ) {
|
|
4906
|
+
return { type: 'exact', value: false };
|
|
4907
|
+
}
|
|
4908
|
+
if ( v === 'true' ) {
|
|
4909
|
+
return { type: 'exact', value: true };
|
|
4910
|
+
}
|
|
4911
|
+
if ( v === 'null' ) {
|
|
4912
|
+
return { type: 'exact', value: null };
|
|
4913
|
+
}
|
|
4914
|
+
if ( v === 'undefined' ) {
|
|
4915
|
+
return { type: 'exact', value: undefined };
|
|
4916
|
+
}
|
|
4917
|
+
});
|
|
4918
|
+
const reflector = proxyApplyFn(methodPath, function(...args) {
|
|
4919
|
+
if ( signature === '' ) {
|
|
4920
|
+
safe.uboLog(logPrefix, `Arguments:\n${args.join('\n')}`);
|
|
4921
|
+
return reflector(...args);
|
|
4922
|
+
}
|
|
4923
|
+
const arglist = args[args.length-1];
|
|
4924
|
+
if ( Array.isArray(arglist) === false ) {
|
|
4925
|
+
return reflector(...args);
|
|
4926
|
+
}
|
|
4927
|
+
if ( arglist.length < signatureArgs.length ) {
|
|
4928
|
+
return reflector(...args);
|
|
4929
|
+
}
|
|
4930
|
+
for ( let i = 0; i < signatureArgs.length; i++ ) {
|
|
4931
|
+
const signatureArg = signatureArgs[i];
|
|
4932
|
+
if ( signatureArg === undefined ) { continue; }
|
|
4933
|
+
const targetArg = arglist[i];
|
|
4934
|
+
if ( signatureArg.type === 'exact' ) {
|
|
4935
|
+
if ( targetArg !== signatureArg.value ) {
|
|
4936
|
+
return reflector(...args);
|
|
4937
|
+
}
|
|
4938
|
+
}
|
|
4939
|
+
if ( signatureArg.type === 'pattern' ) {
|
|
4940
|
+
if ( safe.RegExp_test.call(signatureArg.re, targetArg) === false ) {
|
|
4941
|
+
return reflector(...args);
|
|
4942
|
+
}
|
|
4943
|
+
}
|
|
4944
|
+
}
|
|
4945
|
+
safe.uboLog(logPrefix, `Suppressed:\n${args.join('\n')}`);
|
|
4946
|
+
if ( how === 'abort' ) {
|
|
4947
|
+
throw new ReferenceError();
|
|
4796
4948
|
}
|
|
4797
|
-
return textAfter;
|
|
4798
4949
|
});
|
|
4799
4950
|
}
|
|
4800
4951
|
|