| Index: lib/filterClasses.js |
| =================================================================== |
| --- a/lib/filterClasses.js |
| +++ b/lib/filterClasses.js |
| @@ -382,38 +382,38 @@ |
| /** |
| * Separator character used in domainSource property, must be |
| * overridden by subclasses |
| * @type {string} |
| */ |
| domainSeparator: null, |
| /** |
| - * Determines whether domainSource is already upper-case, |
| + * Determines whether domainSource is already lower-case, |
| * can be overridden by subclasses. |
| * @type {boolean} |
| */ |
| - domainSourceIsUpperCase: false, |
| + domainSourceIsLowerCase: false, |
| /** |
| * Map containing domains that this filter should match on/not match |
| * on or null if the filter should match on all domains |
| * @type {?Map.<string,boolean>} |
| */ |
| get domains() |
| { |
| let domains = null; |
| if (this.domainSource) |
| { |
| let source = this.domainSource; |
| - if (!this.domainSourceIsUpperCase) |
| + if (!this.domainSourceIsLowerCase) |
| { |
| - // RegExpFilter already have uppercase domains |
| - source = source.toUpperCase(); |
| + // RegExpFilter already have lowercase domains |
| + source = source.toLowerCase(); |
| } |
| let list = source.split(this.domainSeparator); |
| if (list.length == 1 && list[0][0] != "~") |
| { |
| // Fast track for the common one-domain scenario |
| domains = new Map([["", false], [list[0], true]]); |
| } |
| else |
| @@ -480,17 +480,17 @@ |
| if (!this.domains) |
| return true; |
| // If the document has no host name, match only if the filter |
| // isn't restricted to specific domains |
| if (!docDomain) |
| return this.domains.get(""); |
| - docDomain = docDomain.replace(/\.+$/, "").toUpperCase(); |
| + docDomain = docDomain.replace(/\.+$/, "").toLowerCase(); |
| while (true) |
| { |
| let isDomainIncluded = this.domains.get(docDomain); |
| if (typeof isDomainIncluded != "undefined") |
| return isDomainIncluded; |
| let nextDot = docDomain.indexOf("."); |
| @@ -506,17 +506,17 @@ |
| * @param {string} docDomain |
| * @return {boolean} |
| */ |
| isActiveOnlyOnDomain(docDomain) |
| { |
| if (!docDomain || !this.domains || this.domains.get("")) |
| return false; |
| - docDomain = docDomain.replace(/\.+$/, "").toUpperCase(); |
| + docDomain = docDomain.replace(/\.+$/, "").toLowerCase(); |
| for (let [domain, isIncluded] of this.domains) |
| { |
| if (isIncluded && domain != docDomain) |
| { |
| if (domain.length <= docDomain.length) |
| return false; |
| @@ -607,19 +607,19 @@ |
| // No need to convert this filter to regular expression yet, do it on demand |
| this.regexpSource = regexpSource; |
| } |
| } |
| exports.RegExpFilter = RegExpFilter; |
| RegExpFilter.prototype = extend(ActiveFilter, { |
| /** |
| - * @see ActiveFilter.domainSourceIsUpperCase |
| + * @see ActiveFilter.domainSourceIsLowerCase |
| */ |
| - domainSourceIsUpperCase: true, |
| + domainSourceIsLowerCase: true, |
| /** |
| * Number of filters contained, will always be 1 (required to |
| * optimize Matcher). |
| * @type {number} |
| */ |
| length: 1, |
| @@ -750,50 +750,67 @@ |
| { |
| let value = null; |
| let separatorIndex = option.indexOf("="); |
| if (separatorIndex >= 0) |
| { |
| value = option.substr(separatorIndex + 1); |
| option = option.substr(0, separatorIndex); |
| } |
| - option = option.replace(/-/, "_").toUpperCase(); |
| - if (option in RegExpFilter.typeMap) |
| - { |
| - contentType |= RegExpFilter.typeMap[option]; |
| + |
| + let inverse = option[0] == "~"; |
|
Manish Jethani
2018/06/08 05:00:41
I'm just calling it "inverse" because "option" is
kzar
2018/06/08 09:30:32
Acknowledged.
|
| + if (inverse) |
| + option = option.substr(1); |
| - if (option == "CSP" && value) |
| - csp = value; |
| - } |
| - else if (option[0] == "~" && option.substr(1) in RegExpFilter.typeMap) |
| + let type = RegExpFilter.typeMap[option.replace(/-/, "_").toUpperCase()]; |
|
Manish Jethani
2018/06/08 05:00:41
Lookup happens only once in the RegExpFilter.typeM
kzar
2018/06/08 09:30:32
Nice.
|
| + if (type) |
| { |
| - if (contentType == null) |
| - ({contentType} = RegExpFilter.prototype); |
| - contentType &= ~RegExpFilter.typeMap[option.substr(1)]; |
| + if (inverse) |
| + { |
| + if (contentType == null) |
| + ({contentType} = RegExpFilter.prototype); |
| + contentType &= ~type; |
| + } |
| + else |
| + { |
| + contentType |= type; |
| + |
| + if (type == RegExpFilter.typeMap.CSP && value) |
|
Manish Jethani
2018/06/08 05:00:41
Integer comparison.
|
| + csp = value; |
| + } |
| } |
| - else if (option == "MATCH_CASE") |
| - matchCase = true; |
| - else if (option == "~MATCH_CASE") |
| - matchCase = false; |
| - else if (option == "DOMAIN" && value) |
| - domains = value.toUpperCase(); |
| - else if (option == "THIRD_PARTY") |
| - thirdParty = true; |
| - else if (option == "~THIRD_PARTY") |
| - thirdParty = false; |
| - else if (option == "COLLAPSE") |
| - collapse = true; |
| - else if (option == "~COLLAPSE") |
| - collapse = false; |
| - else if (option == "SITEKEY" && value) |
| - sitekeys = value.toUpperCase(); |
| - else if (option == "REWRITE" && value) |
| - rewrite = value; |
| else |
| - return new InvalidFilter(origText, "filter_unknown_option"); |
| + { |
| + switch (option.toLowerCase()) |
|
Manish Jethani
2018/06/08 05:00:41
Only lowercase if we get this far.
switch is clea
|
| + { |
| + case "match-case": |
| + matchCase = !inverse; |
|
Manish Jethani
2018/06/08 05:00:41
!inverse
kzar
2018/06/08 09:30:31
(Heh, it does make you wonder if storing !inverse
|
| + break; |
| + case "domain": |
| + if (value) |
|
Manish Jethani
2018/06/08 05:00:41
Note: This has a good side effect. Previously foo$
kzar
2018/06/08 09:30:32
Seems reasonable to me, but I wonder if this was i
sergei
2018/06/08 13:28:11
Formally, if the option is present and there are n
Manish Jethani
2018/06/08 14:12:39
For known options that must have a value but none
|
| + domains = value.toLowerCase(); |
| + break; |
| + case "third-party": |
| + thirdParty = !inverse; |
| + break; |
| + case "collapse": |
| + collapse = !inverse; |
| + break; |
| + case "sitekey": |
| + if (value) |
| + sitekeys = value.toUpperCase(); |
| + break; |
| + case "rewrite": |
| + if (value) |
|
Manish Jethani
2018/06/08 05:00:41
Note that this also simplifies how we can accept t
kzar
2018/06/08 09:30:31
Acknowledged.
|
| + rewrite = value; |
| + break; |
| + default: |
| + return new InvalidFilter(origText, "filter_unknown_option"); |
| + } |
| + } |
| } |
| } |
| // For security reasons, never match $rewrite filters |
| // against requests that might load any code to be executed. |
| if (rewrite != null) |
| { |
| if (contentType == null) |