Add support for `lan`/`loopback` values to `ipaddress=` option · gorhill/uBlock@030d733
@@ -2970,14 +2970,63 @@ registerFilterClass(FilterOnHeaders);
2970297029712971class FilterIPAddress {
29722972static match(idata) {
2973+const ipaddr = $requestAddress;
29732974const details = filterRefs[filterData[idata+1]];
2974-if ( details.isRegex === false ) {
2975-return $requestAddress === details.pattern;
2975+if ( details.isRegex ) {
2976+if ( details.$re === undefined ) {
2977+details.$re = new RegExp(details.pattern.slice(1, -1));
2978+}
2979+return details.$re.test(ipaddr);
2980+}
2981+if ( ipaddr === '' ) { return false; }
2982+if ( details.pattern === 'lan' ) {
2983+return this.isLAN(ipaddr);
2984+}
2985+if ( details.pattern === 'loopback' ) {
2986+return this.isLoopback(ipaddr);
2987+}
2988+return ipaddr.startsWith(details.pattern);
2989+}
2990+2991+// https://github.com/uBlockOrigin/uAssets/blob/master/filters/lan-block.txt
2992+// https://en.wikipedia.org/wiki/Reserved_IP_addresses
2993+// `ipaddr` is assumed well-formed
2994+static isLAN(ipaddr) {
2995+const c0 = ipaddr.charCodeAt(0);
2996+// ipv4
2997+if ( c0 === 0x30 /* 0 */ ) {
2998+return ipaddr.startsWith('0.');
2999+}
3000+if ( c0 === 0x31 /* 1 */ ) {
3001+if ( ipaddr.startsWith('10.') ) { return true; }
3002+if ( ipaddr.startsWith('127.') ) { return true; }
3003+if ( ipaddr.startsWith('169.254.') ) { return true; }
3004+if ( ipaddr.startsWith('172.') ) {
3005+const v = parseInt(ipaddr.slice(4), 10);
3006+return v >= 16 && v <= 31;
3007+}
3008+return ipaddr.startsWith('192.168.');
3009+}
3010+if ( c0 !== 0x5B /* [ */ ) { return false; }
3011+// ipv6
3012+const c1 = ipaddr.charCodeAt(1);
3013+if ( c1 === 0x3A /* : */ ) {
3014+if ( ipaddr.startsWith('[::') === false ) { return false; }
3015+if ( ipaddr === '[::]' || ipaddr === '[::1]' ) { return true; }
3016+if ( ipaddr.startsWith('[::ffff:') === false ) { return false; }
3017+return /^\[::ffff:(7f\w{2}|a\w{2}|a9fe|c0a8):\w+\]$/.test(ipaddr);
3018+}
3019+if ( c1 === 0x36 /* 6 */ ) {
3020+return ipaddr.startsWith('[64:ff9b:');
29763021}
2977-if ( details.$re === undefined ) {
2978-details.$re = new RegExp(details.pattern.slice(1, -1));
3022+if ( c1 === 0x66 /* f */ ) {
3023+return /^\[f[cd]\w{2}:/.test(ipaddr);
29793024}
2980-return details.$re.test($requestAddress);
3025+return false;
3026+}
3027+3028+static isLoopback(ipaddr) {
3029+return ipaddr === '127.0.0.1' || ipaddr === '[::1]';
29813030}
2982303129833032static compile(details) {