Skip to content

Commit aebc108

Browse files
committed
Add support for network filter option top=
This allows to match against the hostname of the top-most context, which usually is the URL in the address bar of the browser. Related issue/discussion: - uBlockOrigin/uBlock-issues#3151 - uBlockOrigin/uAssets#17807 (comment) The `top=` option is compatible with MV3 DNR's `topDomains` and `excludedTopDomains` as long as the values are plain hostnames (entity- and regex-like values are discarded).
1 parent 11b749e commit aebc108

10 files changed

Lines changed: 312 additions & 163 deletions

File tree

‎platform/mv3/firefox/patch-ruleset.js‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ export function patchRuleset(ruleset) {
2323
const out = [];
2424
for ( const rule of ruleset ) {
2525
const { condition } = rule;
26+
if ( Array.isArray(condition.topDomains) ) { continue; }
27+
if ( Array.isArray(condition.excludedTopDomains) ) { continue; }
2628
if ( Array.isArray(condition.responseHeaders) ) { continue; }
2729
if ( Array.isArray(condition.requestHeaders) ) { continue; }
2830
out.push(rule);

‎platform/mv3/make-rulesets.js‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,16 @@ function pruneHostnameArray(hostnames) {
381381
* */
382382

383383
function toJSONRuleset(ruleset) {
384-
const nodupProps = [ 'domains', 'excludedDomains', 'requestDomains', 'excludedRequestDomains', 'initiatorDomains', 'excludedInitiatorDomains' ];
384+
const nodupProps = [
385+
'domains',
386+
'excludedDomains',
387+
'requestDomains',
388+
'excludedRequestDomains',
389+
'initiatorDomains',
390+
'excludedInitiatorDomains',
391+
'topDomains',
392+
'excludedTopDomains',
393+
];
385394
for ( const { condition } of ruleset ) {
386395
if ( condition === undefined ) { continue; }
387396
for ( const prop of nodupProps ) {

‎platform/mv3/safari/patch-ruleset.js‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ function discardUnsupportedRules(ruleset) {
100100
const isValidRule = rule => {
101101
const { action, condition } = rule;
102102
if ( action.type === 'modifyHeaders' ) { return false; }
103+
if ( Array.isArray(condition.topDomains) ) { return false; }
104+
if ( Array.isArray(condition.excludedTopDomains) ) { return false; }
103105
if ( Array.isArray(condition.responseHeaders) ) { return false; }
104106
if ( Array.isArray(condition.requestHeaders) ) { return false; }
105107
return true;

‎src/js/background.js‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,8 @@ const µBlock = { // jshint ignore:line
180180

181181
// Read-only
182182
systemSettings: {
183-
compiledMagic: 71, // Increase when compiled format changes
184-
selfieMagic: 71, // Increase when selfie format changes
183+
compiledMagic: 72, // Increase when compiled format changes
184+
selfieMagic: 72, // Increase when selfie format changes
185185
},
186186

187187
// https://github.com/uBlockOrigin/uBlock-issues/issues/759#issuecomment-546654501

‎src/js/codemirror/ubo-static-filtering.js‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ const uBOStaticFilteringMode = (( ) => {
188188
case sfp.NODE_TYPE_NET_OPTION_NAME_SCRIPT:
189189
case sfp.NODE_TYPE_NET_OPTION_NAME_SHIDE:
190190
case sfp.NODE_TYPE_NET_OPTION_NAME_TO:
191+
case sfp.NODE_TYPE_NET_OPTION_NAME_TOP:
191192
case sfp.NODE_TYPE_NET_OPTION_NAME_URLTRANSFORM:
192193
case sfp.NODE_TYPE_NET_OPTION_NAME_XHR:
193194
case sfp.NODE_TYPE_NET_OPTION_NAME_WEBRTC:
@@ -534,7 +535,7 @@ function initHints() {
534535
matchRight[0]
535536
);
536537
}
537-
if ( /^(domain|from)=/.test(matchLeft[0]) ) {
538+
if ( /^(domain|from|top)=/.test(matchLeft[0]) ) {
538539
return getOriginHints(cursor, line);
539540
}
540541
};

‎src/js/logger-ui.js‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1625,6 +1625,8 @@ dom.on(document, 'keydown', ev => {
16251625
const response = await messaging.send('loggerUI', {
16261626
what: 'listsFromCosmeticFilter',
16271627
url: targetRow.children[COLUMN_URL].textContent,
1628+
dochn: targetRow.dataset.dochn,
1629+
tophn: targetRow.dataset.tabhn,
16281630
rawFilter,
16291631
});
16301632
handleResponse(response);

‎src/js/pagestore.js‎

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -222,40 +222,29 @@ const FrameStore = class {
222222
return this._cosmeticFilteringBits;
223223
}
224224
this._cosmeticFilteringBits = 0b11;
225+
const fctxt = µb.filteringContext
226+
.duplicate()
227+
.fromTabId(tabId)
228+
.setURL(this.rawURL)
229+
.setDocOriginFromURL(this.rawURL)
230+
.setMethod('')
231+
.setRealm('network')
225232
{
226-
const result = staticNetFilteringEngine.matchRequestReverse(
227-
'specifichide',
228-
this.rawURL
229-
);
233+
fctxt.setType('specifichide');
234+
const result = staticNetFilteringEngine.matchRequest(fctxt, 0b11);
230235
if ( result !== 0 && logger.enabled ) {
231-
µb.filteringContext
232-
.duplicate()
233-
.fromTabId(tabId)
234-
.setURL(this.rawURL)
235-
.setDocOriginFromURL(this.rawURL)
236-
.setRealm('network')
237-
.setType('specifichide')
238-
.setFilter(staticNetFilteringEngine.toLogData())
236+
fctxt.setFilter(staticNetFilteringEngine.toLogData())
239237
.toLogger();
240238
}
241239
if ( result === 2 ) {
242240
this._cosmeticFilteringBits &= ~0b01;
243241
}
244242
}
245243
{
246-
const result = staticNetFilteringEngine.matchRequestReverse(
247-
'generichide',
248-
this.rawURL
249-
);
244+
fctxt.setType('generichide');
245+
const result = staticNetFilteringEngine.matchRequest(fctxt, 0b11);
250246
if ( result !== 0 && logger.enabled ) {
251-
µb.filteringContext
252-
.duplicate()
253-
.fromTabId(tabId)
254-
.setURL(this.rawURL)
255-
.setDocOriginFromURL(this.rawURL)
256-
.setRealm('network')
257-
.setType('generichide')
258-
.setFilter(staticNetFilteringEngine.toLogData())
247+
fctxt.setFilter(staticNetFilteringEngine.toLogData())
259248
.toLogger();
260249
}
261250
if ( result === 2 ) {
@@ -1111,12 +1100,13 @@ const PageStore = class {
11111100
}
11121101
}
11131102
if ( exceptCname === undefined ) {
1114-
const result = staticNetFilteringEngine.matchRequestReverse(
1115-
'cname',
1103+
fctxt.setType('cname');
1104+
fctxt.setURL(
11161105
frameStore instanceof Object
11171106
? frameStore.rawURL
11181107
: fctxt.getDocOrigin()
11191108
);
1109+
const result = staticNetFilteringEngine.matchRequest(fctxt, 0b11);
11201110
exceptCname = result === 2
11211111
? staticNetFilteringEngine.toLogData()
11221112
: false;

‎src/js/reverselookup.js‎

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -174,21 +174,23 @@ const fromExtendedFilter = async function(details) {
174174
needle = parser.getResponseheaderName();
175175
}
176176

177+
const fctxt = µb.filteringContext
178+
.duplicate()
179+
.setURL(details.url)
180+
.setDocHostname(details.dochn)
181+
.setTabHostname(details.tabhn);
182+
fctxt.setType('generichide');
183+
const ignoreGeneric = staticNetFilteringEngine.matchRequest(fctxt, 0b11) === 2;
184+
fctxt.setType('specifichide');
185+
const ignoreSpecific = staticNetFilteringEngine.matchRequest(fctxt, 0b11) === 2;
186+
177187
worker.postMessage({
178188
what: 'fromExtendedFilter',
179189
id,
180190
url: details.url,
181191
domain: domainFromHostname(hostname),
182-
ignoreGeneric:
183-
staticNetFilteringEngine.matchRequestReverse(
184-
'generichide',
185-
details.url
186-
) === 2,
187-
ignoreSpecific:
188-
staticNetFilteringEngine.matchRequestReverse(
189-
'specifichide',
190-
details.url
191-
) === 2,
192+
ignoreGeneric,
193+
ignoreSpecific,
192194
rawFilter: details.rawFilter,
193195
needle,
194196
});

‎src/js/static-filtering-parser.js‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ export const NODE_TYPE_NET_OPTION_NAME_REQUESTHEADER = iota++;
192192
export const NODE_TYPE_NET_OPTION_NAME_SCRIPT = iota++;
193193
export const NODE_TYPE_NET_OPTION_NAME_SHIDE = iota++;
194194
export const NODE_TYPE_NET_OPTION_NAME_TO = iota++;
195+
export const NODE_TYPE_NET_OPTION_NAME_TOP = iota++;
195196
export const NODE_TYPE_NET_OPTION_NAME_URLSKIP = iota++;
196197
export const NODE_TYPE_NET_OPTION_NAME_URLTRANSFORM = iota++;
197198
export const NODE_TYPE_NET_OPTION_NAME_XHR = iota++;
@@ -281,6 +282,7 @@ export const nodeTypeFromOptionName = new Map([
281282
[ 'shide', NODE_TYPE_NET_OPTION_NAME_SHIDE ],
282283
/* synonym */ [ 'specifichide', NODE_TYPE_NET_OPTION_NAME_SHIDE ],
283284
[ 'to', NODE_TYPE_NET_OPTION_NAME_TO ],
285+
[ 'top', NODE_TYPE_NET_OPTION_NAME_TOP ],
284286
[ 'urlskip', NODE_TYPE_NET_OPTION_NAME_URLSKIP ],
285287
[ 'uritransform', NODE_TYPE_NET_OPTION_NAME_URLTRANSFORM ],
286288
[ 'xhr', NODE_TYPE_NET_OPTION_NAME_XHR ],
@@ -1330,6 +1332,7 @@ export class AstFilterParser {
13301332
case NODE_TYPE_NET_OPTION_NAME_FROM:
13311333
case NODE_TYPE_NET_OPTION_NAME_METHOD:
13321334
case NODE_TYPE_NET_OPTION_NAME_TO:
1335+
case NODE_TYPE_NET_OPTION_NAME_TOP:
13331336
realBad = isNegated || hasValue === false;
13341337
break;
13351338
case NODE_TYPE_NET_OPTION_NAME_GENERICBLOCK:
@@ -2055,6 +2058,7 @@ export class AstFilterParser {
20552058
break;
20562059
case NODE_TYPE_NET_OPTION_NAME_FROM:
20572060
case NODE_TYPE_NET_OPTION_NAME_TO:
2061+
case NODE_TYPE_NET_OPTION_NAME_TOP:
20582062
this.linkDown(next, this.parseDomainList(next, '|', DOMAIN_FROM_FROMTO_LIST));
20592063
break;
20602064
default:
@@ -2932,6 +2936,12 @@ export class AstFilterParser {
29322936
);
29332937
}
29342938

2939+
getNetFilterTopOptionIterator() {
2940+
return this.getDomainListIterator(
2941+
this.getBranchFromType(NODE_TYPE_NET_OPTION_NAME_TOP)
2942+
);
2943+
}
2944+
29352945
getNetFilterToOptionIterator() {
29362946
return this.getDomainListIterator(
29372947
this.getBranchFromType(NODE_TYPE_NET_OPTION_NAME_TO)
@@ -3195,6 +3205,7 @@ export const netOptionTokenDescriptors = new Map([
31953205
[ 'shide', { } ],
31963206
/* synonym */ [ 'specifichide', { } ],
31973207
[ 'to', { mustAssign: true } ],
3208+
[ 'top', { mustAssign: true } ],
31983209
[ 'urlskip', { mustAssign: true } ],
31993210
[ 'uritransform', { mustAssign: true } ],
32003211
[ 'xhr', { canNegate: true } ],

0 commit comments

Comments
 (0)