@@ -2970,14 +2970,63 @@ registerFilterClass(FilterOnHeaders);
29702970
29712971class FilterIPAddress {
29722972 static match ( idata ) {
2973+ const ipaddr = $requestAddress ;
29732974 const 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 / ^ \[ : : f f f f : ( 7 f \w { 2 } | a \w { 2 } | a 9 f e | c 0 a 8 ) : \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 [ c d ] \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 }
29823031
29833032 static compile ( details ) {
0 commit comments