mirror of https://github.com/gorhill/uBlock.git
Prevent adding known invalid URL-based rules
Related discussion: - https://github.com/uBlockOrigin/uBlock-issues/issues/662#issuecomment-509220702 Currently, `doc` (aka `main_frame`) rules are not evaluated to decide whether a network request must be blocked or not, by design. This commits adjust uBO's UI to account for this.
This commit is contained in:
parent
e55cae6232
commit
2f63fb3fd4
|
@ -38,7 +38,7 @@ CodeMirror.defineMode('ubo-dynamic-filtering', ( ) => {
|
||||||
'true',
|
'true',
|
||||||
'false',
|
'false',
|
||||||
]);
|
]);
|
||||||
const validTypes = new Set([
|
const validHnRuleTypes = new Set([
|
||||||
'*',
|
'*',
|
||||||
'3p',
|
'3p',
|
||||||
'image',
|
'image',
|
||||||
|
@ -47,6 +47,10 @@ CodeMirror.defineMode('ubo-dynamic-filtering', ( ) => {
|
||||||
'3p-script',
|
'3p-script',
|
||||||
'3p-frame',
|
'3p-frame',
|
||||||
]);
|
]);
|
||||||
|
const invalidURLRuleTypes = new Set([
|
||||||
|
'doc',
|
||||||
|
'main_frame',
|
||||||
|
]);
|
||||||
const validActions = new Set([
|
const validActions = new Set([
|
||||||
'block',
|
'block',
|
||||||
'allow',
|
'allow',
|
||||||
|
@ -110,20 +114,26 @@ CodeMirror.defineMode('ubo-dynamic-filtering', ( ) => {
|
||||||
}
|
}
|
||||||
// Field 3
|
// Field 3
|
||||||
if ( tokens.length === 3 ) {
|
if ( tokens.length === 3 ) {
|
||||||
|
// Switch rule
|
||||||
if ( isSwitchRule(tokens[0]) ) {
|
if ( isSwitchRule(tokens[0]) ) {
|
||||||
if ( validSwitcheStates.has(token) === false ) {
|
if ( validSwitcheStates.has(token) === false ) {
|
||||||
return skipToEnd(stream, 'error');
|
return skipToEnd(stream, 'error');
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
// Hostname rule
|
||||||
if ( isURLRule(tokens[1]) === false ) {
|
if ( isURLRule(tokens[1]) === false ) {
|
||||||
if (
|
if (
|
||||||
tokens[1] !== '*' && token !== '*' ||
|
tokens[1] !== '*' && token !== '*' ||
|
||||||
tokens[1] === '*' && validTypes.has(token) === false
|
tokens[1] === '*' && validHnRuleTypes.has(token) === false
|
||||||
) {
|
) {
|
||||||
return skipToEnd(stream, 'error');
|
return skipToEnd(stream, 'error');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// URL rule
|
||||||
|
if ( /[^a-z_-]+/.test(token) || invalidURLRuleTypes.has(token) ) {
|
||||||
|
return skipToEnd(stream, 'error');
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// Field 4
|
// Field 4
|
||||||
|
|
|
@ -1610,6 +1610,9 @@ const reloadTab = function(ev) {
|
||||||
const fillDynamicPane = function() {
|
const fillDynamicPane = function() {
|
||||||
if ( targetRow.classList.contains('cosmeticRealm') ) { return; }
|
if ( targetRow.classList.contains('cosmeticRealm') ) { return; }
|
||||||
|
|
||||||
|
// https://github.com/uBlockOrigin/uBlock-issues/issues/662#issuecomment-509220702
|
||||||
|
if ( targetType === 'doc' ) { return; }
|
||||||
|
|
||||||
// https://github.com/gorhill/uBlock/issues/2469
|
// https://github.com/gorhill/uBlock/issues/2469
|
||||||
if ( targetURLs.length === 0 || reSchemeOnly.test(targetURLs[0]) ) {
|
if ( targetURLs.length === 0 || reSchemeOnly.test(targetURLs[0]) ) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
uBlock Origin - a browser extension to black/white list requests.
|
uBlock Origin - a browser extension to black/white list requests.
|
||||||
Copyright (C) 2015-2018 Raymond Hill
|
Copyright (C) 2015-present Raymond Hill
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
// The purpose of log filtering is to create ad hoc filtering rules, to
|
// The purpose of log filtering is to create ad hoc filtering rules, to
|
||||||
// diagnose and assist in the creation of custom filters.
|
// diagnose and assist in the creation of custom filters.
|
||||||
|
|
||||||
µBlock.URLNetFiltering = (function() {
|
µBlock.URLNetFiltering = (( ) => {
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
|
@ -38,49 +38,49 @@ rule entry: { url, action }
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var actionToNameMap = {
|
const actionToNameMap = {
|
||||||
1: 'block',
|
1: 'block',
|
||||||
2: 'allow',
|
2: 'allow',
|
||||||
3: 'noop'
|
3: 'noop'
|
||||||
};
|
};
|
||||||
|
|
||||||
var nameToActionMap = {
|
const nameToActionMap = {
|
||||||
'block': 1,
|
'block': 1,
|
||||||
'allow': 2,
|
'allow': 2,
|
||||||
'noop': 3
|
'noop': 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const knownInvalidTypes = new Set([
|
||||||
|
'doc',
|
||||||
|
'main_frame',
|
||||||
|
]);
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var RuleEntry = function(url, action) {
|
const RuleEntry = function(url, action) {
|
||||||
this.url = url;
|
this.url = url;
|
||||||
this.action = action;
|
this.action = action;
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var indexOfURL = function(entries, url) {
|
const indexOfURL = function(entries, url) {
|
||||||
// TODO: binary search -- maybe, depends on common use cases
|
// TODO: binary search -- maybe, depends on common use cases
|
||||||
var urlLen = url.length,
|
const urlLen = url.length;
|
||||||
entry;
|
|
||||||
// URLs must be ordered by increasing length.
|
// URLs must be ordered by increasing length.
|
||||||
for ( var i = 0; i < entries.length; i++ ) {
|
for ( let i = 0; i < entries.length; i++ ) {
|
||||||
entry = entries[i];
|
const entry = entries[i];
|
||||||
if ( entry.url.length > urlLen ) {
|
if ( entry.url.length > urlLen ) { break; }
|
||||||
break;
|
if ( entry.url === url ) { return i; }
|
||||||
}
|
|
||||||
if ( entry.url === url ) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var indexOfMatch = function(entries, url) {
|
const indexOfMatch = function(entries, url) {
|
||||||
var urlLen = url.length,
|
const urlLen = url.length;
|
||||||
i = entries.length;
|
let i = entries.length;
|
||||||
while ( i-- ) {
|
while ( i-- ) {
|
||||||
if ( entries[i].url.length <= urlLen ) {
|
if ( entries[i].url.length <= urlLen ) {
|
||||||
break;
|
break;
|
||||||
|
@ -98,22 +98,20 @@ var indexOfMatch = function(entries, url) {
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var indexFromLength = function(entries, len) {
|
const indexFromLength = function(entries, len) {
|
||||||
// TODO: binary search -- maybe, depends on common use cases
|
// TODO: binary search -- maybe, depends on common use cases
|
||||||
// URLs must be ordered by increasing length.
|
// URLs must be ordered by increasing length.
|
||||||
for ( var i = 0; i < entries.length; i++ ) {
|
for ( let i = 0; i < entries.length; i++ ) {
|
||||||
if ( entries[i].url.length > len ) {
|
if ( entries[i].url.length > len ) { return i; }
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var addRuleEntry = function(entries, url, action) {
|
const addRuleEntry = function(entries, url, action) {
|
||||||
var entry = new RuleEntry(url, action),
|
const entry = new RuleEntry(url, action);
|
||||||
i = indexFromLength(entries, url.length);
|
const i = indexFromLength(entries, url.length);
|
||||||
if ( i === -1 ) {
|
if ( i === -1 ) {
|
||||||
entries.push(entry);
|
entries.push(entry);
|
||||||
} else {
|
} else {
|
||||||
|
@ -123,7 +121,7 @@ var addRuleEntry = function(entries, url, action) {
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
var URLNetFiltering = function() {
|
const URLNetFiltering = function() {
|
||||||
this.reset();
|
this.reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -144,13 +142,13 @@ URLNetFiltering.prototype.reset = function() {
|
||||||
|
|
||||||
URLNetFiltering.prototype.assign = function(other) {
|
URLNetFiltering.prototype.assign = function(other) {
|
||||||
// Remove rules not in other
|
// Remove rules not in other
|
||||||
for ( var key of this.rules.keys() ) {
|
for ( const key of this.rules.keys() ) {
|
||||||
if ( other.rules.has(key) === false ) {
|
if ( other.rules.has(key) === false ) {
|
||||||
this.rules.delete(key);
|
this.rules.delete(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Add/change rules in other
|
// Add/change rules in other
|
||||||
for ( var entry of other.rules ) {
|
for ( const entry of other.rules ) {
|
||||||
this.rules.set(entry[0], entry[1].slice());
|
this.rules.set(entry[0], entry[1].slice());
|
||||||
}
|
}
|
||||||
this.changed = true;
|
this.changed = true;
|
||||||
|
@ -162,16 +160,15 @@ URLNetFiltering.prototype.setRule = function(srcHostname, url, type, action) {
|
||||||
if ( action === 0 ) {
|
if ( action === 0 ) {
|
||||||
return this.removeRule(srcHostname, url, type);
|
return this.removeRule(srcHostname, url, type);
|
||||||
}
|
}
|
||||||
var bucketKey = srcHostname + ' ' + type,
|
const bucketKey = srcHostname + ' ' + type;
|
||||||
entries = this.rules.get(bucketKey);
|
let entries = this.rules.get(bucketKey);
|
||||||
if ( entries === undefined ) {
|
if ( entries === undefined ) {
|
||||||
entries = [];
|
entries = [];
|
||||||
this.rules.set(bucketKey, entries);
|
this.rules.set(bucketKey, entries);
|
||||||
}
|
}
|
||||||
var i = indexOfURL(entries, url),
|
const i = indexOfURL(entries, url);
|
||||||
entry;
|
|
||||||
if ( i !== -1 ) {
|
if ( i !== -1 ) {
|
||||||
entry = entries[i];
|
const entry = entries[i];
|
||||||
if ( entry.action === action ) { return false; }
|
if ( entry.action === action ) { return false; }
|
||||||
entry.action = action;
|
entry.action = action;
|
||||||
} else {
|
} else {
|
||||||
|
@ -184,15 +181,11 @@ URLNetFiltering.prototype.setRule = function(srcHostname, url, type, action) {
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
URLNetFiltering.prototype.removeRule = function(srcHostname, url, type) {
|
URLNetFiltering.prototype.removeRule = function(srcHostname, url, type) {
|
||||||
var bucketKey = srcHostname + ' ' + type,
|
const bucketKey = srcHostname + ' ' + type;
|
||||||
entries = this.rules.get(bucketKey);
|
const entries = this.rules.get(bucketKey);
|
||||||
if ( entries === undefined ) {
|
if ( entries === undefined ) { return false; }
|
||||||
return false;
|
const i = indexOfURL(entries, url);
|
||||||
}
|
if ( i === -1 ) { return false; }
|
||||||
var i = indexOfURL(entries, url);
|
|
||||||
if ( i === -1 ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
entries.splice(i, 1);
|
entries.splice(i, 1);
|
||||||
if ( entries.length === 0 ) {
|
if ( entries.length === 0 ) {
|
||||||
this.rules.delete(bucketKey);
|
this.rules.delete(bucketKey);
|
||||||
|
@ -278,14 +271,19 @@ URLNetFiltering.prototype.intToActionMap = new Map([
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
URLNetFiltering.prototype.copyRules = function(other, context, urls, type) {
|
URLNetFiltering.prototype.copyRules = function(other, context, urls, type) {
|
||||||
var url, otherOwn, thisOwn;
|
let i = urls.length;
|
||||||
var i = urls.length;
|
|
||||||
while ( i-- ) {
|
while ( i-- ) {
|
||||||
url = urls[i];
|
const url = urls[i];
|
||||||
other.evaluateZ(context, url, type);
|
other.evaluateZ(context, url, type);
|
||||||
otherOwn = other.r !== 0 && other.context === context && other.url === url && other.type === type;
|
const otherOwn = other.r !== 0 &&
|
||||||
|
other.context === context &&
|
||||||
|
other.url === url &&
|
||||||
|
other.type === type;
|
||||||
this.evaluateZ(context, url, type);
|
this.evaluateZ(context, url, type);
|
||||||
thisOwn = this.r !== 0 && this.context === context && this.url === url && this.type === type;
|
const thisOwn = this.r !== 0 &&
|
||||||
|
this.context === context &&
|
||||||
|
this.url === url &&
|
||||||
|
this.type === type;
|
||||||
if ( otherOwn && !thisOwn ) {
|
if ( otherOwn && !thisOwn ) {
|
||||||
this.setRule(context, url, type, other.r);
|
this.setRule(context, url, type, other.r);
|
||||||
this.changed = true;
|
this.changed = true;
|
||||||
|
@ -303,17 +301,16 @@ URLNetFiltering.prototype.copyRules = function(other, context, urls, type) {
|
||||||
// "url-filtering:" hostname url type action
|
// "url-filtering:" hostname url type action
|
||||||
|
|
||||||
URLNetFiltering.prototype.toArray = function() {
|
URLNetFiltering.prototype.toArray = function() {
|
||||||
var out = [],
|
const out = [];
|
||||||
key, pos, hn, type, entries, i, entry;
|
|
||||||
for ( var item of this.rules ) {
|
for ( var item of this.rules ) {
|
||||||
key = item[0];
|
const key = item[0];
|
||||||
pos = key.indexOf(' ');
|
let pos = key.indexOf(' ');
|
||||||
hn = key.slice(0, pos);
|
const hn = key.slice(0, pos);
|
||||||
pos = key.lastIndexOf(' ');
|
pos = key.lastIndexOf(' ');
|
||||||
type = key.slice(pos + 1);
|
const type = key.slice(pos + 1);
|
||||||
entries = item[1];
|
const entries = item[1];
|
||||||
for ( i = 0; i < entries.length; i++ ) {
|
for ( let i = 0; i < entries.length; i++ ) {
|
||||||
entry = entries[i];
|
const entry = entries[i];
|
||||||
out.push(
|
out.push(
|
||||||
hn + ' ' +
|
hn + ' ' +
|
||||||
entry.url + ' ' +
|
entry.url + ' ' +
|
||||||
|
@ -333,7 +330,7 @@ URLNetFiltering.prototype.toString = function() {
|
||||||
|
|
||||||
URLNetFiltering.prototype.fromString = function(text) {
|
URLNetFiltering.prototype.fromString = function(text) {
|
||||||
this.reset();
|
this.reset();
|
||||||
var lineIter = new µBlock.LineIterator(text);
|
const lineIter = new µBlock.LineIterator(text);
|
||||||
while ( lineIter.eot() === false ) {
|
while ( lineIter.eot() === false ) {
|
||||||
this.addFromRuleParts(lineIter.next().trim().split(/\s+/));
|
this.addFromRuleParts(lineIter.next().trim().split(/\s+/));
|
||||||
}
|
}
|
||||||
|
@ -344,6 +341,9 @@ URLNetFiltering.prototype.fromString = function(text) {
|
||||||
URLNetFiltering.prototype.validateRuleParts = function(parts) {
|
URLNetFiltering.prototype.validateRuleParts = function(parts) {
|
||||||
if ( parts.length !== 4 ) { return; }
|
if ( parts.length !== 4 ) { return; }
|
||||||
if ( parts[1].indexOf('://') === -1 ) { return; }
|
if ( parts[1].indexOf('://') === -1 ) { return; }
|
||||||
|
if ( /[^a-z_-]+/.test(parts[2]) || knownInvalidTypes.has(parts[2]) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if ( nameToActionMap.hasOwnProperty(parts[3]) === false ) { return; }
|
if ( nameToActionMap.hasOwnProperty(parts[3]) === false ) { return; }
|
||||||
return parts;
|
return parts;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue