| OLD | NEW |
| 1 /* | 1 /* |
| 2 * This file is part of Adblock Plus <https://adblockplus.org/>, | 2 * This file is part of Adblock Plus <https://adblockplus.org/>, |
| 3 * Copyright (C) 2006-present eyeo GmbH | 3 * Copyright (C) 2006-present eyeo GmbH |
| 4 * | 4 * |
| 5 * Adblock Plus is free software: you can redistribute it and/or modify | 5 * Adblock Plus is free software: you can redistribute it and/or modify |
| 6 * it under the terms of the GNU General Public License version 3 as | 6 * it under the terms of the GNU General Public License version 3 as |
| 7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
| 8 * | 8 * |
| 9 * Adblock Plus is distributed in the hope that it will be useful, | 9 * Adblock Plus is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| (...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 domainSource: null, | 380 domainSource: null, |
| 381 | 381 |
| 382 /** | 382 /** |
| 383 * Separator character used in domainSource property, must be | 383 * Separator character used in domainSource property, must be |
| 384 * overridden by subclasses | 384 * overridden by subclasses |
| 385 * @type {string} | 385 * @type {string} |
| 386 */ | 386 */ |
| 387 domainSeparator: null, | 387 domainSeparator: null, |
| 388 | 388 |
| 389 /** | 389 /** |
| 390 * Determines whether domainSource is already upper-case, | 390 * Determines whether domainSource is already lower-case, |
| 391 * can be overridden by subclasses. | 391 * can be overridden by subclasses. |
| 392 * @type {boolean} | 392 * @type {boolean} |
| 393 */ | 393 */ |
| 394 domainSourceIsUpperCase: false, | 394 domainSourceIsLowerCase: false, |
| 395 | 395 |
| 396 /** | 396 /** |
| 397 * Map containing domains that this filter should match on/not match | 397 * Map containing domains that this filter should match on/not match |
| 398 * on or null if the filter should match on all domains | 398 * on or null if the filter should match on all domains |
| 399 * @type {?Map.<string,boolean>} | 399 * @type {?Map.<string,boolean>} |
| 400 */ | 400 */ |
| 401 get domains() | 401 get domains() |
| 402 { | 402 { |
| 403 // Despite this property being cached, the getter is called | 403 // Despite this property being cached, the getter is called |
| 404 // several times on Safari, due to WebKit bug 132872 | 404 // several times on Safari, due to WebKit bug 132872 |
| 405 let prop = Object.getOwnPropertyDescriptor(this, "domains"); | 405 let prop = Object.getOwnPropertyDescriptor(this, "domains"); |
| 406 if (prop) | 406 if (prop) |
| 407 return prop.value; | 407 return prop.value; |
| 408 | 408 |
| 409 let domains = null; | 409 let domains = null; |
| 410 | 410 |
| 411 if (this.domainSource) | 411 if (this.domainSource) |
| 412 { | 412 { |
| 413 let source = this.domainSource; | 413 let source = this.domainSource; |
| 414 if (!this.domainSourceIsUpperCase) | 414 if (!this.domainSourceIsLowerCase) |
| 415 { | 415 { |
| 416 // RegExpFilter already have uppercase domains | 416 // RegExpFilter already have lowercase domains |
| 417 source = source.toUpperCase(); | 417 source = source.toLowerCase(); |
| 418 } | 418 } |
| 419 let list = source.split(this.domainSeparator); | 419 let list = source.split(this.domainSeparator); |
| 420 if (list.length == 1 && list[0][0] != "~") | 420 if (list.length == 1 && list[0][0] != "~") |
| 421 { | 421 { |
| 422 // Fast track for the common one-domain scenario | 422 // Fast track for the common one-domain scenario |
| 423 domains = new Map([["", false], [list[0], true]]); | 423 domains = new Map([["", false], [list[0], true]]); |
| 424 } | 424 } |
| 425 else | 425 else |
| 426 { | 426 { |
| 427 let hasIncludes = false; | 427 let hasIncludes = false; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 484 | 484 |
| 485 // If no domains are set the rule matches everywhere | 485 // If no domains are set the rule matches everywhere |
| 486 if (!this.domains) | 486 if (!this.domains) |
| 487 return true; | 487 return true; |
| 488 | 488 |
| 489 // If the document has no host name, match only if the filter | 489 // If the document has no host name, match only if the filter |
| 490 // isn't restricted to specific domains | 490 // isn't restricted to specific domains |
| 491 if (!docDomain) | 491 if (!docDomain) |
| 492 return this.domains.get(""); | 492 return this.domains.get(""); |
| 493 | 493 |
| 494 docDomain = docDomain.replace(/\.+$/, "").toUpperCase(); | 494 docDomain = docDomain.replace(/\.+$/, "").toLowerCase(); |
| 495 | 495 |
| 496 while (true) | 496 while (true) |
| 497 { | 497 { |
| 498 let isDomainIncluded = this.domains.get(docDomain); | 498 let isDomainIncluded = this.domains.get(docDomain); |
| 499 if (typeof isDomainIncluded != "undefined") | 499 if (typeof isDomainIncluded != "undefined") |
| 500 return isDomainIncluded; | 500 return isDomainIncluded; |
| 501 | 501 |
| 502 let nextDot = docDomain.indexOf("."); | 502 let nextDot = docDomain.indexOf("."); |
| 503 if (nextDot < 0) | 503 if (nextDot < 0) |
| 504 break; | 504 break; |
| 505 docDomain = docDomain.substr(nextDot + 1); | 505 docDomain = docDomain.substr(nextDot + 1); |
| 506 } | 506 } |
| 507 return this.domains.get(""); | 507 return this.domains.get(""); |
| 508 }, | 508 }, |
| 509 | 509 |
| 510 /** | 510 /** |
| 511 * Checks whether this filter is active only on a domain and its subdomains. | 511 * Checks whether this filter is active only on a domain and its subdomains. |
| 512 * @param {string} docDomain | 512 * @param {string} docDomain |
| 513 * @return {boolean} | 513 * @return {boolean} |
| 514 */ | 514 */ |
| 515 isActiveOnlyOnDomain(docDomain) | 515 isActiveOnlyOnDomain(docDomain) |
| 516 { | 516 { |
| 517 if (!docDomain || !this.domains || this.domains.get("")) | 517 if (!docDomain || !this.domains || this.domains.get("")) |
| 518 return false; | 518 return false; |
| 519 | 519 |
| 520 docDomain = docDomain.replace(/\.+$/, "").toUpperCase(); | 520 docDomain = docDomain.replace(/\.+$/, "").toLowerCase(); |
| 521 | 521 |
| 522 for (let [domain, isIncluded] of this.domains) | 522 for (let [domain, isIncluded] of this.domains) |
| 523 { | 523 { |
| 524 if (isIncluded && domain != docDomain) | 524 if (isIncluded && domain != docDomain) |
| 525 { | 525 { |
| 526 if (domain.length <= docDomain.length) | 526 if (domain.length <= docDomain.length) |
| 527 return false; | 527 return false; |
| 528 | 528 |
| 529 if (!domain.endsWith("." + docDomain)) | 529 if (!domain.endsWith("." + docDomain)) |
| 530 return false; | 530 return false; |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 611 else | 611 else |
| 612 { | 612 { |
| 613 // No need to convert this filter to regular expression yet, do it on demand | 613 // No need to convert this filter to regular expression yet, do it on demand |
| 614 this.regexpSource = regexpSource; | 614 this.regexpSource = regexpSource; |
| 615 } | 615 } |
| 616 } | 616 } |
| 617 exports.RegExpFilter = RegExpFilter; | 617 exports.RegExpFilter = RegExpFilter; |
| 618 | 618 |
| 619 RegExpFilter.prototype = extend(ActiveFilter, { | 619 RegExpFilter.prototype = extend(ActiveFilter, { |
| 620 /** | 620 /** |
| 621 * @see ActiveFilter.domainSourceIsUpperCase | 621 * @see ActiveFilter.domainSourceIsLowerCase |
| 622 */ | 622 */ |
| 623 domainSourceIsUpperCase: true, | 623 domainSourceIsLowerCase: true, |
| 624 | 624 |
| 625 /** | 625 /** |
| 626 * Number of filters contained, will always be 1 (required to | 626 * Number of filters contained, will always be 1 (required to |
| 627 * optimize Matcher). | 627 * optimize Matcher). |
| 628 * @type {number} | 628 * @type {number} |
| 629 */ | 629 */ |
| 630 length: 1, | 630 length: 1, |
| 631 | 631 |
| 632 /** | 632 /** |
| 633 * @see ActiveFilter.domainSeparator | 633 * @see ActiveFilter.domainSeparator |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 766 text = match.input.substr(0, match.index); | 766 text = match.input.substr(0, match.index); |
| 767 for (let option of options) | 767 for (let option of options) |
| 768 { | 768 { |
| 769 let value = null; | 769 let value = null; |
| 770 let separatorIndex = option.indexOf("="); | 770 let separatorIndex = option.indexOf("="); |
| 771 if (separatorIndex >= 0) | 771 if (separatorIndex >= 0) |
| 772 { | 772 { |
| 773 value = option.substr(separatorIndex + 1); | 773 value = option.substr(separatorIndex + 1); |
| 774 option = option.substr(0, separatorIndex); | 774 option = option.substr(0, separatorIndex); |
| 775 } | 775 } |
| 776 option = option.replace(/-/, "_").toUpperCase(); | 776 let type = (option[0] == "~" ? option.substr(1) : option) |
| 777 if (option in RegExpFilter.typeMap) | 777 .replace(/-/, "_").toUpperCase(); |
| 778 option = option.toLowerCase(); |
| 779 if (type in RegExpFilter.typeMap) |
| 778 { | 780 { |
| 779 if (contentType == null) | 781 if (option[0] == "~") |
| 780 contentType = 0; | 782 { |
| 781 contentType |= RegExpFilter.typeMap[option]; | 783 if (contentType == null) |
| 784 ({contentType} = RegExpFilter.prototype); |
| 785 contentType &= ~RegExpFilter.typeMap[type]; |
| 786 } |
| 787 else |
| 788 { |
| 789 if (contentType == null) |
| 790 contentType = 0; |
| 791 contentType |= RegExpFilter.typeMap[type]; |
| 782 | 792 |
| 783 if (option == "CSP" && value) | 793 if (type == "CSP" && value) |
| 784 csp = value; | 794 csp = value; |
| 795 } |
| 785 } | 796 } |
| 786 else if (option[0] == "~" && option.substr(1) in RegExpFilter.typeMap) | 797 else if (option == "match-case") |
| 787 { | |
| 788 if (contentType == null) | |
| 789 ({contentType} = RegExpFilter.prototype); | |
| 790 contentType &= ~RegExpFilter.typeMap[option.substr(1)]; | |
| 791 } | |
| 792 else if (option == "MATCH_CASE") | |
| 793 matchCase = true; | 798 matchCase = true; |
| 794 else if (option == "~MATCH_CASE") | 799 else if (option == "~match-case") |
| 795 matchCase = false; | 800 matchCase = false; |
| 796 else if (option == "DOMAIN" && value) | 801 else if (option == "domain" && value) |
| 797 domains = value.toUpperCase(); | 802 domains = value.toLowerCase(); |
| 798 else if (option == "THIRD_PARTY") | 803 else if (option == "third-party") |
| 799 thirdParty = true; | 804 thirdParty = true; |
| 800 else if (option == "~THIRD_PARTY") | 805 else if (option == "~third-party") |
| 801 thirdParty = false; | 806 thirdParty = false; |
| 802 else if (option == "COLLAPSE") | 807 else if (option == "collapse") |
| 803 collapse = true; | 808 collapse = true; |
| 804 else if (option == "~COLLAPSE") | 809 else if (option == "~collapse") |
| 805 collapse = false; | 810 collapse = false; |
| 806 else if (option == "SITEKEY" && value) | 811 else if (option == "sitekey" && value) |
| 807 sitekeys = value.toUpperCase(); | 812 sitekeys = value.toUpperCase(); |
| 808 else if (option == "REWRITE" && value) | 813 else if (option == "rewrite" && value) |
| 809 rewrite = value; | 814 rewrite = value; |
| 810 else | 815 else |
| 811 return new InvalidFilter(origText, "filter_unknown_option"); | 816 return new InvalidFilter(origText, "filter_unknown_option"); |
| 812 } | 817 } |
| 813 } | 818 } |
| 814 | 819 |
| 815 // For security reasons, never match $rewrite filters | 820 // For security reasons, never match $rewrite filters |
| 816 // against requests that might load any code to be executed. | 821 // against requests that might load any code to be executed. |
| 817 if (rewrite != null) | 822 if (rewrite != null) |
| 818 { | 823 { |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1100 */ | 1105 */ |
| 1101 function ElemHideEmulationFilter(text, domains, selector) | 1106 function ElemHideEmulationFilter(text, domains, selector) |
| 1102 { | 1107 { |
| 1103 ElemHideBase.call(this, text, domains, selector); | 1108 ElemHideBase.call(this, text, domains, selector); |
| 1104 } | 1109 } |
| 1105 exports.ElemHideEmulationFilter = ElemHideEmulationFilter; | 1110 exports.ElemHideEmulationFilter = ElemHideEmulationFilter; |
| 1106 | 1111 |
| 1107 ElemHideEmulationFilter.prototype = extend(ElemHideBase, { | 1112 ElemHideEmulationFilter.prototype = extend(ElemHideBase, { |
| 1108 type: "elemhideemulation" | 1113 type: "elemhideemulation" |
| 1109 }); | 1114 }); |
| OLD | NEW |