Skip to content

Commit cf2c638

Browse files
committed
Improve reporting of matching redirect= rules in logger
All matching `redirect-rule` directives will now be reported in the logger, instead of just the effective one. The highest-ranked redirect directive will be the one effectively used for redirection. This way filter list authors can see whether a lower priority redirect is being overriden by a higher priority one. The default priority has been changed to 10, so as to allow more leeway to create lower ranked redirect directives. Additonally, rendering of redirect directives with explicit priority has been fixed in the logger, they will no longer be rendered as unknown redirect tokens.
1 parent e08f8cb commit cf2c638

File tree

4 files changed

+42
-46
lines changed

4 files changed

+42
-46
lines changed

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

+3-2
Original file line numberDiff line numberDiff line change
@@ -192,11 +192,12 @@ CodeMirror.defineMode('ubo-static-filtering', function() {
192192
parser.commentSpan.i,
193193
parser.BITComma
194194
);
195-
const token = parser.strFromSlices(parserSlot, end - 3);
195+
const raw = parser.strFromSlices(parserSlot, end - 3);
196+
const { token } = StaticFilteringParser.parseRedirectValue(raw);
196197
if ( redirectNames.has(token) === false ) {
197198
style += ' warning';
198199
}
199-
stream.pos += token.length;
200+
stream.pos += raw.length;
200201
parserSlot = end;
201202
return style;
202203
}

src/js/pagestore.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -716,10 +716,10 @@ const PageStore = class {
716716

717717
redirectBlockedRequest(fctxt) {
718718
if ( µb.hiddenSettings.ignoreRedirectFilters === true ) { return; }
719-
const directive = µb.staticNetFilteringEngine.redirectRequest(fctxt);
720-
if ( directive === undefined ) { return; }
719+
const directives = µb.staticNetFilteringEngine.redirectRequest(fctxt);
720+
if ( directives === undefined ) { return; }
721721
if ( µb.logger.enabled !== true ) { return; }
722-
fctxt.pushFilter(directive.logData());
722+
fctxt.pushFilters(directives.map(a => a.logData()));
723723
if ( fctxt.redirectURL === undefined ) { return; }
724724
fctxt.pushFilter({
725725
source: 'redirect',

src/js/static-filtering-parser.js

+11
Original file line numberDiff line numberDiff line change
@@ -1162,6 +1162,17 @@ const Parser = class {
11621162
);
11631163
}
11641164

1165+
static parseRedirectValue(arg) {
1166+
let token = arg.trim();
1167+
let priority = 10;
1168+
const match = /:\d+$/.exec(token);
1169+
if ( match !== null ) {
1170+
token = token.slice(0, match.index);
1171+
priority = parseInt(token.slice(match.index + 1), 10);
1172+
}
1173+
return { token, priority };
1174+
}
1175+
11651176
static parseQueryPruneValue(arg) {
11661177
let s = arg.trim();
11671178
if ( s === '' ) { return { all: true }; }

src/js/static-net-filtering.js

+25-41
Original file line numberDiff line numberDiff line change
@@ -4236,57 +4236,41 @@ FilterContainer.prototype.redirectRequest = function(fctxt) {
42364236
const directives = this.matchAndFetchModifiers(fctxt, 'redirect-rule');
42374237
// No directive is the most common occurrence.
42384238
if ( directives === undefined ) { return; }
4239-
// A single directive should be the next most common occurrence.
4240-
if ( directives.length === 1 ) {
4241-
const directive = directives[0];
4242-
if ( (directive.bits & AllowAction) !== 0 ) { return directive; }
4243-
const modifier = directive.modifier;
4244-
const { token } = this.parseRedirectRequestValue(modifier);
4239+
// More than a single directive means more work.
4240+
if ( directives.length !== 1 ) {
4241+
directives.sort(FilterContainer.compareRedirectRequests);
4242+
}
4243+
// Redirect to highest-ranked directive
4244+
const directive = directives[directives.length - 1];
4245+
if ( (directive.bits & AllowAction) === 0 ) {
4246+
const { token } =
4247+
FilterContainer.parseRedirectRequestValue(directive.modifier);
42454248
fctxt.redirectURL = µb.redirectEngine.tokenToURL(fctxt, token);
42464249
if ( fctxt.redirectURL === undefined ) { return; }
4247-
return directive;
4248-
}
4249-
// Multiple directives mean more work to do.
4250-
let winningDirective;
4251-
let winningPriority = 0;
4252-
for ( const directive of directives ) {
4253-
const modifier = directive.modifier;
4254-
const isException = (directive.bits & AllowAction) !== 0;
4255-
if ( isException && modifier.value === '' ) {
4256-
winningDirective = directive;
4257-
break;
4258-
}
4259-
const { token, priority } = this.parseRedirectRequestValue(modifier);
4260-
if ( µb.redirectEngine.hasToken(token) === false ) { continue; }
4261-
if ( winningDirective === undefined || priority > winningPriority ) {
4262-
winningDirective = directive;
4263-
winningPriority = priority;
4264-
}
4265-
}
4266-
if ( winningDirective === undefined ) { return; }
4267-
if ( (winningDirective.bits & AllowAction) === 0 ) {
4268-
fctxt.redirectURL = µb.redirectEngine.tokenToURL(
4269-
fctxt,
4270-
winningDirective.modifier.cache.token
4271-
);
42724250
}
4273-
return winningDirective;
4251+
return directives;
42744252
};
42754253

4276-
FilterContainer.prototype.parseRedirectRequestValue = function(modifier) {
4254+
FilterContainer.parseRedirectRequestValue = function(modifier) {
42774255
if ( modifier.cache === undefined ) {
4278-
let token = modifier.value;
4279-
let priority = 1;
4280-
const match = /:(\d+)$/.exec(token);
4281-
if ( match !== null ) {
4282-
token = token.slice(0, match.index);
4283-
priority = parseInt(match[1], 10);
4284-
}
4285-
modifier.cache = { token, priority };
4256+
modifier.cache =
4257+
vAPI.StaticFilteringParser.parseRedirectValue(modifier.value);
42864258
}
42874259
return modifier.cache;
42884260
};
42894261

4262+
FilterContainer.compareRedirectRequests = function(a, b) {
4263+
if ( (a.bits & AllowAction) !== 0 ) { return -1; }
4264+
if ( (b.bits & AllowAction) !== 0 ) { return 1; }
4265+
const { token: atok, priority: aint } =
4266+
FilterContainer.parseRedirectRequestValue(a.modifier);
4267+
if ( µb.redirectEngine.hasToken(atok) === false ) { return -1; }
4268+
const { token: btok, priority: bint } =
4269+
FilterContainer.parseRedirectRequestValue(b.modifier);
4270+
if ( µb.redirectEngine.hasToken(btok) === false ) { return 1; }
4271+
return aint - bint;
4272+
};
4273+
42904274
/******************************************************************************/
42914275

42924276
FilterContainer.prototype.filterQuery = function(fctxt) {

0 commit comments

Comments
 (0)