| 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 670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 681 * @param {boolean} [matchCase] | 681 * @param {boolean} [matchCase] |
| 682 * Defines whether the filter should distinguish between lower and upper case | 682 * Defines whether the filter should distinguish between lower and upper case |
| 683 * letters | 683 * letters |
| 684 * @param {string} [domains] | 684 * @param {string} [domains] |
| 685 * Domains that the filter is restricted to, e.g. "foo.com|bar.com|~baz.com" | 685 * Domains that the filter is restricted to, e.g. "foo.com|bar.com|~baz.com" |
| 686 * @param {boolean} [thirdParty] | 686 * @param {boolean} [thirdParty] |
| 687 * Defines whether the filter should apply to third-party or first-party | 687 * Defines whether the filter should apply to third-party or first-party |
| 688 * content only | 688 * content only |
| 689 * @param {string} [sitekeys] | 689 * @param {string} [sitekeys] |
| 690 * Public keys of websites that this filter should apply to | 690 * Public keys of websites that this filter should apply to |
| 691 * @param {?string} [rewrite] |
| 692 * The (optional) rule specifying how to rewrite the URL. See |
| 693 * RegExpFilter.prototype.rewrite. |
| 691 * @constructor | 694 * @constructor |
| 692 * @augments ActiveFilter | 695 * @augments ActiveFilter |
| 693 */ | 696 */ |
| 694 function RegExpFilter(text, regexpSource, contentType, matchCase, domains, | 697 function RegExpFilter(text, regexpSource, contentType, matchCase, domains, |
| 695 thirdParty, sitekeys) | 698 thirdParty, sitekeys, rewrite) |
| 696 { | 699 { |
| 697 ActiveFilter.call(this, text, domains); | 700 ActiveFilter.call(this, text, domains); |
| 698 | 701 |
| 699 if (contentType != null) | 702 if (contentType != null) |
| 700 this.contentType = contentType; | 703 this.contentType = contentType; |
| 701 if (matchCase) | 704 if (matchCase) |
| 702 this.matchCase = matchCase; | 705 this.matchCase = matchCase; |
| 703 if (thirdParty != null) | 706 if (thirdParty != null) |
| 704 this.thirdParty = thirdParty; | 707 this.thirdParty = thirdParty; |
| 705 if (sitekeys != null) | 708 if (sitekeys != null) |
| 706 this.sitekeySource = sitekeys; | 709 this.sitekeySource = sitekeys; |
| 710 if (rewrite != null) |
| 711 this.rewrite = rewrite; |
| 707 | 712 |
| 708 if (regexpSource.length >= 2 && | 713 if (regexpSource.length >= 2 && |
| 709 regexpSource[0] == "/" && | 714 regexpSource[0] == "/" && |
| 710 regexpSource[regexpSource.length - 1] == "/") | 715 regexpSource[regexpSource.length - 1] == "/") |
| 711 { | 716 { |
| 712 // The filter is a regular expression - convert it immediately to | 717 // The filter is a regular expression - convert it immediately to |
| 713 // catch syntax errors | 718 // catch syntax errors |
| 714 let regexp = new RegExp(regexpSource.substr(1, regexpSource.length - 2), | 719 let regexp = new RegExp(regexpSource.substr(1, regexpSource.length - 2), |
| 715 this.matchCase ? "" : "i"); | 720 this.matchCase ? "" : "i"); |
| 716 Object.defineProperty(this, "regexp", {value: regexp}); | 721 Object.defineProperty(this, "regexp", {value: regexp}); |
| 717 } | 722 } |
| 718 else | 723 else |
| 719 { | 724 { |
| 725 // Patterns like /foo/bar/* exist so that they are not treated as regular |
| 726 // expressions. We drop any superfluous wildcards here so our optimizations |
| 727 // can kick in. |
| 728 if (this.rewrite == null) |
| 729 regexpSource = regexpSource.replace(/^\*+/, "").replace(/\*+$/, ""); |
| 730 |
| 720 if (!this.matchCase && isLiteralPattern(regexpSource)) | 731 if (!this.matchCase && isLiteralPattern(regexpSource)) |
| 721 regexpSource = regexpSource.toLowerCase(); | 732 regexpSource = regexpSource.toLowerCase(); |
| 722 | 733 |
| 723 // No need to convert this filter to regular expression yet, do it on demand | 734 // No need to convert this filter to regular expression yet, do it on demand |
| 724 this.pattern = regexpSource; | 735 this.pattern = regexpSource; |
| 725 } | 736 } |
| 726 } | 737 } |
| 727 exports.RegExpFilter = RegExpFilter; | 738 exports.RegExpFilter = RegExpFilter; |
| 728 | 739 |
| 729 RegExpFilter.prototype = extend(ActiveFilter, { | 740 RegExpFilter.prototype = extend(ActiveFilter, { |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 801 this.sitekeySource = null; | 812 this.sitekeySource = null; |
| 802 } | 813 } |
| 803 | 814 |
| 804 Object.defineProperty( | 815 Object.defineProperty( |
| 805 this, "sitekeys", {value: sitekeys, enumerable: true} | 816 this, "sitekeys", {value: sitekeys, enumerable: true} |
| 806 ); | 817 ); |
| 807 return this.sitekeys; | 818 return this.sitekeys; |
| 808 }, | 819 }, |
| 809 | 820 |
| 810 /** | 821 /** |
| 822 * The rule specifying how to rewrite the URL. |
| 823 * The syntax is similar to the one of String.prototype.replace(). |
| 824 * @type {?string} |
| 825 */ |
| 826 rewrite: null, |
| 827 |
| 828 /** |
| 811 * Tests whether the URL matches this filter | 829 * Tests whether the URL matches this filter |
| 812 * @param {string} location URL to be tested | 830 * @param {string} location URL to be tested |
| 813 * @param {number} typeMask bitmask of content / request types to match | 831 * @param {number} typeMask bitmask of content / request types to match |
| 814 * @param {string} [docDomain] domain name of the document that loads the URL | 832 * @param {string} [docDomain] domain name of the document that loads the URL |
| 815 * @param {boolean} [thirdParty] should be true if the URL is a third-party | 833 * @param {boolean} [thirdParty] should be true if the URL is a third-party |
| 816 * request | 834 * request |
| 817 * @param {string} [sitekey] public key provided by the document | 835 * @param {string} [sitekey] public key provided by the document |
| 818 * @return {boolean} true in case of a match | 836 * @return {boolean} true in case of a match |
| 819 */ | 837 */ |
| 820 matches(location, typeMask, docDomain, thirdParty, sitekey) | 838 matches(location, typeMask, docDomain, thirdParty, sitekey) |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 990 } | 1008 } |
| 991 | 1009 |
| 992 try | 1010 try |
| 993 { | 1011 { |
| 994 if (blocking) | 1012 if (blocking) |
| 995 { | 1013 { |
| 996 if (csp && Filter.invalidCSPRegExp.test(csp)) | 1014 if (csp && Filter.invalidCSPRegExp.test(csp)) |
| 997 return new InvalidFilter(origText, "filter_invalid_csp"); | 1015 return new InvalidFilter(origText, "filter_invalid_csp"); |
| 998 | 1016 |
| 999 return new BlockingFilter(origText, text, contentType, matchCase, domains, | 1017 return new BlockingFilter(origText, text, contentType, matchCase, domains, |
| 1000 thirdParty, sitekeys, collapse, csp, rewrite); | 1018 thirdParty, sitekeys, rewrite, collapse, csp); |
| 1001 } | 1019 } |
| 1002 return new WhitelistFilter(origText, text, contentType, matchCase, domains, | 1020 return new WhitelistFilter(origText, text, contentType, matchCase, domains, |
| 1003 thirdParty, sitekeys); | 1021 thirdParty, sitekeys); |
| 1004 } | 1022 } |
| 1005 catch (e) | 1023 catch (e) |
| 1006 { | 1024 { |
| 1007 return new InvalidFilter(origText, "filter_invalid_regexp"); | 1025 return new InvalidFilter(origText, "filter_invalid_regexp"); |
| 1008 } | 1026 } |
| 1009 }; | 1027 }; |
| 1010 | 1028 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1049 | 1067 |
| 1050 /** | 1068 /** |
| 1051 * Class for blocking filters | 1069 * Class for blocking filters |
| 1052 * @param {string} text see {@link Filter Filter()} | 1070 * @param {string} text see {@link Filter Filter()} |
| 1053 * @param {string} regexpSource see {@link RegExpFilter RegExpFilter()} | 1071 * @param {string} regexpSource see {@link RegExpFilter RegExpFilter()} |
| 1054 * @param {number} [contentType] see {@link RegExpFilter RegExpFilter()} | 1072 * @param {number} [contentType] see {@link RegExpFilter RegExpFilter()} |
| 1055 * @param {boolean} [matchCase] see {@link RegExpFilter RegExpFilter()} | 1073 * @param {boolean} [matchCase] see {@link RegExpFilter RegExpFilter()} |
| 1056 * @param {string} [domains] see {@link RegExpFilter RegExpFilter()} | 1074 * @param {string} [domains] see {@link RegExpFilter RegExpFilter()} |
| 1057 * @param {boolean} [thirdParty] see {@link RegExpFilter RegExpFilter()} | 1075 * @param {boolean} [thirdParty] see {@link RegExpFilter RegExpFilter()} |
| 1058 * @param {string} [sitekeys] see {@link RegExpFilter RegExpFilter()} | 1076 * @param {string} [sitekeys] see {@link RegExpFilter RegExpFilter()} |
| 1077 * @param {?string} [rewrite] |
| 1078 * The (optional) rule specifying how to rewrite the URL. See |
| 1079 * RegExpFilter.prototype.rewrite. |
| 1059 * @param {boolean} [collapse] | 1080 * @param {boolean} [collapse] |
| 1060 * defines whether the filter should collapse blocked content, can be null | 1081 * defines whether the filter should collapse blocked content, can be null |
| 1061 * @param {string} [csp] | 1082 * @param {string} [csp] |
| 1062 * Content Security Policy to inject when the filter matches | 1083 * Content Security Policy to inject when the filter matches |
| 1063 * @param {?string} [rewrite] | |
| 1064 * The (optional) rule specifying how to rewrite the URL. See | |
| 1065 * BlockingFilter.prototype.rewrite. | |
| 1066 * @constructor | 1084 * @constructor |
| 1067 * @augments RegExpFilter | 1085 * @augments RegExpFilter |
| 1068 */ | 1086 */ |
| 1069 function BlockingFilter(text, regexpSource, contentType, matchCase, domains, | 1087 function BlockingFilter(text, regexpSource, contentType, matchCase, domains, |
| 1070 thirdParty, sitekeys, collapse, csp, rewrite) | 1088 thirdParty, sitekeys, rewrite, collapse, csp) |
| 1071 { | 1089 { |
| 1072 RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, | 1090 RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, |
| 1073 thirdParty, sitekeys); | 1091 thirdParty, sitekeys, rewrite); |
| 1074 | 1092 |
| 1075 if (collapse != null) | 1093 if (collapse != null) |
| 1076 this.collapse = collapse; | 1094 this.collapse = collapse; |
| 1077 | 1095 |
| 1078 if (csp != null) | 1096 if (csp != null) |
| 1079 this.csp = csp; | 1097 this.csp = csp; |
| 1080 | |
| 1081 if (rewrite != null) | |
| 1082 this.rewrite = rewrite; | |
| 1083 } | 1098 } |
| 1084 exports.BlockingFilter = BlockingFilter; | 1099 exports.BlockingFilter = BlockingFilter; |
| 1085 | 1100 |
| 1086 BlockingFilter.prototype = extend(RegExpFilter, { | 1101 BlockingFilter.prototype = extend(RegExpFilter, { |
| 1087 type: "blocking", | 1102 type: "blocking", |
| 1088 | 1103 |
| 1089 /** | 1104 /** |
| 1090 * Defines whether the filter should collapse blocked content. | 1105 * Defines whether the filter should collapse blocked content. |
| 1091 * Can be null (use the global preference). | 1106 * Can be null (use the global preference). |
| 1092 * @type {?boolean} | 1107 * @type {?boolean} |
| 1093 */ | 1108 */ |
| 1094 collapse: null, | 1109 collapse: null, |
| 1095 | 1110 |
| 1096 /** | 1111 /** |
| 1097 * Content Security Policy to inject for matching requests. | 1112 * Content Security Policy to inject for matching requests. |
| 1098 * @type {?string} | 1113 * @type {?string} |
| 1099 */ | 1114 */ |
| 1100 csp: null, | 1115 csp: null, |
| 1101 | 1116 |
| 1102 /** | 1117 /** |
| 1103 * The rule specifying how to rewrite the URL. | |
| 1104 * The syntax is similar to the one of String.prototype.replace(). | |
| 1105 * @type {?string} | |
| 1106 */ | |
| 1107 rewrite: null, | |
| 1108 | |
| 1109 /** | |
| 1110 * Rewrites an URL. | 1118 * Rewrites an URL. |
| 1111 * @param {string} url the URL to rewrite | 1119 * @param {string} url the URL to rewrite |
| 1112 * @return {string} the rewritten URL, or the original in case of failure | 1120 * @return {string} the rewritten URL, or the original in case of failure |
| 1113 */ | 1121 */ |
| 1114 rewriteUrl(url) | 1122 rewriteUrl(url) |
| 1115 { | 1123 { |
| 1116 try | 1124 try |
| 1117 { | 1125 { |
| 1118 let rewrittenUrl = new URL(url.replace(this.regexp, this.rewrite), url); | 1126 let rewrittenUrl = new URL(url.replace(this.regexp, this.rewrite), url); |
| 1119 if (rewrittenUrl.origin == new URL(url).origin) | 1127 if (rewrittenUrl.origin == new URL(url).origin) |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1353 | 1361 |
| 1354 /** | 1362 /** |
| 1355 * Script that should be executed | 1363 * Script that should be executed |
| 1356 * @type {string} | 1364 * @type {string} |
| 1357 */ | 1365 */ |
| 1358 get script() | 1366 get script() |
| 1359 { | 1367 { |
| 1360 return this.body; | 1368 return this.body; |
| 1361 } | 1369 } |
| 1362 }); | 1370 }); |
| OLD | NEW |