From 0a14913fe54e269e535c1f66f715823fa731c843 Mon Sep 17 00:00:00 2001 From: Pascal Kriete Date: Thu, 7 Jun 2012 16:15:51 -0400 Subject: Adding IPv6 support to the Input and Form_validation libraries. --- system/core/Input.php | 134 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 131 insertions(+), 3 deletions(-) (limited to 'system/core') diff --git a/system/core/Input.php b/system/core/Input.php index 9bfb5f1fb..4b7622cbe 100755 --- a/system/core/Input.php +++ b/system/core/Input.php @@ -365,13 +365,66 @@ class CI_Input { /** * Validate IP Address * + * @access public + * @param string + * @param string ipv4 or ipv6 + * @return bool + */ + public function valid_ip($ip, $which = '') + { + $which = strtolower($which); + + // First check if filter_var is available + if (is_callable('filter_var')) + { + switch ($which) { + case 'ipv4': + $flag = FILTER_FLAG_IPV4; + break; + case 'ipv6': + $flag = FILTER_FLAG_IPV6; + break; + default: + $flag = ''; + break; + } + + return filter_var($ip, FILTER_VALIDATE_IP, $flag) !== FALSE; + } + + // If it's not we'll do it manually + if ($which != 'ipv6' OR $which != 'ipv4') + { + if (strpos($ip, ':') !== FALSE) + { + $which = 'ipv6'; + } + elseif (strpos($ip, '.') !== FALSE) + { + $which = 'ipv4'; + } + else + { + return FALSE; + } + } + + $func = '_valid_'.$which; + return $this->$func($ip); + } + + // -------------------------------------------------------------------- + + /** + * Validate IPv4 Address + * * Updated version suggested by Geert De Deckere * - * @access public + * @access protected * @param string - * @return string + * @return bool */ - function valid_ip($ip) + protected function _valid_ipv4($ip) { $ip_segments = explode('.', $ip); @@ -385,6 +438,7 @@ class CI_Input { { return FALSE; } + // Check each segment foreach ($ip_segments as $segment) { @@ -398,6 +452,80 @@ class CI_Input { return TRUE; } + + // -------------------------------------------------------------------- + + /** + * Validate IPv6 Address + * + * @access protected + * @param string + * @return bool + */ + protected function _valid_ipv6($str) + { + // 8 groups, separated by : + // 0-ffff per group + // one set of consecutive 0 groups can be collapsed to :: + + $groups = 8; + $collapsed = FALSE; + + $chunks = array_filter( + preg_split('/(:{1,2})/', $str, NULL, PREG_SPLIT_DELIM_CAPTURE) + ); + + // Rule out easy nonsense + if (current($chunks) == ':' OR end($chunks) == ':') + { + return FALSE; + } + + // PHP supports IPv4-mapped IPv6 addresses, so we'll expect those as well + if (strpos(end($chunks), '.') !== FALSE) + { + $ipv4 = array_pop($chunks); + + if ( ! $this->_valid_ipv4($ipv4)) + { + return FALSE; + } + + $groups--; + } + + while ($seg = array_pop($chunks)) + { + if ($seg[0] == ':') + { + if (--$groups == 0) + { + return FALSE; // too many groups + } + + if (strlen($seg) > 2) + { + return FALSE; // long separator + } + + if ($seg == '::') + { + if ($collapsed) + { + return FALSE; // multiple collapsed + } + + $collapsed = TRUE; + } + } + elseif (preg_match("/[^0-9a-f]/i", $seg) OR strlen($seg) > 4) + { + return FALSE; // invalid segment + } + } + + return $collapsed OR $groups == 1; + } // -------------------------------------------------------------------- -- cgit v1.2.3-24-g4f1b From 728115901ff93183f8f2f695417621cfc799a865 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Fri, 8 Jun 2012 00:01:10 +0300 Subject: Fixed valid_ip() for PHP < 5.2 --- system/core/Input.php | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) (limited to 'system/core') diff --git a/system/core/Input.php b/system/core/Input.php index 4b7622cbe..47fc0f887 100755 --- a/system/core/Input.php +++ b/system/core/Input.php @@ -389,11 +389,10 @@ class CI_Input { break; } - return filter_var($ip, FILTER_VALIDATE_IP, $flag) !== FALSE; + return (bool) filter_var($ip, FILTER_VALIDATE_IP, $flag); } - - // If it's not we'll do it manually - if ($which != 'ipv6' OR $which != 'ipv4') + + if ($which !== 'ipv6' && $which !== 'ipv4') { if (strpos($ip, ':') !== FALSE) { @@ -405,16 +404,16 @@ class CI_Input { } else { - return FALSE; + return $this->_valid_ipv4($ip) OR $this->_valid_ipv6($ip); } } - + $func = '_valid_'.$which; return $this->$func($ip); } - + // -------------------------------------------------------------------- - + /** * Validate IPv4 Address * @@ -429,7 +428,7 @@ class CI_Input { $ip_segments = explode('.', $ip); // Always 4 segments needed - if (count($ip_segments) != 4) + if (count($ip_segments) !== 4) { return FALSE; } @@ -438,7 +437,7 @@ class CI_Input { { return FALSE; } - + // Check each segment foreach ($ip_segments as $segment) { @@ -452,9 +451,9 @@ class CI_Input { return TRUE; } - + // -------------------------------------------------------------------- - + /** * Validate IPv6 Address * @@ -467,33 +466,33 @@ class CI_Input { // 8 groups, separated by : // 0-ffff per group // one set of consecutive 0 groups can be collapsed to :: - + $groups = 8; $collapsed = FALSE; - + $chunks = array_filter( preg_split('/(:{1,2})/', $str, NULL, PREG_SPLIT_DELIM_CAPTURE) ); - + // Rule out easy nonsense if (current($chunks) == ':' OR end($chunks) == ':') { return FALSE; } - + // PHP supports IPv4-mapped IPv6 addresses, so we'll expect those as well if (strpos(end($chunks), '.') !== FALSE) { $ipv4 = array_pop($chunks); - + if ( ! $this->_valid_ipv4($ipv4)) { return FALSE; } - + $groups--; } - + while ($seg = array_pop($chunks)) { if ($seg[0] == ':') @@ -502,19 +501,19 @@ class CI_Input { { return FALSE; // too many groups } - + if (strlen($seg) > 2) { return FALSE; // long separator } - + if ($seg == '::') { if ($collapsed) { return FALSE; // multiple collapsed } - + $collapsed = TRUE; } } -- cgit v1.2.3-24-g4f1b From cef5bda9765080b818898811023d9ab427b0faf2 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Fri, 8 Jun 2012 00:04:46 +0300 Subject: Revert a change --- system/core/Input.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/core') diff --git a/system/core/Input.php b/system/core/Input.php index 47fc0f887..3559d8607 100755 --- a/system/core/Input.php +++ b/system/core/Input.php @@ -404,7 +404,7 @@ class CI_Input { } else { - return $this->_valid_ipv4($ip) OR $this->_valid_ipv6($ip); + return FALSE; } } -- cgit v1.2.3-24-g4f1b