Skip to content

Commit 5c7efea

Browse files
authored
fix(adblocker): ensure case insensitive matching (#5277)
1 parent bc3a942 commit 5c7efea

File tree

4 files changed

+22
-29
lines changed

4 files changed

+22
-29
lines changed

packages/adblocker/src/filters/network.ts

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2072,6 +2072,7 @@ export function isAnchoredByHostname(
20722072
*/
20732073
function checkPattern(filter: NetworkFilter, request: Request): boolean {
20742074
const pattern = filter.getFilter();
2075+
const url = request.normalizedUrl;
20752076

20762077
if (filter.isHostnameAnchor() === true) {
20772078
// Make sure request is anchored by hostname before proceeding to matching
@@ -2091,15 +2092,13 @@ function checkPattern(filter: NetworkFilter, request: Request): boolean {
20912092
// ||pattern*^
20922093
return filter
20932094
.getRegex()
2094-
.test(request.url.slice(request.url.indexOf(filterHostname) + filterHostname.length));
2095+
.test(url.slice(url.indexOf(filterHostname) + filterHostname.length));
20952096
} else if (filter.isRightAnchor() && filter.isLeftAnchor()) {
20962097
// |||pattern|
20972098
// Since this is not a regex, the filter pattern must follow the hostname
20982099
// with nothing in between. So we extract the part of the URL following
20992100
// after hostname and will perform the matching on it.
2100-
const urlAfterHostname = request.url.slice(
2101-
request.url.indexOf(filterHostname) + filterHostname.length,
2102-
);
2101+
const urlAfterHostname = url.slice(url.indexOf(filterHostname) + filterHostname.length);
21032102

21042103
// Since it must follow immediatly after the hostname and be a suffix of
21052104
// the URL, we conclude that filter must be equal to the part of the
@@ -2119,49 +2118,43 @@ function checkPattern(filter: NetworkFilter, request: Request): boolean {
21192118
);
21202119
} else {
21212120
// pattern|
2122-
return request.url.endsWith(pattern);
2121+
return url.endsWith(pattern);
21232122
}
21242123
} else if (filter.isLeftAnchor()) {
21252124
// ||pattern + left-anchor => This means that a plain pattern needs to appear
21262125
// exactly after the hostname, with nothing in between.
21272126
// Since this is not a regex, the filter pattern must follow the hostname
21282127
// with nothing in between. So we extract the part of the URL following
21292128
// after hostname and will perform the matching on it.
2130-
return request.url.startsWith(
2131-
pattern,
2132-
request.url.indexOf(filterHostname) + filterHostname.length,
2133-
);
2129+
return url.startsWith(pattern, url.indexOf(filterHostname) + filterHostname.length);
21342130
}
21352131

21362132
if (filter.hasFilter() === false) {
21372133
return true;
21382134
}
21392135

21402136
// We consider this a match if the plain patter (i.e.: filter) appears anywhere.
2141-
return (
2142-
request.url.indexOf(pattern, request.url.indexOf(filterHostname) + filterHostname.length) !==
2143-
-1
2144-
);
2137+
return url.indexOf(pattern, url.indexOf(filterHostname) + filterHostname.length) !== -1;
21452138
} else if (filter.isRegex()) {
21462139
// pattern*^
2147-
return filter.getRegex().test(request.url);
2140+
return filter.getRegex().test(url);
21482141
} else if (filter.isLeftAnchor() && filter.isRightAnchor()) {
21492142
// |pattern|
2150-
return request.url === pattern;
2143+
return url === pattern;
21512144
} else if (filter.isLeftAnchor()) {
21522145
// |pattern
2153-
return request.url.startsWith(pattern);
2146+
return url.startsWith(pattern);
21542147
} else if (filter.isRightAnchor()) {
21552148
// pattern|
2156-
return request.url.endsWith(pattern);
2149+
return url.endsWith(pattern);
21572150
}
21582151

21592152
// pattern
21602153
if (filter.hasFilter() === false) {
21612154
return true;
21622155
}
21632156

2164-
return request.url.indexOf(pattern) !== -1;
2157+
return url.indexOf(pattern) !== -1;
21652158
}
21662159

21672160
function checkOptions(filter: NetworkFilter, request: Request): boolean {

packages/adblocker/src/request.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -292,8 +292,6 @@ export default class Request<T = any | undefined> {
292292
type = 'main_frame',
293293
_originalRequestDetails,
294294
}: Partial<RequestInitialization<T>>): Request<T> {
295-
url = url.toLowerCase();
296-
297295
if (hostname === undefined || domain === undefined) {
298296
const parsed = parse(url, TLDTS_OPTIONS);
299297
hostname = hostname || parsed.hostname || '';
@@ -337,6 +335,7 @@ export default class Request<T = any | undefined> {
337335
public readonly id: string;
338336
public readonly tabId: number;
339337
public readonly url: string;
338+
public readonly normalizedUrl: string;
340339
public readonly hostname: string;
341340
public readonly domain: string;
342341

@@ -369,6 +368,7 @@ export default class Request<T = any | undefined> {
369368
this.type = type;
370369

371370
this.url = url;
371+
this.normalizedUrl = url.toLowerCase();
372372
this.hostname = hostname;
373373
this.domain = domain;
374374

@@ -448,7 +448,7 @@ export default class Request<T = any | undefined> {
448448
// Add token corresponding to request type
449449
TOKENS_BUFFER.push(NORMALIZED_TYPE_TOKEN[this.type]);
450450

451-
tokenizeNoSkipInPlace(this.url, TOKENS_BUFFER);
451+
tokenizeNoSkipInPlace(this.normalizedUrl, TOKENS_BUFFER);
452452

453453
this.tokens = TOKENS_BUFFER.slice();
454454
}

packages/adblocker/test/data/requests.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52921,4 +52921,12 @@ export default [
5292152921
type: 'script',
5292252922
url: 'https://www1.swatchseries.to/public/js/bootstrap-modal.js',
5292352923
},
52924+
{
52925+
filters: [
52926+
'||assets.adobedtm.com/extensions/*/AppMeasurement_Module_ActivityMap.min.js$script,domain=euronews.com',
52927+
],
52928+
sourceUrl: 'https://euronews.com',
52929+
type: 'script',
52930+
url: 'https://assets.adobedtm.com/extensions/EP31dbb9c60e404ba1aa6e746d49be6f29/AppMeasurement_Module_ActivityMap.min.js',
52931+
},
5292452932
];

packages/adblocker/test/request.test.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,6 @@ describe('#Request', () => {
2929
});
3030
});
3131

32-
it('converts url to lower case', () => {
33-
expect(Request.fromRawDetails({ url: 'https://sub.FOO.cOm/bar' })).to.deep.include({
34-
domain: 'foo.com',
35-
hostname: 'sub.foo.com',
36-
url: 'https://sub.foo.com/bar',
37-
});
38-
});
39-
4032
it('parses url', () => {
4133
expect(Request.fromRawDetails({ url: 'https://sub.foo.com/bar' })).to.deep.include({
4234
domain: 'foo.com',

0 commit comments

Comments
 (0)