@browserless.io/browserless 2.23.0 → 2.24.0-beta-2
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/build/routes/chrome/http/pdf.post.body.json +8 -8
- package/build/routes/chromium/http/content.post.body.json +8 -8
- package/build/routes/chromium/http/pdf.post.body.json +8 -8
- package/build/routes/chromium/http/scrape.post.body.json +8 -8
- package/build/routes/chromium/http/screenshot.post.body.json +8 -8
- package/docker/base/Dockerfile +1 -1
- package/docker/multi/Dockerfile +2 -1
- package/docker/webkit/Dockerfile +2 -1
- package/extensions/ublock/_locales/ar/messages.json +5 -1
- package/extensions/ublock/_locales/az/messages.json +4 -0
- package/extensions/ublock/_locales/be/messages.json +5 -1
- package/extensions/ublock/_locales/bg/messages.json +4 -0
- package/extensions/ublock/_locales/bn/messages.json +4 -0
- package/extensions/ublock/_locales/br_FR/messages.json +4 -0
- package/extensions/ublock/_locales/bs/messages.json +4 -0
- package/extensions/ublock/_locales/ca/messages.json +4 -0
- package/extensions/ublock/_locales/cs/messages.json +6 -2
- package/extensions/ublock/_locales/cv/messages.json +4 -0
- package/extensions/ublock/_locales/cy/messages.json +15 -11
- package/extensions/ublock/_locales/da/messages.json +4 -0
- package/extensions/ublock/_locales/de/messages.json +8 -4
- package/extensions/ublock/_locales/el/messages.json +4 -0
- package/extensions/ublock/_locales/en/messages.json +4 -0
- package/extensions/ublock/_locales/en_GB/messages.json +4 -0
- package/extensions/ublock/_locales/eo/messages.json +4 -0
- package/extensions/ublock/_locales/es/messages.json +5 -1
- package/extensions/ublock/_locales/et/messages.json +4 -0
- package/extensions/ublock/_locales/eu/messages.json +4 -0
- package/extensions/ublock/_locales/fa/messages.json +14 -10
- package/extensions/ublock/_locales/fi/messages.json +7 -3
- package/extensions/ublock/_locales/fil/messages.json +4 -0
- package/extensions/ublock/_locales/fr/messages.json +5 -1
- package/extensions/ublock/_locales/fy/messages.json +4 -0
- package/extensions/ublock/_locales/gl/messages.json +4 -0
- package/extensions/ublock/_locales/gu/messages.json +4 -0
- package/extensions/ublock/_locales/he/messages.json +4 -0
- package/extensions/ublock/_locales/hi/messages.json +4 -0
- package/extensions/ublock/_locales/hr/messages.json +4 -0
- package/extensions/ublock/_locales/hu/messages.json +4 -0
- package/extensions/ublock/_locales/hy/messages.json +4 -0
- package/extensions/ublock/_locales/id/messages.json +4 -0
- package/extensions/ublock/_locales/it/messages.json +4 -0
- package/extensions/ublock/_locales/ja/messages.json +6 -2
- package/extensions/ublock/_locales/ka/messages.json +5 -1
- package/extensions/ublock/_locales/kk/messages.json +4 -0
- package/extensions/ublock/_locales/kn/messages.json +4 -0
- package/extensions/ublock/_locales/ko/messages.json +5 -1
- package/extensions/ublock/_locales/lt/messages.json +4 -0
- package/extensions/ublock/_locales/lv/messages.json +4 -0
- package/extensions/ublock/_locales/mk/messages.json +4 -0
- package/extensions/ublock/_locales/ml/messages.json +4 -0
- package/extensions/ublock/_locales/mr/messages.json +4 -0
- package/extensions/ublock/_locales/ms/messages.json +4 -0
- package/extensions/ublock/_locales/nb/messages.json +4 -0
- package/extensions/ublock/_locales/nl/messages.json +4 -0
- package/extensions/ublock/_locales/no/messages.json +4 -0
- package/extensions/ublock/_locales/oc/messages.json +4 -0
- package/extensions/ublock/_locales/pa/messages.json +5 -1
- package/extensions/ublock/_locales/pl/messages.json +4 -0
- package/extensions/ublock/_locales/pt_BR/messages.json +4 -0
- package/extensions/ublock/_locales/pt_PT/messages.json +4 -0
- package/extensions/ublock/_locales/ro/messages.json +4 -0
- package/extensions/ublock/_locales/ru/messages.json +5 -1
- package/extensions/ublock/_locales/si/messages.json +4 -0
- package/extensions/ublock/_locales/sk/messages.json +4 -0
- package/extensions/ublock/_locales/sl/messages.json +4 -0
- package/extensions/ublock/_locales/so/messages.json +4 -0
- package/extensions/ublock/_locales/sq/messages.json +4 -0
- package/extensions/ublock/_locales/sr/messages.json +4 -0
- package/extensions/ublock/_locales/sv/messages.json +5 -1
- package/extensions/ublock/_locales/sw/messages.json +4 -0
- package/extensions/ublock/_locales/ta/messages.json +4 -0
- package/extensions/ublock/_locales/te/messages.json +4 -0
- package/extensions/ublock/_locales/th/messages.json +4 -0
- package/extensions/ublock/_locales/tr/messages.json +4 -0
- package/extensions/ublock/_locales/uk/messages.json +7 -3
- package/extensions/ublock/_locales/ur/messages.json +4 -0
- package/extensions/ublock/_locales/vi/messages.json +4 -0
- package/extensions/ublock/_locales/zh_CN/messages.json +4 -0
- package/extensions/ublock/_locales/zh_TW/messages.json +4 -0
- package/extensions/ublock/assets/assets.json +14 -14
- package/extensions/ublock/assets/resources/run-at.js +80 -0
- package/extensions/ublock/assets/resources/safe-self.js +218 -0
- package/extensions/ublock/assets/resources/scriptlets.js +461 -538
- package/extensions/ublock/assets/resources/set-attr.js +201 -0
- package/extensions/ublock/assets/thirdparties/easylist/easylist.txt +4002 -11582
- package/extensions/ublock/assets/thirdparties/easylist/easyprivacy.txt +257 -83
- package/extensions/ublock/assets/thirdparties/pgl.yoyo.org/as/serverlist +22 -38
- package/extensions/ublock/assets/thirdparties/publicsuffix.org/list/effective_tld_names.dat +102 -110
- package/extensions/ublock/assets/thirdparties/urlhaus-filter/urlhaus-filter-online.txt +2776 -3613
- package/extensions/ublock/assets/ublock/badware.min.txt +581 -382
- package/extensions/ublock/assets/ublock/filters.min.txt +997 -990
- package/extensions/ublock/assets/ublock/privacy.min.txt +145 -26
- package/extensions/ublock/assets/ublock/quick-fixes.min.txt +134 -83
- package/extensions/ublock/assets/ublock/unbreak.min.txt +69 -46
- package/extensions/ublock/css/document-blocked.css +28 -1
- package/extensions/ublock/document-blocked.html +9 -7
- package/extensions/ublock/js/assets.js +15 -11
- package/extensions/ublock/js/benchmarks.js +13 -9
- package/extensions/ublock/js/biditrie.js +1 -1
- package/extensions/ublock/js/document-blocked.js +41 -5
- package/extensions/ublock/js/hntrie.js +1 -1
- package/extensions/ublock/js/i18n.js +2 -4
- package/extensions/ublock/js/pagestore.js +61 -43
- package/extensions/ublock/js/s14e-serializer.js +47 -22
- package/extensions/ublock/js/scriptlet-filtering.js +21 -18
- package/extensions/ublock/js/scriptlets/load-large-media-interactive.js +61 -48
- package/extensions/ublock/js/scriptlets/should-inject-contentscript.js +1 -3
- package/extensions/ublock/js/static-dnr-filtering.js +9 -7
- package/extensions/ublock/js/static-filtering-parser.js +87 -54
- package/extensions/ublock/js/static-net-filtering.js +118 -42
- package/extensions/ublock/js/traffic.js +37 -18
- package/extensions/ublock/js/vapi-background-ext.js +21 -49
- package/extensions/ublock/js/vapi-background.js +8 -0
- package/extensions/ublock/manifest.json +1 -1
- package/extensions/ublock/web_accessible_resources/googlesyndication_adsbygoogle.js +3 -1
- package/package.json +16 -16
- package/static/docs/swagger.json +1 -1
- package/static/docs/swagger.min.json +1 -1
|
@@ -1531,7 +1531,7 @@ export class AstFilterParser {
|
|
|
1531
1531
|
break;
|
|
1532
1532
|
}
|
|
1533
1533
|
const value = this.getNetOptionValue(NODE_TYPE_NET_OPTION_NAME_URLSKIP);
|
|
1534
|
-
if ( value.
|
|
1534
|
+
if ( value.length < 2 ) {
|
|
1535
1535
|
this.astError = AST_ERROR_OPTION_BADVALUE;
|
|
1536
1536
|
realBad = true;
|
|
1537
1537
|
}
|
|
@@ -1988,6 +1988,7 @@ export class AstFilterParser {
|
|
|
1988
1988
|
if ( parentEnd === parentBeg ) { return 0; }
|
|
1989
1989
|
const s = this.getNodeString(parent);
|
|
1990
1990
|
const optionsEnd = s.length;
|
|
1991
|
+
const parseDetails = { node: 0, len: 0 };
|
|
1991
1992
|
const head = this.allocHeadNode();
|
|
1992
1993
|
let prev = head, next = 0;
|
|
1993
1994
|
let optionBeg = 0, optionEnd = 0;
|
|
@@ -1997,11 +1998,11 @@ export class AstFilterParser {
|
|
|
1997
1998
|
parentBeg + optionBeg,
|
|
1998
1999
|
parentBeg + optionsEnd // open ended
|
|
1999
2000
|
);
|
|
2000
|
-
|
|
2001
|
+
this.parseNetOption(next, parseDetails);
|
|
2001
2002
|
// set next's end to down's end
|
|
2002
|
-
optionEnd +=
|
|
2003
|
+
optionEnd += parseDetails.len;
|
|
2003
2004
|
this.nodes[next+NODE_END_INDEX] = parentBeg + optionEnd;
|
|
2004
|
-
this.linkDown(next,
|
|
2005
|
+
this.linkDown(next, parseDetails.node);
|
|
2005
2006
|
prev = this.linkRight(prev, next);
|
|
2006
2007
|
if ( optionEnd === optionsEnd ) { break; }
|
|
2007
2008
|
optionBeg = optionEnd + 1;
|
|
@@ -2010,7 +2011,7 @@ export class AstFilterParser {
|
|
|
2010
2011
|
parentBeg + optionEnd,
|
|
2011
2012
|
parentBeg + optionBeg
|
|
2012
2013
|
);
|
|
2013
|
-
if (
|
|
2014
|
+
if ( parseDetails.len === 0 || optionBeg === optionsEnd ) {
|
|
2014
2015
|
this.addNodeFlags(next, NODE_FLAG_ERROR);
|
|
2015
2016
|
this.addFlags(AST_FLAG_HAS_ERROR);
|
|
2016
2017
|
}
|
|
@@ -2023,7 +2024,7 @@ export class AstFilterParser {
|
|
|
2023
2024
|
return this.throwHeadNode(head);
|
|
2024
2025
|
}
|
|
2025
2026
|
|
|
2026
|
-
parseNetOption(parent) {
|
|
2027
|
+
parseNetOption(parent, parseDetails) {
|
|
2027
2028
|
const parentBeg = this.nodes[parent+NODE_BEG_INDEX];
|
|
2028
2029
|
const s = this.getNodeString(parent);
|
|
2029
2030
|
const match = this.reNetOption.exec(s) || [];
|
|
@@ -2031,7 +2032,9 @@ export class AstFilterParser {
|
|
|
2031
2032
|
this.addNodeFlags(parent, NODE_FLAG_ERROR);
|
|
2032
2033
|
this.addFlags(AST_FLAG_HAS_ERROR);
|
|
2033
2034
|
this.astError = AST_ERROR_OPTION_UNKNOWN;
|
|
2034
|
-
|
|
2035
|
+
parseDetails.node = 0;
|
|
2036
|
+
parseDetails.len = s.length;
|
|
2037
|
+
return;
|
|
2035
2038
|
}
|
|
2036
2039
|
const head = this.allocHeadNode();
|
|
2037
2040
|
let prev = head, next = 0;
|
|
@@ -2073,7 +2076,9 @@ export class AstFilterParser {
|
|
|
2073
2076
|
}
|
|
2074
2077
|
prev = this.linkRight(prev, next);
|
|
2075
2078
|
if ( assigned === false ) {
|
|
2076
|
-
|
|
2079
|
+
parseDetails.node = this.throwHeadNode(head);
|
|
2080
|
+
parseDetails.len = matchEnd;
|
|
2081
|
+
return;
|
|
2077
2082
|
}
|
|
2078
2083
|
next = this.allocTypedNode(
|
|
2079
2084
|
NODE_TYPE_NET_OPTION_ASSIGN,
|
|
@@ -2129,7 +2134,8 @@ export class AstFilterParser {
|
|
|
2129
2134
|
);
|
|
2130
2135
|
this.linkRight(prev, next);
|
|
2131
2136
|
}
|
|
2132
|
-
|
|
2137
|
+
parseDetails.node = this.throwHeadNode(head);
|
|
2138
|
+
parseDetails.len = details.quoteEnd;
|
|
2133
2139
|
}
|
|
2134
2140
|
|
|
2135
2141
|
endOfNetOption(s, beg) {
|
|
@@ -2156,32 +2162,26 @@ export class AstFilterParser {
|
|
|
2156
2162
|
);
|
|
2157
2163
|
if ( parentEnd === parentBeg ) { return containerNode; }
|
|
2158
2164
|
const separatorCode = separator.charCodeAt(0);
|
|
2165
|
+
const parseDetails = { separator, mode, node: 0, len: 0 };
|
|
2159
2166
|
const listNode = this.allocHeadNode();
|
|
2160
2167
|
let prev = listNode;
|
|
2161
2168
|
let domainNode = 0;
|
|
2162
2169
|
let separatorNode = 0;
|
|
2163
2170
|
const s = this.getNodeString(parent);
|
|
2164
2171
|
const listEnd = s.length;
|
|
2165
|
-
let beg = 0, end = 0
|
|
2172
|
+
let beg = 0, end = 0;
|
|
2166
2173
|
while ( beg < listEnd ) {
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
end = s.indexOf(separator, end !== -1 ? end+1 : beg);
|
|
2176
|
-
}
|
|
2177
|
-
if ( end === -1 ) { end = listEnd; }
|
|
2174
|
+
const next = this.allocTypedNode(
|
|
2175
|
+
NODE_TYPE_OPTION_VALUE_DOMAIN_RAW,
|
|
2176
|
+
parentBeg + beg,
|
|
2177
|
+
parentBeg + listEnd // open ended
|
|
2178
|
+
);
|
|
2179
|
+
this.parseDomain(next, parseDetails);
|
|
2180
|
+
end = beg + parseDetails.len;
|
|
2181
|
+
this.nodes[next+NODE_END_INDEX] = parentBeg + end;
|
|
2178
2182
|
if ( end !== beg ) {
|
|
2179
|
-
domainNode =
|
|
2180
|
-
|
|
2181
|
-
parentBeg + beg,
|
|
2182
|
-
parentBeg + end
|
|
2183
|
-
);
|
|
2184
|
-
this.linkDown(domainNode, this.parseDomain(domainNode, mode));
|
|
2183
|
+
domainNode = next;
|
|
2184
|
+
this.linkDown(domainNode, parseDetails.node);
|
|
2185
2185
|
prev = this.linkRight(prev, domainNode);
|
|
2186
2186
|
} else {
|
|
2187
2187
|
domainNode = 0;
|
|
@@ -2217,23 +2217,38 @@ export class AstFilterParser {
|
|
|
2217
2217
|
return containerNode;
|
|
2218
2218
|
}
|
|
2219
2219
|
|
|
2220
|
-
parseDomain(parent,
|
|
2220
|
+
parseDomain(parent, parseDetails) {
|
|
2221
2221
|
const parentBeg = this.nodes[parent+NODE_BEG_INDEX];
|
|
2222
2222
|
const parentEnd = this.nodes[parent+NODE_END_INDEX];
|
|
2223
|
+
const not = this.charCodeAt(parentBeg) === 0x7E /* ~ */;
|
|
2223
2224
|
let head = 0, next = 0;
|
|
2224
2225
|
let beg = parentBeg;
|
|
2225
|
-
|
|
2226
|
-
if ( c === 0x7E /* ~ */ ) {
|
|
2226
|
+
if ( not ) {
|
|
2227
2227
|
this.addNodeFlags(parent, NODE_FLAG_IS_NEGATED);
|
|
2228
2228
|
head = this.allocTypedNode(NODE_TYPE_OPTION_VALUE_NOT, beg, beg + 1);
|
|
2229
|
-
if ( (mode & 0b1000) === 0 ) {
|
|
2229
|
+
if ( (parseDetails.mode & 0b1000) === 0 ) {
|
|
2230
2230
|
this.addNodeFlags(parent, NODE_FLAG_ERROR);
|
|
2231
2231
|
}
|
|
2232
2232
|
beg += 1;
|
|
2233
2233
|
}
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2234
|
+
const c0 = this.charCodeAt(beg);
|
|
2235
|
+
let end = beg;
|
|
2236
|
+
let type = 0;
|
|
2237
|
+
if ( c0 === 0x2F /* / */ ) {
|
|
2238
|
+
end = this.indexOf('/', beg + 1, parentEnd);
|
|
2239
|
+
if ( end !== -1 ) { end += 1; }
|
|
2240
|
+
type = 1;
|
|
2241
|
+
} else if ( c0 === 0x5B /* [ */ && this.startsWith('[$domain=/', beg) ) {
|
|
2242
|
+
end = this.indexOf('/]', beg + 10, parentEnd);
|
|
2243
|
+
if ( end !== -1 ) { end += 2; }
|
|
2244
|
+
type = 2;
|
|
2245
|
+
} else {
|
|
2246
|
+
end = this.indexOf(parseDetails.separator, end, parentEnd);
|
|
2247
|
+
}
|
|
2248
|
+
if ( end === -1 ) { end = parentEnd; }
|
|
2249
|
+
if ( beg !== end ) {
|
|
2250
|
+
next = this.allocTypedNode(NODE_TYPE_OPTION_VALUE_DOMAIN, beg, end);
|
|
2251
|
+
const hn = this.normalizeDomainValue(next, type, parseDetails.mode);
|
|
2237
2252
|
if ( hn !== undefined ) {
|
|
2238
2253
|
if ( hn !== '' ) {
|
|
2239
2254
|
this.setNodeTransform(next, hn);
|
|
@@ -2252,7 +2267,8 @@ export class AstFilterParser {
|
|
|
2252
2267
|
this.addNodeFlags(parent, NODE_FLAG_ERROR);
|
|
2253
2268
|
this.addFlags(AST_FLAG_HAS_ERROR);
|
|
2254
2269
|
}
|
|
2255
|
-
|
|
2270
|
+
parseDetails.node = head;
|
|
2271
|
+
parseDetails.len = end - parentBeg;
|
|
2256
2272
|
}
|
|
2257
2273
|
|
|
2258
2274
|
// mode bits:
|
|
@@ -2261,16 +2277,16 @@ export class AstFilterParser {
|
|
|
2261
2277
|
// 0b00100: can use single wildcard
|
|
2262
2278
|
// 0b01000: can be negated
|
|
2263
2279
|
// 0b10000: can be a regex
|
|
2264
|
-
normalizeDomainValue(
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
s.charCodeAt(0) !== 0x2F /* / */ ||
|
|
2268
|
-
exCharCodeAt(s, -1) !== 0x2F /* / */
|
|
2269
|
-
) {
|
|
2280
|
+
normalizeDomainValue(node, type, modeBits) {
|
|
2281
|
+
const s = this.getNodeString(node);
|
|
2282
|
+
if ( type === 0 ) {
|
|
2270
2283
|
return this.normalizeHostnameValue(s, modeBits);
|
|
2271
2284
|
}
|
|
2272
|
-
|
|
2285
|
+
if ( (modeBits & 0b10000) === 0 ) { return ''; }
|
|
2286
|
+
const regex = type === 1 ? s : `/${s.slice(10, -2)}/`;
|
|
2287
|
+
const source = this.normalizeRegexPattern(regex);
|
|
2273
2288
|
if ( source === '' ) { return ''; }
|
|
2289
|
+
if ( type === 1 && source === regex ) { return; }
|
|
2274
2290
|
return `/${source}/`;
|
|
2275
2291
|
}
|
|
2276
2292
|
|
|
@@ -2857,6 +2873,15 @@ export class AstFilterParser {
|
|
|
2857
2873
|
return pos < this.rawEnd ? this.raw.charCodeAt(pos) : -1;
|
|
2858
2874
|
}
|
|
2859
2875
|
|
|
2876
|
+
indexOf(needle, beg, end = 0) {
|
|
2877
|
+
const haystack = end === 0 ? this.raw : this.raw.slice(0, end);
|
|
2878
|
+
return haystack.indexOf(needle, beg);
|
|
2879
|
+
}
|
|
2880
|
+
|
|
2881
|
+
startsWith(s, pos) {
|
|
2882
|
+
return pos < this.rawEnd && this.raw.startsWith(s, pos);
|
|
2883
|
+
}
|
|
2884
|
+
|
|
2860
2885
|
isTokenCharCode(c) {
|
|
2861
2886
|
return c === 0x25 ||
|
|
2862
2887
|
c >= 0x30 && c <= 0x39 ||
|
|
@@ -4116,9 +4141,11 @@ class ExtSelectorCompiler {
|
|
|
4116
4141
|
compileXpathExpression(s) {
|
|
4117
4142
|
const r = this.unquoteString(s);
|
|
4118
4143
|
if ( r.i !== s.length ) { return; }
|
|
4119
|
-
|
|
4144
|
+
const doc = globalThis.document;
|
|
4145
|
+
if ( doc instanceof Object === false ) { return r.s; }
|
|
4120
4146
|
try {
|
|
4121
|
-
|
|
4147
|
+
const expr = doc.createExpression(r.s, null);
|
|
4148
|
+
expr.evaluate(doc, XPathResult.ANY_UNORDERED_NODE_TYPE);
|
|
4122
4149
|
} catch (e) {
|
|
4123
4150
|
return;
|
|
4124
4151
|
}
|
|
@@ -4362,7 +4389,7 @@ export const utils = (( ) => {
|
|
|
4362
4389
|
// only ABP.
|
|
4363
4390
|
[ 'ext_abp', 'false' ],
|
|
4364
4391
|
// Compatibility with other blockers
|
|
4365
|
-
// https://
|
|
4392
|
+
// https://adguard.com/kb/general/ad-filtering/create-own-filters/#conditions-directive
|
|
4366
4393
|
[ 'adguard', 'adguard' ],
|
|
4367
4394
|
[ 'adguard_app_android', 'false' ],
|
|
4368
4395
|
[ 'adguard_app_ios', 'false' ],
|
|
@@ -4430,14 +4457,14 @@ export const utils = (( ) => {
|
|
|
4430
4457
|
const parts = [ 0 ];
|
|
4431
4458
|
let discard = false;
|
|
4432
4459
|
|
|
4433
|
-
const shouldDiscard = ( ) => stack.some(v => v);
|
|
4460
|
+
const shouldDiscard = ( ) => stack.some(v => v.known && v.discard);
|
|
4434
4461
|
|
|
4435
|
-
const begif =
|
|
4436
|
-
if ( discard === false &&
|
|
4437
|
-
parts.push(
|
|
4462
|
+
const begif = details => {
|
|
4463
|
+
if ( discard === false && details.known && details.discard ) {
|
|
4464
|
+
parts.push(details.pos);
|
|
4438
4465
|
discard = true;
|
|
4439
4466
|
}
|
|
4440
|
-
stack.push(
|
|
4467
|
+
stack.push(details);
|
|
4441
4468
|
};
|
|
4442
4469
|
|
|
4443
4470
|
const endif = match => {
|
|
@@ -4455,15 +4482,21 @@ export const utils = (( ) => {
|
|
|
4455
4482
|
|
|
4456
4483
|
switch ( match[1] ) {
|
|
4457
4484
|
case 'if': {
|
|
4458
|
-
const
|
|
4459
|
-
begif(
|
|
4485
|
+
const result = this.evaluateExpr(match[2].trim(), env);
|
|
4486
|
+
begif({
|
|
4487
|
+
known: result !== undefined,
|
|
4488
|
+
discard: result === false,
|
|
4489
|
+
pos: match.index,
|
|
4490
|
+
});
|
|
4460
4491
|
break;
|
|
4461
4492
|
}
|
|
4462
4493
|
case 'else': {
|
|
4463
4494
|
if ( stack.length === 0 ) { break; }
|
|
4464
|
-
const
|
|
4495
|
+
const details = stack[stack.length-1];
|
|
4465
4496
|
endif(match);
|
|
4466
|
-
|
|
4497
|
+
details.discard = details.discard === false;
|
|
4498
|
+
details.pos = match.index;
|
|
4499
|
+
begif(details);
|
|
4467
4500
|
break;
|
|
4468
4501
|
}
|
|
4469
4502
|
case 'endif': {
|
|
@@ -3048,9 +3048,6 @@ class FilterIPAddress {
|
|
|
3048
3048
|
if ( ipaddr.startsWith('::ffff:') === false ) { return false; }
|
|
3049
3049
|
return this.reIPv6IPv4lan.test(ipaddr);
|
|
3050
3050
|
}
|
|
3051
|
-
if ( c0 === 0x36 /* 6 */ ) {
|
|
3052
|
-
return ipaddr.startsWith('64:ff9b:');
|
|
3053
|
-
}
|
|
3054
3051
|
if ( c0 === 0x66 /* f */ ) {
|
|
3055
3052
|
return this.reIPv6local.test(ipaddr);
|
|
3056
3053
|
}
|
|
@@ -4789,20 +4786,13 @@ StaticNetFilteringEngine.prototype.toSelfie = function() {
|
|
|
4789
4786
|
};
|
|
4790
4787
|
};
|
|
4791
4788
|
|
|
4792
|
-
StaticNetFilteringEngine.prototype.serialize =
|
|
4793
|
-
|
|
4794
|
-
const storage = {
|
|
4795
|
-
put(name, data) {
|
|
4796
|
-
selfie.push([ name, data ]);
|
|
4797
|
-
}
|
|
4798
|
-
};
|
|
4799
|
-
await this.toSelfie(storage, '');
|
|
4800
|
-
return JSON.stringify(selfie);
|
|
4789
|
+
StaticNetFilteringEngine.prototype.serialize = function() {
|
|
4790
|
+
return this.toSelfie();
|
|
4801
4791
|
};
|
|
4802
4792
|
|
|
4803
4793
|
/******************************************************************************/
|
|
4804
4794
|
|
|
4805
|
-
StaticNetFilteringEngine.prototype.fromSelfie =
|
|
4795
|
+
StaticNetFilteringEngine.prototype.fromSelfie = function(selfie) {
|
|
4806
4796
|
if ( typeof selfie !== 'object' || selfie === null ) { return; }
|
|
4807
4797
|
|
|
4808
4798
|
this.reset();
|
|
@@ -4835,14 +4825,8 @@ StaticNetFilteringEngine.prototype.fromSelfie = async function(selfie) {
|
|
|
4835
4825
|
return true;
|
|
4836
4826
|
};
|
|
4837
4827
|
|
|
4838
|
-
StaticNetFilteringEngine.prototype.unserialize =
|
|
4839
|
-
|
|
4840
|
-
const storage = {
|
|
4841
|
-
async get(name) {
|
|
4842
|
-
return { content: selfie.get(name) };
|
|
4843
|
-
}
|
|
4844
|
-
};
|
|
4845
|
-
return this.fromSelfie(storage, '');
|
|
4828
|
+
StaticNetFilteringEngine.prototype.unserialize = function(selfie) {
|
|
4829
|
+
return this.fromSelfie(selfie);
|
|
4846
4830
|
};
|
|
4847
4831
|
|
|
4848
4832
|
/******************************************************************************/
|
|
@@ -5369,12 +5353,10 @@ StaticNetFilteringEngine.prototype.transformRequest = function(fctxt, out = [])
|
|
|
5369
5353
|
out.push(directive);
|
|
5370
5354
|
continue;
|
|
5371
5355
|
}
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
if ( refs.$cache === null ) {
|
|
5375
|
-
refs.$cache = sfp.parseReplaceValue(refs.value);
|
|
5356
|
+
if ( directive.cache === null ) {
|
|
5357
|
+
directive.cache = sfp.parseReplaceValue(directive.value);
|
|
5376
5358
|
}
|
|
5377
|
-
const cache =
|
|
5359
|
+
const cache = directive.cache;
|
|
5378
5360
|
if ( cache === undefined ) { continue; }
|
|
5379
5361
|
const before = `${redirectURL.pathname}${redirectURL.search}${redirectURL.hash}`;
|
|
5380
5362
|
if ( cache.re.test(before) !== true ) { continue; }
|
|
@@ -5395,9 +5377,60 @@ StaticNetFilteringEngine.prototype.transformRequest = function(fctxt, out = [])
|
|
|
5395
5377
|
return out;
|
|
5396
5378
|
};
|
|
5397
5379
|
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
5380
|
+
/**
|
|
5381
|
+
* @trustedOption urlskip
|
|
5382
|
+
*
|
|
5383
|
+
* @description
|
|
5384
|
+
* Extract a URL from another URL according to one or more transformation steps,
|
|
5385
|
+
* thereby skipping over intermediate network request(s) to remote servers.
|
|
5386
|
+
* Requires a trusted source.
|
|
5387
|
+
*
|
|
5388
|
+
* @param steps
|
|
5389
|
+
* A serie of space-separated directives representing the transformation steps
|
|
5390
|
+
* to perform to extract the final URL to which a network request should be
|
|
5391
|
+
* redirected.
|
|
5392
|
+
*
|
|
5393
|
+
* Supported directives:
|
|
5394
|
+
*
|
|
5395
|
+
* `?name`: extract the value of parameter `name` as the current string.
|
|
5396
|
+
*
|
|
5397
|
+
* `&i`: extract the name of the parameter at position `i` as the current
|
|
5398
|
+
* string. The position is 1-based.
|
|
5399
|
+
*
|
|
5400
|
+
* `/.../`: extract the first capture group of a regex as the current string.
|
|
5401
|
+
*
|
|
5402
|
+
* `+https`: prepend the current string with `https://`.
|
|
5403
|
+
*
|
|
5404
|
+
* `-base64`: decode the current string as a base64-encoded string.
|
|
5405
|
+
*
|
|
5406
|
+
* `-uricomponent`: decode the current string as a URI encoded string.
|
|
5407
|
+
*
|
|
5408
|
+
* `-blocked`: allow the redirection of blocked requests. By default, blocked
|
|
5409
|
+
* requests can't by urlskip'ed.
|
|
5410
|
+
*
|
|
5411
|
+
* At any given step, the currently extracted string may not necessarily be
|
|
5412
|
+
* a valid URL, and more transformation steps may be needed to obtain a valid
|
|
5413
|
+
* URL once all the steps are applied.
|
|
5414
|
+
*
|
|
5415
|
+
* An unsupported step or a failed step will abort the transformation and no
|
|
5416
|
+
* redirection will be performed.
|
|
5417
|
+
*
|
|
5418
|
+
* The final step is expected to yield a valid URL. If the result is not a
|
|
5419
|
+
* valid URL, no redirection will be performed.
|
|
5420
|
+
*
|
|
5421
|
+
* @example
|
|
5422
|
+
* ||example.com/path/to/tracker$urlskip=?url
|
|
5423
|
+
* ||example.com/path/to/tracker$urlskip=?url ?to
|
|
5424
|
+
* ||pixiv.net/jump.php?$urlskip=&1
|
|
5425
|
+
* ||podtrac.com/pts/redirect.mp3/$urlskip=/\/redirect\.mp3\/(.*?\.mp3\b)/ +https
|
|
5426
|
+
*
|
|
5427
|
+
* */
|
|
5428
|
+
|
|
5429
|
+
StaticNetFilteringEngine.prototype.urlSkip = function(
|
|
5430
|
+
fctxt,
|
|
5431
|
+
blocked,
|
|
5432
|
+
out = []
|
|
5433
|
+
) {
|
|
5401
5434
|
if ( fctxt.redirectURL !== undefined ) { return; }
|
|
5402
5435
|
const directives = this.matchAndFetchModifiers(fctxt, 'urlskip');
|
|
5403
5436
|
if ( directives === undefined ) { return; }
|
|
@@ -5409,7 +5442,7 @@ StaticNetFilteringEngine.prototype.urlSkip = function(fctxt, out = []) {
|
|
|
5409
5442
|
const urlin = fctxt.url;
|
|
5410
5443
|
const value = directive.value;
|
|
5411
5444
|
const steps = value.includes(' ') && value.split(/ +/) || [ value ];
|
|
5412
|
-
const urlout = urlSkip(urlin, steps);
|
|
5445
|
+
const urlout = urlSkip(directive, urlin, blocked, steps);
|
|
5413
5446
|
if ( urlout === undefined ) { continue; }
|
|
5414
5447
|
if ( urlout === urlin ) { continue; }
|
|
5415
5448
|
fctxt.redirectURL = urlout;
|
|
@@ -5420,31 +5453,74 @@ StaticNetFilteringEngine.prototype.urlSkip = function(fctxt, out = []) {
|
|
|
5420
5453
|
return out;
|
|
5421
5454
|
};
|
|
5422
5455
|
|
|
5423
|
-
function urlSkip(
|
|
5456
|
+
function urlSkip(directive, url, blocked, steps) {
|
|
5424
5457
|
try {
|
|
5425
|
-
let
|
|
5458
|
+
let redirectBlocked = false;
|
|
5459
|
+
let urlout = url;
|
|
5426
5460
|
for ( const step of steps ) {
|
|
5461
|
+
const urlin = urlout;
|
|
5462
|
+
const c0 = step.charCodeAt(0);
|
|
5463
|
+
// Extract from URL parameter name at position i
|
|
5464
|
+
if ( c0 === 0x26 ) { // &
|
|
5465
|
+
const i = (parseInt(step.slice(1)) || 0) - 1;
|
|
5466
|
+
if ( i < 0 ) { return; }
|
|
5467
|
+
const url = new URL(urlin);
|
|
5468
|
+
if ( i >= url.searchParams.size ) { return; }
|
|
5469
|
+
const params = Array.from(url.searchParams.keys());
|
|
5470
|
+
urlout = decodeURIComponent(params[i]);
|
|
5471
|
+
continue;
|
|
5472
|
+
}
|
|
5473
|
+
// Enforce https
|
|
5474
|
+
if ( c0 === 0x2B && step === '+https' ) {
|
|
5475
|
+
const s = urlin.replace(/^https?:\/\//, '');
|
|
5476
|
+
if ( /^[\w-]:\/\//.test(s) ) { return; }
|
|
5477
|
+
urlout = `https://${s}`;
|
|
5478
|
+
continue;
|
|
5479
|
+
}
|
|
5480
|
+
// Decode
|
|
5481
|
+
if ( c0 === 0x2D ) {
|
|
5482
|
+
// Base64
|
|
5483
|
+
if ( step === '-base64' ) {
|
|
5484
|
+
urlout = self.atob(urlin);
|
|
5485
|
+
continue;
|
|
5486
|
+
}
|
|
5487
|
+
// URI component
|
|
5488
|
+
if ( step === '-uricomponent' ) {
|
|
5489
|
+
urlout = self.decodeURIComponent(urlin);
|
|
5490
|
+
continue;
|
|
5491
|
+
}
|
|
5492
|
+
// Enable skip of blocked requests
|
|
5493
|
+
if ( step === '-blocked' ) {
|
|
5494
|
+
redirectBlocked = true;
|
|
5495
|
+
continue;
|
|
5496
|
+
}
|
|
5497
|
+
}
|
|
5498
|
+
// Regex extraction from first capture group
|
|
5499
|
+
if ( c0 === 0x2F ) { // /
|
|
5500
|
+
if ( directive.cache === null ) {
|
|
5501
|
+
directive.cache = new RegExp(step.slice(1, -1));
|
|
5502
|
+
}
|
|
5503
|
+
const match = directive.cache.exec(urlin);
|
|
5504
|
+
if ( match === null ) { return; }
|
|
5505
|
+
if ( match.length <= 1 ) { return; }
|
|
5506
|
+
urlout = match[1];
|
|
5507
|
+
continue;
|
|
5508
|
+
}
|
|
5427
5509
|
// Extract from URL parameter
|
|
5428
|
-
if (
|
|
5510
|
+
if ( c0 === 0x3F ) { // ?
|
|
5429
5511
|
urlout = (new URL(urlin)).searchParams.get(step.slice(1));
|
|
5430
5512
|
if ( urlout === null ) { return; }
|
|
5431
5513
|
if ( urlout.includes(' ') ) {
|
|
5432
5514
|
urlout = urlout.replace(/ /g, '%20');
|
|
5433
5515
|
}
|
|
5434
|
-
urlin = urlout;
|
|
5435
|
-
continue;
|
|
5436
|
-
}
|
|
5437
|
-
// Enforce https
|
|
5438
|
-
if ( step === '+https' ) {
|
|
5439
|
-
const s = urlin.replace(/^https?:\/\//, '');
|
|
5440
|
-
if ( /^[\w-]:\/\//.test(s) ) { return; }
|
|
5441
|
-
urlin = urlout = `https://${s}`;
|
|
5442
5516
|
continue;
|
|
5443
5517
|
}
|
|
5444
5518
|
// Unknown directive
|
|
5445
5519
|
return;
|
|
5446
5520
|
}
|
|
5447
|
-
|
|
5521
|
+
const urlfinal = new URL(urlout);
|
|
5522
|
+
if ( urlfinal.protocol !== 'https:' ) { return; }
|
|
5523
|
+
if ( blocked && redirectBlocked !== true ) { return; }
|
|
5448
5524
|
return urlout;
|
|
5449
5525
|
} catch(x) {
|
|
5450
5526
|
}
|
|
@@ -196,8 +196,9 @@ const onBeforeRootFrameRequest = function(fctxt) {
|
|
|
196
196
|
if ( trusted === false && pageStore !== null ) {
|
|
197
197
|
if ( result !== 1 ) {
|
|
198
198
|
pageStore.redirectNonBlockedRequest(fctxt);
|
|
199
|
+
} else {
|
|
200
|
+
pageStore.skipMainDocument(fctxt, true);
|
|
199
201
|
}
|
|
200
|
-
pageStore.skipMainDocument(fctxt);
|
|
201
202
|
}
|
|
202
203
|
|
|
203
204
|
if ( logger.enabled ) {
|
|
@@ -215,16 +216,20 @@ const onBeforeRootFrameRequest = function(fctxt) {
|
|
|
215
216
|
if ( result !== 1 ) { return; }
|
|
216
217
|
|
|
217
218
|
// No log data means no strict blocking (because we need to report why
|
|
218
|
-
// the blocking occurs
|
|
219
|
+
// the blocking occurs
|
|
219
220
|
if ( logData === undefined ) { return; }
|
|
220
221
|
|
|
221
222
|
// Blocked
|
|
222
223
|
|
|
224
|
+
// Find out the URL navigated to should the document not be strict-blocked
|
|
225
|
+
pageStore.skipMainDocument(fctxt, false);
|
|
226
|
+
|
|
223
227
|
const query = encodeURIComponent(JSON.stringify({
|
|
224
228
|
url: requestURL,
|
|
225
|
-
hn: requestHostname,
|
|
226
229
|
dn: fctxt.getDomain() || requestHostname,
|
|
227
|
-
fs: logData.raw
|
|
230
|
+
fs: logData.raw,
|
|
231
|
+
hn: requestHostname,
|
|
232
|
+
to: fctxt.redirectURL || '',
|
|
228
233
|
}));
|
|
229
234
|
|
|
230
235
|
vAPI.tabs.replace(
|
|
@@ -488,7 +493,7 @@ const onHeadersReceived = function(details) {
|
|
|
488
493
|
}
|
|
489
494
|
if ( pageStore.getNetFilteringSwitch(fctxt) === false ) { return; }
|
|
490
495
|
|
|
491
|
-
if ( fctxt.itype
|
|
496
|
+
if ( (fctxt.itype & foilLargeMediaElement.TYPE_BITS) !== 0 ) {
|
|
492
497
|
const result = foilLargeMediaElement(details, fctxt, pageStore);
|
|
493
498
|
if ( result !== undefined ) { return result; }
|
|
494
499
|
}
|
|
@@ -1124,15 +1129,12 @@ const injectPP = function(fctxt, pageStore, responseHeaders) {
|
|
|
1124
1129
|
const foilLargeMediaElement = function(details, fctxt, pageStore) {
|
|
1125
1130
|
if ( details.fromCache === true ) { return; }
|
|
1126
1131
|
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
size = parseInt(headers[i].value, 10) || 0;
|
|
1133
|
-
}
|
|
1132
|
+
onDemandHeaders.setHeaders(details.responseHeaders);
|
|
1133
|
+
|
|
1134
|
+
const result = pageStore.filterLargeMediaElement(fctxt, onDemandHeaders);
|
|
1135
|
+
|
|
1136
|
+
onDemandHeaders.reset();
|
|
1134
1137
|
|
|
1135
|
-
const result = pageStore.filterLargeMediaElement(fctxt, size);
|
|
1136
1138
|
if ( result === 0 ) { return; }
|
|
1137
1139
|
|
|
1138
1140
|
if ( logger.enabled ) {
|
|
@@ -1142,16 +1144,15 @@ const foilLargeMediaElement = function(details, fctxt, pageStore) {
|
|
|
1142
1144
|
return { cancel: true };
|
|
1143
1145
|
};
|
|
1144
1146
|
|
|
1147
|
+
foilLargeMediaElement.TYPE_BITS = fc.IMAGE | fc.MEDIA | fc.XMLHTTPREQUEST;
|
|
1148
|
+
|
|
1145
1149
|
/******************************************************************************/
|
|
1146
1150
|
|
|
1147
1151
|
// Caller must ensure headerName is normalized to lower case.
|
|
1148
1152
|
|
|
1149
1153
|
const headerIndexFromName = function(headerName, headers) {
|
|
1150
|
-
let i = headers.length;
|
|
1151
|
-
|
|
1152
|
-
if ( headers[i].name.toLowerCase() === headerName ) {
|
|
1153
|
-
return i;
|
|
1154
|
-
}
|
|
1154
|
+
for ( let i = 0, n = headers.length; i < n; i++ ) {
|
|
1155
|
+
if ( headers[i].name.toLowerCase() === headerName ) { return i; }
|
|
1155
1156
|
}
|
|
1156
1157
|
return -1;
|
|
1157
1158
|
};
|
|
@@ -1161,6 +1162,24 @@ const headerValueFromName = function(headerName, headers) {
|
|
|
1161
1162
|
return i !== -1 ? headers[i].value : '';
|
|
1162
1163
|
};
|
|
1163
1164
|
|
|
1165
|
+
const onDemandHeaders = {
|
|
1166
|
+
headers: [],
|
|
1167
|
+
get contentLength() {
|
|
1168
|
+
const contentLength = headerValueFromName('content-length', this.headers);
|
|
1169
|
+
if ( contentLength === '' ) { return Number.NaN; }
|
|
1170
|
+
return parseInt(contentLength, 10) || 0;
|
|
1171
|
+
},
|
|
1172
|
+
get contentType() {
|
|
1173
|
+
return headerValueFromName('content-type', this.headers);
|
|
1174
|
+
},
|
|
1175
|
+
setHeaders(headers) {
|
|
1176
|
+
this.headers = headers;
|
|
1177
|
+
},
|
|
1178
|
+
reset() {
|
|
1179
|
+
this.headers = [];
|
|
1180
|
+
}
|
|
1181
|
+
};
|
|
1182
|
+
|
|
1164
1183
|
/******************************************************************************/
|
|
1165
1184
|
|
|
1166
1185
|
const strictBlockBypasser = {
|