From f5776a968c62d495d04d189d9144b8bc4161e56d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Somogyi=20M=C3=A1rton?= Date: Sun, 18 Aug 2019 08:33:31 +0200 Subject: [PATCH] #17508 fix --- framework/helpers/BaseIpHelper.php | 18 ++++++++++++------ tests/framework/helpers/IpHelperTest.php | 8 +++++--- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/framework/helpers/BaseIpHelper.php b/framework/helpers/BaseIpHelper.php index 1548336..672f8c3 100644 --- a/framework/helpers/BaseIpHelper.php +++ b/framework/helpers/BaseIpHelper.php @@ -7,6 +7,8 @@ namespace yii\helpers; +use yii\base\NotSupportedException; + /** * Class BaseIpHelper provides concrete implementation for [[IpHelper]] * @@ -61,6 +63,7 @@ class BaseIpHelper * @param string $range the valid IPv4 or IPv6 CIDR range, e.g. `10.0.0.0/8` or `2001:af::/64` * @return bool whether $subnet is contained by $range * + * @throws NotSupportedException * @see https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing */ public static function inRange($subnet, $range) @@ -102,19 +105,22 @@ class BaseIpHelper * * @param string $ip the valid IPv4 or IPv6 address * @return string bits as a string + * @throws NotSupportedException */ public static function ip2bin($ip) { + $ipBinary = null; if (static::getIpVersion($ip) === self::IPV4) { - return str_pad(base_convert(ip2long($ip), 10, 2), self::IPV4_ADDRESS_LENGTH, '0', STR_PAD_LEFT); + $ipBinary = pack('N', ip2long($ip)); + } elseif (@inet_pton('::1') === false) { + throw new NotSupportedException('IPv6 is not supported by inet_pton()!'); + } else { + $ipBinary = inet_pton($ip); } - $unpack = unpack('A16', inet_pton($ip)); - $binStr = array_shift($unpack); - $bytes = self::IPV6_ADDRESS_LENGTH / 8; // 128 bit / 8 = 16 bytes $result = ''; - while ($bytes-- > 0) { - $result = sprintf('%08b', isset($binStr[$bytes]) ? ord($binStr[$bytes]) : '0') . $result; + for ($i = 0; $i < strlen($ipBinary); $i += 4) { + $result .= str_pad(decbin(unpack('N', substr($ipBinary, $i, 4))[1]), 32, '0', STR_PAD_LEFT); } return $result; } diff --git a/tests/framework/helpers/IpHelperTest.php b/tests/framework/helpers/IpHelperTest.php index f515f76..ac77758 100644 --- a/tests/framework/helpers/IpHelperTest.php +++ b/tests/framework/helpers/IpHelperTest.php @@ -61,8 +61,8 @@ class IpHelperTest extends TestCase } /** - * @param $value - * @param $expected + * @param $value + * @param $expected * @param string $message * * @dataProvider ip2binProvider @@ -79,7 +79,8 @@ class IpHelperTest extends TestCase ['192.168.1.1', '11000000101010000000000100000001'], ['', '00000000000000000000000000000000'], ['fa01:0000:0000:0000:0000:0000:0000:0001', '11111010000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001'], - ['fa01::1', '11111010000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001'] + ['fa01::1', '11111010000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001'], + ['2620:0:2d0:200::7', '00100110001000000000000000000000000000101101000000000010000000000000000000000000000000000000000000000000000000000000000000000111'], ]; } @@ -108,6 +109,7 @@ class IpHelperTest extends TestCase ['fa01::1/128', 'fa01::/64', true], ['fa01::1/128', 'fa01::1/128', true], ['fa01::1/64', 'fa01::1/128', false], + ['2620:0:0:0:0:0:0:0', '2620:0:2d0:200::7/32', true], ]; } }