Left: | ||
Right: |
LEFT | RIGHT |
---|---|
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 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
393 */ | 393 */ |
394 domainSourceIsLowerCase: 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 | |
404 // several times on Safari, due to WebKit bug 132872 | |
405 let prop = Object.getOwnPropertyDescriptor(this, "domains"); | |
406 if (prop) | |
407 return prop.value; | |
408 | |
409 let domains = null; | 403 let domains = null; |
410 | 404 |
411 if (this.domainSource) | 405 if (this.domainSource) |
412 { | 406 { |
413 let source = this.domainSource; | 407 let source = this.domainSource; |
414 if (!this.domainSourceIsLowerCase) | 408 if (!this.domainSourceIsLowerCase) |
415 { | 409 { |
416 // RegExpFilter already have lowercase domains | 410 // RegExpFilter already have lowercase domains |
417 source = source.toLowerCase(); | 411 source = source.toLowerCase(); |
418 } | 412 } |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
639 * for delayed creation of the regexp property | 633 * for delayed creation of the regexp property |
640 * @type {string} | 634 * @type {string} |
641 */ | 635 */ |
642 regexpSource: null, | 636 regexpSource: null, |
643 /** | 637 /** |
644 * Regular expression to be used when testing against this filter | 638 * Regular expression to be used when testing against this filter |
645 * @type {RegExp} | 639 * @type {RegExp} |
646 */ | 640 */ |
647 get regexp() | 641 get regexp() |
648 { | 642 { |
649 // Despite this property being cached, the getter is called | |
650 // several times on Safari, due to WebKit bug 132872 | |
651 let prop = Object.getOwnPropertyDescriptor(this, "regexp"); | |
652 if (prop) | |
653 return prop.value; | |
654 | |
655 let source = Filter.toRegExp(this.regexpSource); | 643 let source = Filter.toRegExp(this.regexpSource); |
656 let regexp = new RegExp(source, this.matchCase ? "" : "i"); | 644 let regexp = new RegExp(source, this.matchCase ? "" : "i"); |
657 Object.defineProperty(this, "regexp", {value: regexp}); | 645 Object.defineProperty(this, "regexp", {value: regexp}); |
658 this.regexpSource = null; | 646 this.regexpSource = null; |
659 return regexp; | 647 return regexp; |
660 }, | 648 }, |
661 /** | 649 /** |
662 * Content types the filter applies to, combination of values from | 650 * Content types the filter applies to, combination of values from |
663 * RegExpFilter.typeMap | 651 * RegExpFilter.typeMap |
664 * @type {number} | 652 * @type {number} |
(...skipping 16 matching lines...) Expand all Loading... | |
681 * String that the sitekey property should be generated from | 669 * String that the sitekey property should be generated from |
682 * @type {?string} | 670 * @type {?string} |
683 */ | 671 */ |
684 sitekeySource: null, | 672 sitekeySource: null, |
685 | 673 |
686 /** | 674 /** |
687 * @see ActiveFilter.sitekeys | 675 * @see ActiveFilter.sitekeys |
688 */ | 676 */ |
689 get sitekeys() | 677 get sitekeys() |
690 { | 678 { |
691 // Despite this property being cached, the getter is called | |
692 // several times on Safari, due to WebKit bug 132872 | |
693 let prop = Object.getOwnPropertyDescriptor(this, "sitekeys"); | |
694 if (prop) | |
695 return prop.value; | |
696 | |
697 let sitekeys = null; | 679 let sitekeys = null; |
698 | 680 |
699 if (this.sitekeySource) | 681 if (this.sitekeySource) |
700 { | 682 { |
701 sitekeys = this.sitekeySource.split("|"); | 683 sitekeys = this.sitekeySource.split("|"); |
702 this.sitekeySource = null; | 684 this.sitekeySource = null; |
703 } | 685 } |
704 | 686 |
705 Object.defineProperty( | 687 Object.defineProperty( |
706 this, "sitekeys", {value: sitekeys, enumerable: true} | 688 this, "sitekeys", {value: sitekeys, enumerable: true} |
(...skipping 30 matching lines...) Expand all Loading... | |
737 | 719 |
738 /** | 720 /** |
739 * Creates a RegExp filter from its text representation | 721 * Creates a RegExp filter from its text representation |
740 * @param {string} text same as in Filter() | 722 * @param {string} text same as in Filter() |
741 * @return {Filter} | 723 * @return {Filter} |
742 */ | 724 */ |
743 RegExpFilter.fromText = function(text) | 725 RegExpFilter.fromText = function(text) |
744 { | 726 { |
745 let blocking = true; | 727 let blocking = true; |
746 let origText = text; | 728 let origText = text; |
747 if (text.indexOf("@@") == 0) | 729 if (text[0] == "@" && text[1] == "@") |
748 { | 730 { |
749 blocking = false; | 731 blocking = false; |
750 text = text.substr(2); | 732 text = text.substr(2); |
751 } | 733 } |
752 | 734 |
753 let contentType = null; | 735 let contentType = null; |
754 let matchCase = null; | 736 let matchCase = null; |
755 let domains = null; | 737 let domains = null; |
756 let sitekeys = null; | 738 let sitekeys = null; |
757 let thirdParty = null; | 739 let thirdParty = null; |
758 let collapse = null; | 740 let collapse = null; |
759 let csp = null; | 741 let csp = null; |
760 let rewrite = null; | 742 let rewrite = null; |
761 let options; | 743 let options; |
762 let match = (text.indexOf("$") >= 0 ? Filter.optionsRegExp.exec(text) : null); | 744 let match = text.includes("$") ? Filter.optionsRegExp.exec(text) : null; |
763 if (match) | 745 if (match) |
764 { | 746 { |
765 options = match[1].split(","); | 747 options = match[1].split(","); |
766 text = match.input.substr(0, match.index); | 748 text = match.input.substr(0, match.index); |
767 for (let option of options) | 749 for (let option of options) |
768 { | 750 { |
769 let value = null; | 751 let value = null; |
770 let separatorIndex = option.indexOf("="); | 752 let separatorIndex = option.indexOf("="); |
771 if (separatorIndex >= 0) | 753 if (separatorIndex >= 0) |
772 { | 754 { |
773 value = option.substr(separatorIndex + 1); | 755 value = option.substr(separatorIndex + 1); |
774 option = option.substr(0, separatorIndex); | 756 option = option.substr(0, separatorIndex); |
775 } | 757 } |
776 let type = (option[0] == "~" ? option.substr(1) : option) | 758 |
Manish Jethani
2018/06/06 14:59:13
This part may seem unrelated but the goal is to av
| |
777 .replace(/-/, "_").toUpperCase(); | 759 let inverse = option[0] == "~"; |
778 option = option.toLowerCase(); | 760 if (inverse) |
779 if (type in RegExpFilter.typeMap) | 761 option = option.substr(1); |
762 | |
763 let type = RegExpFilter.typeMap[option.replace(/-/, "_").toUpperCase()]; | |
764 if (type) | |
780 { | 765 { |
781 if (option[0] == "~") | 766 if (inverse) |
782 { | 767 { |
783 if (contentType == null) | 768 if (contentType == null) |
784 ({contentType} = RegExpFilter.prototype); | 769 ({contentType} = RegExpFilter.prototype); |
785 contentType &= ~RegExpFilter.typeMap[type]; | 770 contentType &= ~type; |
786 } | 771 } |
787 else | 772 else |
788 { | 773 { |
789 if (contentType == null) | 774 contentType |= type; |
790 contentType = 0; | 775 |
791 contentType |= RegExpFilter.typeMap[type]; | 776 if (type == RegExpFilter.typeMap.CSP && value) |
Manish Jethani
2018/06/08 14:21:14
By the way in the case of csp we quietly ignore th
kzar
2018/06/15 10:44:03
Yea, agreed. By the way Rosie is reimplementing th
| |
792 | |
793 if (type == "CSP" && value) | |
794 csp = value; | 777 csp = value; |
795 } | 778 } |
796 } | 779 } |
797 else if (option == "match-case") | |
798 matchCase = true; | |
799 else if (option == "~match-case") | |
800 matchCase = false; | |
801 else if (option == "domain" && value) | |
802 domains = value.toLowerCase(); | |
803 else if (option == "third-party") | |
804 thirdParty = true; | |
805 else if (option == "~third-party") | |
806 thirdParty = false; | |
807 else if (option == "collapse") | |
808 collapse = true; | |
809 else if (option == "~collapse") | |
810 collapse = false; | |
811 else if (option == "sitekey" && value) | |
812 sitekeys = value.toUpperCase(); | |
813 else if (option == "rewrite" && value) | |
814 rewrite = value; | |
815 else | 780 else |
816 return new InvalidFilter(origText, "filter_unknown_option"); | 781 { |
782 switch (option.toLowerCase()) | |
783 { | |
784 case "match-case": | |
785 matchCase = !inverse; | |
786 break; | |
787 case "domain": | |
788 if (!value) | |
789 return new InvalidFilter(origText, "filter_unknown_option"); | |
790 domains = value.toLowerCase(); | |
791 break; | |
792 case "third-party": | |
793 thirdParty = !inverse; | |
794 break; | |
795 case "collapse": | |
796 collapse = !inverse; | |
797 break; | |
798 case "sitekey": | |
799 if (!value) | |
Manish Jethani
2018/06/08 14:19:42
There's a bit of code repetition here but I'm OK w
kzar
2018/06/15 10:44:03
Yea, I think it's fine.
| |
800 return new InvalidFilter(origText, "filter_unknown_option"); | |
801 sitekeys = value.toUpperCase(); | |
802 break; | |
803 case "rewrite": | |
804 if (!value) | |
Manish Jethani
2018/06/08 14:19:42
Note that this will get updated for the rewrite op
| |
805 return new InvalidFilter(origText, "filter_unknown_option"); | |
806 rewrite = value; | |
807 break; | |
808 default: | |
809 return new InvalidFilter(origText, "filter_unknown_option"); | |
810 } | |
811 } | |
817 } | 812 } |
818 } | 813 } |
819 | 814 |
820 // For security reasons, never match $rewrite filters | 815 // For security reasons, never match $rewrite filters |
821 // against requests that might load any code to be executed. | 816 // against requests that might load any code to be executed. |
822 if (rewrite != null) | 817 if (rewrite != null) |
823 { | 818 { |
824 if (contentType == null) | 819 if (contentType == null) |
825 ({contentType} = RegExpFilter.prototype); | 820 ({contentType} = RegExpFilter.prototype); |
826 contentType &= ~(RegExpFilter.typeMap.SCRIPT | | 821 contentType &= ~(RegExpFilter.typeMap.SCRIPT | |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1105 */ | 1100 */ |
1106 function ElemHideEmulationFilter(text, domains, selector) | 1101 function ElemHideEmulationFilter(text, domains, selector) |
1107 { | 1102 { |
1108 ElemHideBase.call(this, text, domains, selector); | 1103 ElemHideBase.call(this, text, domains, selector); |
1109 } | 1104 } |
1110 exports.ElemHideEmulationFilter = ElemHideEmulationFilter; | 1105 exports.ElemHideEmulationFilter = ElemHideEmulationFilter; |
1111 | 1106 |
1112 ElemHideEmulationFilter.prototype = extend(ElemHideBase, { | 1107 ElemHideEmulationFilter.prototype = extend(ElemHideBase, { |
1113 type: "elemhideemulation" | 1108 type: "elemhideemulation" |
1114 }); | 1109 }); |
LEFT | RIGHT |