@@ -30,32 +30,38 @@ public function __construct(
3030 * Rely on security.ipv6_normalized_subnet_size, defaults to 56
3131 */
3232 private function getIPv6Subnet (string $ ip ): string {
33- if ($ ip[ 0 ] === '[ ' && $ ip[- 1 ] === '] ' ) { // If IP is with brackets, for example [::1]
34- $ ip = substr ($ ip , 1 , strlen ( $ ip ) - 2 );
33+ if (str_starts_with ( $ ip, '[ ' ) && str_ends_with ( $ ip, '] ' )) {
34+ $ ip = substr ($ ip , 1 , - 1 );
3535 }
36- $ pos = strpos ($ ip , '% ' ); // if there is an explicit interface added to the IP, e.g. fe80::ae2d:d1e7:fe1e:9a8d%enp2s0
36+
37+ // Remove explicit interface if present (e.g., %enp2s0)
38+ $ pos = strpos ($ ip , '% ' );
3739 if ($ pos !== false ) {
38- $ ip = substr ($ ip , 0 , $ pos - 1 );
40+ $ ip = substr ($ ip , 0 , $ pos );
3941 }
4042
4143 $ config = \OCP \Server::get (IConfig::class);
42- $ maskSize = min (64 , $ config ->getSystemValueInt ('security.ipv6_normalized_subnet_size ' , 56 ));
43- $ maskSize = max (32 , $ maskSize );
44+ $ maskSize = min (64 , max (32 , $ config ->getSystemValueInt ('security.ipv6_normalized_subnet_size ' , 56 )));
45+
46+ $ binary = inet_pton ($ ip );
47+ if ($ binary === false ) {
48+ return $ ip . '/ ' . $ maskSize ;
49+ }
50+
4451 if (PHP_INT_SIZE === 4 ) {
45- if ($ maskSize === 64 ) {
46- $ value = -1 ;
47- } elseif ($ maskSize === 63 ) {
48- $ value = PHP_INT_MAX ;
49- } else {
50- $ value = (1 << $ maskSize - 32 ) - 1 ;
51- }
52+ // 32-bit PHP
53+ $ value = match ($ maskSize ) {
54+ 64 => -1 ,
55+ 63 => PHP_INT_MAX ,
56+ default => (1 << ($ maskSize - 32 )) - 1 ,
57+ };
5258 // as long as we support 32bit PHP we cannot use the `P` pack formatter (and not overflow 32bit integer)
5359 $ mask = pack ('VVVV ' , -1 , $ value , 0 , 0 );
5460 } else {
55- $ mask = pack ('VVP ' , (1 << 32 ) - 1 , (1 << $ maskSize - 32 ) - 1 , 0 );
61+ // 64-bit PHP
62+ $ mask = pack ('VVP ' , (1 << 32 ) - 1 , (1 << ($ maskSize - 32 )) - 1 , 0 );
5663 }
5764
58- $ binary = \inet_pton ($ ip );
5965 return inet_ntop ($ binary & $ mask ) . '/ ' . $ maskSize ;
6066 }
6167
@@ -67,7 +73,7 @@ private function getIPv6Subnet(string $ip): string {
6773 */
6874 private function getEmbeddedIpv4 (string $ ipv6 ): ?string {
6975 $ binary = inet_pton ($ ipv6 );
70- if (! $ binary ) {
76+ if ($ binary === false ) {
7177 return null ;
7278 }
7379
@@ -79,7 +85,6 @@ private function getEmbeddedIpv4(string $ipv6): ?string {
7985 return inet_ntop (substr ($ binary , -4 ));
8086 }
8187
82-
8388 /**
8489 * Gets either the /32 (IPv4) or the /56 (default for IPv6) subnet of an IP address
8590 */
0 commit comments