Index: lib/filterClasses.js |
=================================================================== |
--- a/lib/filterClasses.js |
+++ b/lib/filterClasses.js |
@@ -28,32 +28,40 @@ |
/** |
* Regular expression used to match the <code>||</code> prefix in an otherwise |
* literal pattern. |
* @type {RegExp} |
*/ |
let doubleAnchorRegExp = new RegExp(filterToRegExp("||") + "$"); |
/** |
+ * Regular expression used to match the <code>^</code> suffix in an otherwise |
+ * literal pattern. |
+ * @type {RegExp} |
+ */ |
+// Note: This should match the pattern in lib/common.js |
+let separatorRegExp = /[\x00-\x24\x26-\x2C\x2F\x3A-\x40\x5B-\x5E\x60\x7B-\x7F]/; |
+ |
+/** |
* All known unique domain sources mapped to their parsed values. |
* @type {Map.<string,Map.<string,boolean>>} |
*/ |
let knownDomainMaps = new Map(); |
/** |
* Checks whether the given pattern is a string of literal characters with no |
* wildcards or any other special characters. If the pattern is prefixed with a |
- * <code>||</code> but otherwise contains no special characters, it is still |
- * considered to be a literal pattern. |
+ * <code>||</code> or suffixed with a <code>^</code> but otherwise contains no |
+ * special characters, it is still considered to be a literal pattern. |
* @param {string} pattern |
* @returns {boolean} |
*/ |
function isLiteralPattern(pattern) |
{ |
- return !/[*^|]/.test(pattern.replace(/^\|{2}/, "")); |
+ return !/[*^|]/.test(pattern.replace(/^\|{2}/, "").replace(/\^$/, "")); |
} |
/** |
* Abstract base class for filters |
* |
* @param {string} text string representation of the filter |
* @constructor |
*/ |
@@ -837,27 +845,34 @@ |
if (regexp) |
return regexp.test(location); |
if (!this.matchCase) |
location = location.toLowerCase(); |
let {pattern} = this; |
- if (pattern[0] == "|" && pattern[1] == "|") |
- { |
- let index = location.indexOf(pattern.substring(2)); |
+ let startsWithDoubleAnchor = pattern[0] == "|" && pattern[1] == "|"; |
+ let endsWithSeparator = pattern[pattern.length - 1] == "^"; |
+ |
+ if (startsWithDoubleAnchor) |
+ pattern = pattern.substr(2); |
+ |
+ if (endsWithSeparator) |
+ pattern = pattern.slice(0, -1); |
- // The "||" prefix requires that the text that follows does not start |
- // with a forward slash. |
- return index != -1 && location[index] != "/" && |
- doubleAnchorRegExp.test(location.substring(0, index)); |
- } |
+ let index = location.indexOf(pattern); |
- return location.includes(pattern); |
+ // The "||" prefix requires that the text that follows does not start |
+ // with a forward slash. |
+ return index != -1 && |
+ (!startsWithDoubleAnchor || location[index] != "/" && |
+ doubleAnchorRegExp.test(location.substring(0, index))) && |
+ (!endsWithSeparator || !location[index + pattern.length] || |
+ separatorRegExp.test(location[index + pattern.length])); |
}, |
/** |
* Checks whether this filter has only a URL pattern and no content type, |
* third-party flag, domains, or sitekeys. |
* @returns {boolean} |
*/ |
isLocationOnly() |