Skip to content

Commit a3c8e6b

Browse files
committed
code review: stricter interpretation of ^
1 parent 94e4a95 commit a3c8e6b

2 files changed

Lines changed: 89 additions & 85 deletions

File tree

src/js/logger-ui.js

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -283,8 +283,9 @@ var filterDecompiler = (function() {
283283
return filter;
284284
};
285285

286-
var reEscape = /[.+?^${}()|[\]\\]/g;
286+
var reEscape = /[.+?${}()|[\]\\]/g;
287287
var reWildcards = /\*+/g;
288+
var reSeparator = /\^/g;
288289

289290
var toRegex = function(compiled) {
290291
var vfields = compiled.split('\v');
@@ -302,27 +303,20 @@ var filterDecompiler = (function() {
302303
case '0ah':
303304
case '1a':
304305
case '1ah':
306+
case '|a':
307+
case '|ah':
308+
case 'a|':
309+
case 'a|h':
305310
case '_':
306311
case '_h':
307312
case '||a':
308313
case '||ah':
309314
case '||_':
310315
case '||_h':
311316
reStr = tfields[0]
312-
.replace(reEscape, '\\$&')
313-
.replace(reWildcards, '.*');
314-
break;
315-
case '|a':
316-
case '|ah':
317-
reStr = '^' + tfields[0].
318-
replace(reEscape, '\\$&')
319-
.replace(reWildcards, '.*');
320-
break;
321-
case 'a|':
322-
case 'a|h':
323-
reStr = tfields[0]
324-
.replace(reEscape, '\\$&')
325-
.replace(reWildcards, '.*') + '$';
317+
.replace(reEscape, '\\$&')
318+
.replace(reWildcards, '.*')
319+
.replace(reSeparator, '[^%.0-9a-z_-]');
326320
break;
327321
case '//':
328322
case '//h':
@@ -332,6 +326,14 @@ var filterDecompiler = (function() {
332326
break;
333327
}
334328

329+
// Anchored?
330+
var s = fid.slice(0, 2);
331+
if ( s === '|a' ) {
332+
reStr = '^' + reStr;
333+
} else if ( s === 'a|' ) {
334+
reStr += '$';
335+
}
336+
335337
if ( reStr === undefined) {
336338
return null;
337339
}

src/js/static-net-filtering.js

Lines changed: 72 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,8 @@ var strToRegex = function(s, anchor, flags) {
208208

209209
// https://www.loggly.com/blog/five-invaluable-techniques-to-improve-regex-performance/
210210
// https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions
211-
var reStr = s.replace(/[.+?^${}()|[\]\\]/g, '\\$&')
211+
var reStr = s.replace(/[.+?${}()|[\]\\]/g, '\\$&')
212+
.replace(/\^/g, '[^%.0-9a-z_-]')
212213
.replace(/\*/g, '[^ ]*?');
213214

214215
if ( anchor < 0 ) {
@@ -1279,71 +1280,6 @@ FilterBucket.fromSelfie = function() {
12791280

12801281
/******************************************************************************/
12811282

1282-
var getFilterClass = function(details) {
1283-
if ( details.domainOpt.length !== 0 ) {
1284-
return getHostnameBasedFilterClass(details);
1285-
}
1286-
if ( details.isRegex ) {
1287-
return FilterRegex;
1288-
}
1289-
var s = details.f;
1290-
if ( s.indexOf('*') !== -1 || details.token === '*' ) {
1291-
if ( details.hostnameAnchored ) {
1292-
return FilterGenericHnAnchored;
1293-
}
1294-
return FilterGeneric;
1295-
}
1296-
if ( details.anchor < 0 ) {
1297-
return FilterPlainLeftAnchored;
1298-
}
1299-
if ( details.anchor > 0 ) {
1300-
return FilterPlainRightAnchored;
1301-
}
1302-
if ( details.hostnameAnchored ) {
1303-
return FilterPlainHnAnchored;
1304-
}
1305-
if ( details.tokenBeg === 0 ) {
1306-
return FilterPlainPrefix0;
1307-
}
1308-
if ( details.tokenBeg === 1 ) {
1309-
return FilterPlainPrefix1;
1310-
}
1311-
return FilterPlain;
1312-
};
1313-
1314-
/******************************************************************************/
1315-
1316-
var getHostnameBasedFilterClass = function(details) {
1317-
if ( details.isRegex ) {
1318-
return FilterRegexHostname;
1319-
}
1320-
var s = details.f;
1321-
if ( s.indexOf('*') !== -1 || details.token === '*' ) {
1322-
if ( details.hostnameAnchored ) {
1323-
return FilterGenericHnAnchoredHostname;
1324-
}
1325-
return FilterGenericHostname;
1326-
}
1327-
if ( details.anchor < 0 ) {
1328-
return FilterPlainLeftAnchoredHostname;
1329-
}
1330-
if ( details.anchor > 0 ) {
1331-
return FilterPlainRightAnchoredHostname;
1332-
}
1333-
if ( details.hostnameAnchored ) {
1334-
return FilterPlainHnAnchoredHostname;
1335-
}
1336-
if ( details.tokenBeg === 0 ) {
1337-
return FilterPlainPrefix0Hostname;
1338-
}
1339-
if ( details.tokenBeg === 1 ) {
1340-
return FilterPlainPrefix1Hostname;
1341-
}
1342-
return FilterPlainHostname;
1343-
};
1344-
1345-
/******************************************************************************/
1346-
13471283
// Trim leading/trailing char "c"
13481284

13491285
var trimChar = function(s, c) {
@@ -1622,10 +1558,15 @@ FilterParser.prototype.parse = function(raw) {
16221558
// TODO: transforming `^` into `*` is not a strict interpretation of
16231559
// ABP syntax.
16241560
if ( this.reHasWildcard.test(s) ) {
1625-
s = s.replace(/^\*+([^%0-9a-z])/, '$1') // remove pointless leading *
1626-
.replace(/([^%0-9a-z])\*+$/, '$1'); // remove pointless trailing *
1561+
// remove pointless leading *
1562+
if ( s.charAt(0) === '*' ) {
1563+
s = s.replace(/^\*+([^%0-9a-z])/, '$1');
1564+
}
1565+
// remove pointless trailing *
1566+
if ( s.slice(-1) === '*' ) {
1567+
s = s.replace(/([^%0-9a-z])\*+$/, '$1');
1568+
}
16271569
s = trimChar(s, '^');
1628-
s = s.replace(/\^/g, '*').replace(/\*\*+/g, '*');
16291570
}
16301571

16311572
// nothing left?
@@ -1731,6 +1672,7 @@ var TokenEntry = function() {
17311672

17321673
var FilterContainer = function() {
17331674
this.reAnyToken = /[%0-9a-z]+/g;
1675+
this.reIsGeneric = /[\^\*]/;
17341676
this.tokens = [];
17351677
this.filterParser = new FilterParser();
17361678
this.reset();
@@ -1899,6 +1841,66 @@ FilterContainer.prototype.fromSelfie = function(selfie) {
18991841

19001842
/******************************************************************************/
19011843

1844+
FilterContainer.prototype.getFilterClass = function(details) {
1845+
var s = details.f;
1846+
1847+
if ( details.domainOpt.length !== 0 ) {
1848+
if ( details.isRegex ) {
1849+
return FilterRegexHostname;
1850+
}
1851+
if ( this.reIsGeneric.test(s) ) {
1852+
if ( details.hostnameAnchored ) {
1853+
return FilterGenericHnAnchoredHostname;
1854+
}
1855+
return FilterGenericHostname;
1856+
}
1857+
if ( details.anchor < 0 ) {
1858+
return FilterPlainLeftAnchoredHostname;
1859+
}
1860+
if ( details.anchor > 0 ) {
1861+
return FilterPlainRightAnchoredHostname;
1862+
}
1863+
if ( details.hostnameAnchored ) {
1864+
return FilterPlainHnAnchoredHostname;
1865+
}
1866+
if ( details.tokenBeg === 0 ) {
1867+
return FilterPlainPrefix0Hostname;
1868+
}
1869+
if ( details.tokenBeg === 1 ) {
1870+
return FilterPlainPrefix1Hostname;
1871+
}
1872+
return FilterPlainHostname;
1873+
}
1874+
1875+
if ( details.isRegex ) {
1876+
return FilterRegex;
1877+
}
1878+
if ( this.reIsGeneric.test(s) ) {
1879+
if ( details.hostnameAnchored ) {
1880+
return FilterGenericHnAnchored;
1881+
}
1882+
return FilterGeneric;
1883+
}
1884+
if ( details.anchor < 0 ) {
1885+
return FilterPlainLeftAnchored;
1886+
}
1887+
if ( details.anchor > 0 ) {
1888+
return FilterPlainRightAnchored;
1889+
}
1890+
if ( details.hostnameAnchored ) {
1891+
return FilterPlainHnAnchored;
1892+
}
1893+
if ( details.tokenBeg === 0 ) {
1894+
return FilterPlainPrefix0;
1895+
}
1896+
if ( details.tokenBeg === 1 ) {
1897+
return FilterPlainPrefix1;
1898+
}
1899+
return FilterPlain;
1900+
};
1901+
1902+
/******************************************************************************/
1903+
19021904
FilterContainer.prototype.compile = function(raw, out) {
19031905
// ORDER OF TESTS IS IMPORTANT!
19041906

@@ -1993,7 +1995,7 @@ FilterContainer.prototype.compileFilter = function(parsed, out) {
19931995
party = parsed.firstParty ? FirstParty : ThirdParty;
19941996
}
19951997

1996-
var filterClass = getFilterClass(parsed);
1998+
var filterClass = this.getFilterClass(parsed);
19971999
if ( filterClass === null ) {
19982000
return false;
19992001
}

0 commit comments

Comments
 (0)