From 82d2cf17e77d0ca5ffdcaafb72ca2d3dc82dc142 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Sat, 13 Oct 2012 12:38:42 +0300 Subject: Fix CI_Input::ip_address() subnet detection --- system/core/Input.php | 48 ++++++++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 20 deletions(-) (limited to 'system/core/Input.php') diff --git a/system/core/Input.php b/system/core/Input.php index 82482f2aa..ec935d531 100644 --- a/system/core/Input.php +++ b/system/core/Input.php @@ -390,31 +390,32 @@ class CI_Input { } // Convert the REMOTE_ADDR IP address to binary, if needed - if ( ! isset($ip, $convert_func)) + if ( ! isset($ip, $sprintf)) { if ($separator === ':') { // Make sure we're have the "full" IPv6 format - $ip = str_replace('::', str_repeat(':', 9 - substr_count($this->ip_address, ':')), $this->ip_address); - $convert_func = is_php('5.3') - ? function ($value) - { - return str_pad(base_convert($value, 16, 2), 16, '0', STR_PAD_LEFT); - } - : create_function('$value', 'return str_pad(base_convert($value, 16, 2), 16, "0", STR_PAD_LEFT);'); + $ip = explode(':', + str_replace('::', + str_repeat(':', 9 - substr_count($this->ip_address, ':')), + $this->ip_address + ) + ); + + for ($i = 0; $i < 8; $i++) + { + $ip[$i] = intval($ip[$i], 16); + } + + $sprintf = '%016b%016b%016b%016b%016b%016b%016b%016b'; } else { - $ip = $this->ip_address; - $convert_func = is_php('5.3') - ? function ($value) - { - return str_pad(decbin($value), 8, '0', STR_PAD_LEFT); - } - : create_function('$value', 'return str_pad(decbin($value), 8, "0", STR_PAD_LEFT);'); + $ip = explode('.', $this->ip_address); + $sprintf = '%08b%08b%08b%08b'; } - $ip = implode(array_map($convert_func, explode($separator, $ip))); + $ip = vsprintf($sprintf, $ip); } // Split the netmask length off the network address @@ -423,12 +424,19 @@ class CI_Input { // Again, an IPv6 address is most likely in a compressed form if ($separator === ':') { - $netaddr = str_replace('::', str_repeat(':', 9 - substr_count($netaddr, ':')), $netaddr); + $netaddr = explode(':', str_replace('::', str_repeat(':', 9 - substr_count($netaddr, ':')), $netaddr)); + for ($i = 0; $i < 8; $i++) + { + $netaddr[$i] = intval($netaddr[$i], 16); + } + } + else + { + $netaddr = explode('.', $netaddr); } - // Convert to a binary form and finally compare - $netaddr = implode(array_map($convert_func, explode($separator, $netaddr))); - if (strncmp($ip, $netaddr, $masklen) === 0) + // Convert to binary and finally compare + if (strncmp($ip, vsprintf($sprintf, $netaddr), $masklen) === 0) { $this->ip_address = $spoof; break; -- cgit v1.2.3-24-g4f1b