Skip to content

Commit 6327aae

Browse files
committed
Add support to strict-block from ipaddress= option
As discussed with filter list maintainers.
1 parent 31cd8b3 commit 6327aae

File tree

2 files changed

+53
-53
lines changed

2 files changed

+53
-53
lines changed

platform/common/vapi-common.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,11 @@ vAPI.webextFlavor = {
178178
soup.add('native_css_has');
179179
}
180180

181+
const extensionOrigin = browser.runtime.getURL('');
182+
181183
// Order of tests is important
182-
if ( browser.runtime.getURL('').startsWith('moz-extension://') ) {
184+
flavor.isGecko = extensionOrigin.startsWith('moz-extension://');
185+
if ( flavor.isGecko ) {
183186
soup.add('firefox')
184187
.add('user_stylesheet')
185188
.add('html_filtering');

src/js/traffic.js

Lines changed: 49 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -39,20 +39,8 @@ import µb from './background.js';
3939

4040
/******************************************************************************/
4141

42-
// Platform-specific behavior.
43-
44-
// https://github.com/uBlockOrigin/uBlock-issues/issues/42
45-
// https://bugzilla.mozilla.org/show_bug.cgi?id=1376932
46-
// Add proper version number detection once issue is fixed in Firefox.
47-
let dontCacheResponseHeaders =
48-
vAPI.webextFlavor.soup.has('firefox');
49-
50-
// The real actual webextFlavor value may not be set in stone, so listen
51-
// for possible future changes.
52-
window.addEventListener('webextFlavor', function() {
53-
dontCacheResponseHeaders =
54-
vAPI.webextFlavor.soup.has('firefox');
55-
}, { once: true });
42+
// For platform-specific behavior.
43+
const isGecko = vAPI.webextFlavor.isGecko;
5644

5745
/******************************************************************************/
5846

@@ -64,7 +52,7 @@ const patchLocalRedirectURL = url => url.charCodeAt(0) === 0x2F /* '/' */
6452

6553
// Intercept and filter web requests.
6654

67-
const onBeforeRequest = function(details) {
55+
function onBeforeRequest(details) {
6856
const fctxt = µb.filteringContext.fromWebrequestDetails(details);
6957

7058
// Special handling for root document.
@@ -248,7 +236,7 @@ const onBeforeRootFrameRequest = function(fctxt) {
248236
);
249237

250238
return { cancel: true };
251-
};
239+
}
252240

253241
/******************************************************************************/
254242

@@ -278,7 +266,7 @@ const onBeforeRootFrameRequest = function(fctxt) {
278266
// | 2 | rg | rg | rs | rs |
279267
// --------+--------+--------+--------+--------+--------+
280268

281-
const shouldStrictBlock = function(fctxt, loggerEnabled) {
269+
function shouldStrictBlock(fctxt, loggerEnabled) {
282270
const snfe = staticNetFilteringEngine;
283271

284272
// Explicit filtering: `document` option
@@ -338,7 +326,7 @@ const shouldStrictBlock = function(fctxt, loggerEnabled) {
338326
// | 2 | - | - | - | x |
339327
// --------+--------+--------+--------+--------+--------+
340328
return { result: rs, logData: lds };
341-
};
329+
}
342330

343331
/******************************************************************************/
344332

@@ -348,7 +336,7 @@ const shouldStrictBlock = function(fctxt, loggerEnabled) {
348336
// Do not strict-block if the filter pattern does not contain at least one
349337
// token character.
350338

351-
const validateStrictBlock = function(fctxt, logData) {
339+
function validateStrictBlock(fctxt, logData) {
352340
if ( typeof logData.regex !== 'string' ) { return false; }
353341
if ( typeof logData.raw === 'string' && /\w/.test(logData.raw) === false ) {
354342
return false;
@@ -370,13 +358,13 @@ const validateStrictBlock = function(fctxt, logData) {
370358
const end = match.index + match[0].length - hnpos - hnlen;
371359
return end === 0 || end === 1 ||
372360
end === 2 && url.charCodeAt(hnpos + hnlen) === 0x2E /* '.' */;
373-
};
361+
}
374362

375363
/******************************************************************************/
376364

377365
// Intercept and filter behind-the-scene requests.
378366

379-
const onBeforeBehindTheSceneRequest = function(fctxt) {
367+
function onBeforeBehindTheSceneRequest(fctxt) {
380368
const pageStore = µb.pageStoreFromTabId(fctxt.tabId);
381369
if ( pageStore === null ) { return; }
382370

@@ -436,7 +424,7 @@ const onBeforeBehindTheSceneRequest = function(fctxt) {
436424
if ( result === 1 ) {
437425
return { cancel: true };
438426
}
439-
};
427+
}
440428

441429
// https://github.com/uBlockOrigin/uBlock-issues/issues/1204
442430
// Report the tabless network requests to all page stores matching the
@@ -491,7 +479,7 @@ const onBeforeBehindTheSceneRequest = function(fctxt) {
491479
// - HTML filtering (requires ability to modify response body)
492480
// - CSP injection
493481

494-
const onHeadersReceived = function(details) {
482+
function onHeadersReceived(details) {
495483

496484
const fctxt = µb.filteringContext.fromWebrequestDetails(details);
497485
const isRootDoc = fctxt.itype === fctxt.MAIN_FRAME;
@@ -503,6 +491,12 @@ const onHeadersReceived = function(details) {
503491
}
504492
if ( pageStore.getNetFilteringSwitch(fctxt) === false ) { return; }
505493

494+
// To enforce strict-blocking with ipaddress option
495+
if ( isRootDoc && fctxt.ipaddress ) {
496+
const r = onBeforeRootFrameRequest(fctxt);
497+
if ( r ) { return ( r ); }
498+
}
499+
506500
if ( (fctxt.itype & foilLargeMediaElement.TYPE_BITS) !== 0 ) {
507501
const result = foilLargeMediaElement(details, fctxt, pageStore);
508502
if ( result !== undefined ) { return result; }
@@ -589,7 +583,7 @@ const onHeadersReceived = function(details) {
589583
// https://github.com/uBlockOrigin/uBlock-issues/issues/229
590584
// Use `no-cache` instead of `no-cache, no-store, must-revalidate`, this
591585
// allows Firefox's offline mode to work as expected.
592-
if ( modifiedHeaders && dontCacheResponseHeaders ) {
586+
if ( modifiedHeaders && isGecko ) {
593587
const cacheControl = µb.hiddenSettings.cacheControlForFirefox1376932;
594588
if ( cacheControl !== 'unset' ) {
595589
let i = headerIndexFromName('cache-control', responseHeaders);
@@ -605,7 +599,7 @@ const onHeadersReceived = function(details) {
605599
if ( modifiedHeaders ) {
606600
return { responseHeaders };
607601
}
608-
};
602+
}
609603

610604
const reMediaContentTypes = /^(?:audio|image|video)\/|(?:\/ogg)$/;
611605

@@ -1011,7 +1005,7 @@ const bodyFilterer = (( ) => {
10111005

10121006
/******************************************************************************/
10131007

1014-
const injectCSP = function(fctxt, pageStore, responseHeaders) {
1008+
function injectCSP(fctxt, pageStore, responseHeaders) {
10151009
const cspSubsets = [];
10161010
const requestType = fctxt.type;
10171011

@@ -1138,11 +1132,11 @@ const injectCSP = function(fctxt, pageStore, responseHeaders) {
11381132
});
11391133

11401134
return true;
1141-
};
1135+
}
11421136

11431137
/******************************************************************************/
11441138

1145-
const injectPP = function(fctxt, pageStore, responseHeaders) {
1139+
function injectPP(fctxt, pageStore, responseHeaders) {
11461140
const permissions = [];
11471141
const directives = staticNetFilteringEngine.matchAndFetchModifiers(fctxt, 'permissions');
11481142
if ( directives !== undefined ) {
@@ -1168,7 +1162,7 @@ const injectPP = function(fctxt, pageStore, responseHeaders) {
11681162
});
11691163

11701164
return true;
1171-
};
1165+
}
11721166

11731167
/******************************************************************************/
11741168

@@ -1179,7 +1173,7 @@ const injectPP = function(fctxt, pageStore, responseHeaders) {
11791173
// cache. This works only when the webext API supports the `fromCache`
11801174
// property (Firefox).
11811175

1182-
const foilLargeMediaElement = function(details, fctxt, pageStore) {
1176+
function foilLargeMediaElement(details, fctxt, pageStore) {
11831177
if ( details.fromCache === true ) { return; }
11841178

11851179
onDemandHeaders.setHeaders(details.responseHeaders);
@@ -1195,7 +1189,7 @@ const foilLargeMediaElement = function(details, fctxt, pageStore) {
11951189
}
11961190

11971191
return { cancel: true };
1198-
};
1192+
}
11991193

12001194
foilLargeMediaElement.TYPE_BITS = fc.IMAGE | fc.MEDIA | fc.XMLHTTPREQUEST;
12011195

@@ -1280,6 +1274,23 @@ const strictBlockBypasser = {
12801274

12811275
/******************************************************************************/
12821276

1277+
function onResponseStarted(details) {
1278+
if ( details.tabId === -1 ) { return; }
1279+
const pageStore = µb.pageStoreFromTabId(details.tabId);
1280+
if ( pageStore === null ) { return; }
1281+
if ( pageStore.getNetFilteringSwitch() === false ) { return; }
1282+
// To enforce strict-blocking with ipaddress option
1283+
if ( isGecko === false && details.type === 'main_frame' ) {
1284+
const fctxt = µb.filteringContext.fromWebrequestDetails(details);
1285+
const r = onBeforeRootFrameRequest(fctxt);
1286+
if ( r?.cancel ) { return; }
1287+
}
1288+
details.ancestors = pageStore.getFrameAncestorDetails(details.frameId);
1289+
scriptletFilteringEngine.injectNow(details);
1290+
}
1291+
1292+
/******************************************************************************/
1293+
12831294
// https://github.com/uBlockOrigin/uBlock-issues/issues/2350
12841295
// Added scriptlet injection attempt at onResponseStarted time as per
12851296
// https://github.com/AdguardTeam/AdguardBrowserExtension/issues/1029 and
@@ -1296,27 +1307,13 @@ const webRequest = {
12961307

12971308
return ( ) => {
12981309
vAPI.net.setSuspendableListener(onBeforeRequest);
1299-
vAPI.net.addListener(
1300-
'onHeadersReceived',
1301-
onHeadersReceived,
1302-
{ urls: [ 'http://*/*', 'https://*/*' ] },
1303-
[ 'blocking', 'responseHeaders' ]
1304-
);
1305-
vAPI.net.addListener(
1306-
'onResponseStarted',
1307-
details => {
1308-
if ( details.tabId === -1 ) { return; }
1309-
const pageStore = µb.pageStoreFromTabId(details.tabId);
1310-
if ( pageStore === null ) { return; }
1311-
if ( pageStore.getNetFilteringSwitch() === false ) { return; }
1312-
details.ancestors = pageStore.getFrameAncestorDetails(details.frameId);
1313-
scriptletFilteringEngine.injectNow(details);
1314-
},
1315-
{
1316-
types: [ 'main_frame', 'sub_frame' ],
1317-
urls: [ 'http://*/*', 'https://*/*' ]
1318-
}
1319-
);
1310+
vAPI.net.addListener('onHeadersReceived', onHeadersReceived, {
1311+
urls: [ 'http://*/*', 'https://*/*' ]
1312+
}, [ 'blocking', 'responseHeaders' ]);
1313+
vAPI.net.addListener('onResponseStarted', onResponseStarted, {
1314+
types: [ 'main_frame', 'sub_frame' ],
1315+
urls: [ 'http://*/*', 'https://*/*' ]
1316+
});
13201317
vAPI.defer.once({ sec: µb.hiddenSettings.toolbarWarningTimeout }).then(( ) => {
13211318
if ( vAPI.net.hasUnprocessedRequest() === false ) { return; }
13221319
vAPI.net.removeUnprocessedRequest();

0 commit comments

Comments
 (0)