Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: lib/filterClasses.js

Issue 29912636: Issue 7052 - Use string-based matching for literal patterns (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore/
Patch Set: Abstract literal pattern test into separate function Created Oct. 17, 2018, 2:45 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | test/filterClasses.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 "use strict"; 18 "use strict";
19 19
20 /** 20 /**
21 * @fileOverview Definition of Filter class and its subclasses. 21 * @fileOverview Definition of Filter class and its subclasses.
22 */ 22 */
23 23
24 const {filterNotifier} = require("./filterNotifier"); 24 const {filterNotifier} = require("./filterNotifier");
25 const {extend} = require("./coreUtils"); 25 const {extend} = require("./coreUtils");
26 const {filterToRegExp} = require("./common"); 26 const {filterToRegExp} = require("./common");
27 27
28 let tripleAnchorRegExp = new RegExp(filterToRegExp("|||"));
29
28 /** 30 /**
29 * All known unique domain sources mapped to their parsed values. 31 * All known unique domain sources mapped to their parsed values.
30 * @type {Map.<string,Map.<string,boolean>>} 32 * @type {Map.<string,Map.<string,boolean>>}
31 */ 33 */
32 let knownDomainMaps = new Map(); 34 let knownDomainMaps = new Map();
33 35
36 function isLiteralPattern(pattern)
37 {
38 return !/[*^|]/.test(pattern.replace(/^\|{2}/, ""));
39 }
40
34 /** 41 /**
35 * Abstract base class for filters 42 * Abstract base class for filters
36 * 43 *
37 * @param {string} text string representation of the filter 44 * @param {string} text string representation of the filter
38 * @constructor 45 * @constructor
39 */ 46 */
40 function Filter(text) 47 function Filter(text)
41 { 48 {
42 this.text = text; 49 this.text = text;
43 50
(...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 regexpSource[regexpSource.length - 1] == "/") 693 regexpSource[regexpSource.length - 1] == "/")
687 { 694 {
688 // The filter is a regular expression - convert it immediately to 695 // The filter is a regular expression - convert it immediately to
689 // catch syntax errors 696 // catch syntax errors
690 let regexp = new RegExp(regexpSource.substr(1, regexpSource.length - 2), 697 let regexp = new RegExp(regexpSource.substr(1, regexpSource.length - 2),
691 this.matchCase ? "" : "i"); 698 this.matchCase ? "" : "i");
692 Object.defineProperty(this, "regexp", {value: regexp}); 699 Object.defineProperty(this, "regexp", {value: regexp});
693 } 700 }
694 else 701 else
695 { 702 {
703 if (!this.matchCase && isLiteralPattern(regexpSource))
704 regexpSource = regexpSource.toLowerCase();
705
696 // No need to convert this filter to regular expression yet, do it on demand 706 // No need to convert this filter to regular expression yet, do it on demand
697 this.pattern = regexpSource; 707 this.pattern = regexpSource;
698 } 708 }
699 } 709 }
700 exports.RegExpFilter = RegExpFilter; 710 exports.RegExpFilter = RegExpFilter;
701 711
702 RegExpFilter.prototype = extend(ActiveFilter, { 712 RegExpFilter.prototype = extend(ActiveFilter, {
703 /** 713 /**
704 * Number of filters contained, will always be 1 (required to 714 * Number of filters contained, will always be 1 (required to
705 * optimize {@link Matcher}). 715 * optimize {@link Matcher}).
(...skipping 11 matching lines...) Expand all
717 * for delayed creation of the regexp property 727 * for delayed creation of the regexp property
718 * @type {?string} 728 * @type {?string}
719 */ 729 */
720 pattern: null, 730 pattern: null,
721 /** 731 /**
722 * Regular expression to be used when testing against this filter 732 * Regular expression to be used when testing against this filter
723 * @type {RegExp} 733 * @type {RegExp}
724 */ 734 */
725 get regexp() 735 get regexp()
726 { 736 {
727 let source = filterToRegExp(this.pattern, this.rewrite != null); 737 let value = null;
728 let regexp = new RegExp(source, this.matchCase ? "" : "i"); 738
729 Object.defineProperty(this, "regexp", {value: regexp}); 739 let {pattern, rewrite} = this;
730 return regexp; 740 if (rewrite != null || !isLiteralPattern(pattern))
741 {
742 value = new RegExp(filterToRegExp(pattern, rewrite != null),
743 this.matchCase ? "" : "i");
744 }
745
746 Object.defineProperty(this, "regexp", {value});
747 return value;
731 }, 748 },
732 /** 749 /**
733 * Content types the filter applies to, combination of values from 750 * Content types the filter applies to, combination of values from
734 * RegExpFilter.typeMap 751 * RegExpFilter.typeMap
735 * @type {number} 752 * @type {number}
736 */ 753 */
737 contentType: 0x7FFFFFFF, 754 contentType: 0x7FFFFFFF,
738 /** 755 /**
739 * Defines whether the filter should distinguish between lower and 756 * Defines whether the filter should distinguish between lower and
740 * upper case letters 757 * upper case letters
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 * @param {boolean} [thirdParty] should be true if the URL is a third-party 798 * @param {boolean} [thirdParty] should be true if the URL is a third-party
782 * request 799 * request
783 * @param {string} [sitekey] public key provided by the document 800 * @param {string} [sitekey] public key provided by the document
784 * @return {boolean} true in case of a match 801 * @return {boolean} true in case of a match
785 */ 802 */
786 matches(location, typeMask, docDomain, thirdParty, sitekey) 803 matches(location, typeMask, docDomain, thirdParty, sitekey)
787 { 804 {
788 return (this.contentType & typeMask) != 0 && 805 return (this.contentType & typeMask) != 0 &&
789 (this.thirdParty == null || this.thirdParty == thirdParty) && 806 (this.thirdParty == null || this.thirdParty == thirdParty) &&
790 this.isActiveOnDomain(docDomain, sitekey) && 807 this.isActiveOnDomain(docDomain, sitekey) &&
791 this.regexp.test(location); 808 this.matchesLocation(location);
809 },
810
811 matchesLocation(location)
812 {
813 let {regexp} = this;
814
815 if (regexp)
816 return regexp.test(location);
817
818 if (!this.matchCase)
819 location = location.toLowerCase();
820
821 let {pattern} = this;
822
823 if (pattern[0] == "|" && pattern[1] == "|")
824 {
825 let index = location.indexOf(pattern.substring(2));
826 return index != -1 && location[index] != "/" &&
827 tripleAnchorRegExp.test(location.substring(0, index));
828 }
829
830 return location.includes(pattern);
792 } 831 }
793 }); 832 });
794 833
795 /** 834 /**
796 * Yields the filter itself (required to optimize {@link Matcher}). 835 * Yields the filter itself (required to optimize {@link Matcher}).
797 * @yields {RegExpFilter} 836 * @yields {RegExpFilter}
798 */ 837 */
799 RegExpFilter.prototype[Symbol.iterator] = function*() 838 RegExpFilter.prototype[Symbol.iterator] = function*()
800 { 839 {
801 yield this; 840 yield this;
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
1276 1315
1277 /** 1316 /**
1278 * Script that should be executed 1317 * Script that should be executed
1279 * @type {string} 1318 * @type {string}
1280 */ 1319 */
1281 get script() 1320 get script()
1282 { 1321 {
1283 return this.body; 1322 return this.body;
1284 } 1323 }
1285 }); 1324 });
OLDNEW
« no previous file with comments | « no previous file | test/filterClasses.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld