diff options
| -rw-r--r-- | phpBB/develop/regex.php | 40 | ||||
| -rw-r--r-- | phpBB/develop/regex_idn.php | 41 | ||||
| -rw-r--r-- | phpBB/includes/functions.php | 162 | ||||
| -rw-r--r-- | phpBB/includes/functions_compatibility.php | 36 | ||||
| -rw-r--r-- | phpBB/includes/functions_transfer.php | 4 | ||||
| -rw-r--r-- | phpBB/includes/functions_user.php | 7 | ||||
| -rw-r--r-- | phpBB/phpbb/session.php | 49 | ||||
| -rw-r--r-- | tests/network/inet_ntop_pton_test.php | 56 | 
8 files changed, 61 insertions, 334 deletions
diff --git a/phpBB/develop/regex.php b/phpBB/develop/regex.php index 46b6fff701..77c6d5c0e6 100644 --- a/phpBB/develop/regex.php +++ b/phpBB/develop/regex.php @@ -8,46 +8,6 @@  //  die("Please read the first lines of this script for instructions on how to enable it"); - -// IP regular expressions - -$dec_octet = '(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])'; -$h16 = '[\dA-F]{1,4}'; -$ipv4 = "(?:$dec_octet\.){3}$dec_octet"; -$ls32 = "(?:$h16:$h16|$ipv4)"; - -$ipv6_construct = array( -	array(false,	'',		'{6}',	$ls32), -	array(false,	'::',	'{0,5}', "(?:$h16(?::$h16)?|$ipv4)"), -	array('',		':',	'{4}',	$ls32), -	array('{1,2}',	':',	'{3}',	$ls32), -	array('{1,3}',	':',	'{2}',	$ls32), -	array('{1,4}',	':',	'',		$ls32), -	array('{1,5}',	':',	false,	$ls32), -	array('{1,6}',	':',	false,	$h16), -	array('{1,7}',	':',	false,	''), -	array(false, '::', false, '') -); - -$ipv6 = '(?:'; -foreach ($ipv6_construct as $ip_type) -{ -	$ipv6 .= '(?:'; -	if ($ip_type[0] !== false) -	{ -		$ipv6 .= "(?:$h16:)" . $ip_type[0]; -	} -	$ipv6 .= $ip_type[1]; -	if ($ip_type[2] !== false) -	{ -		$ipv6 .= "(?:$h16:)" . $ip_type[2]; -	} -	$ipv6 .= $ip_type[3] . ')|'; -} -$ipv6 = substr($ipv6, 0, -1) . ')'; - -echo 'IPv4: ' . $ipv4 . "<br />\nIPv6: " . $ipv6 . "<br />\n"; -  // URL regular expressions  $pct_encoded = "%[\dA-F]{2}"; diff --git a/phpBB/develop/regex_idn.php b/phpBB/develop/regex_idn.php index 30373f8de3..24d1eb9196 100644 --- a/phpBB/develop/regex_idn.php +++ b/phpBB/develop/regex_idn.php @@ -8,45 +8,6 @@  //  die("Please read the first lines of this script for instructions on how to enable it"); -// IP regular expressions - -$dec_octet = '(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])'; -$h16 = '[\dA-F]{1,4}'; -$ipv4 = "(?:$dec_octet\.){3}$dec_octet"; -$ls32 = "(?:$h16:$h16|$ipv4)"; - -$ipv6_construct = array( -	array(false,	'',		'{6}',	$ls32), -	array(false,	'::',	'{0,5}', "(?:$h16(?::$h16)?|$ipv4)"), -	array('',		':',	'{4}',	$ls32), -	array('{1,2}',	':',	'{3}',	$ls32), -	array('{1,3}',	':',	'{2}',	$ls32), -	array('{1,4}',	':',	'',		$ls32), -	array('{1,5}',	':',	false,	$ls32), -	array('{1,6}',	':',	false,	$h16), -	array('{1,7}',	':',	false,	''), -	array(false, '::', false, '') -); - -$ipv6 = '(?:'; -foreach ($ipv6_construct as $ip_type) -{ -	$ipv6 .= '(?:'; -	if ($ip_type[0] !== false) -	{ -		$ipv6 .= "(?:$h16:)" . $ip_type[0]; -	} -	$ipv6 .= $ip_type[1]; -	if ($ip_type[2] !== false) -	{ -		$ipv6 .= "(?:$h16:)" . $ip_type[2]; -	} -	$ipv6 .= $ip_type[3] . ')|'; -} -$ipv6 = substr($ipv6, 0, -1) . ')'; - -echo 'IPv4: ' . $ipv4 . "<br /><br />\n\nIPv6: " . $ipv6 . "<br /><br />\n\n"; -  // URL regular expressions  /* IDN2008 characters derivation @@ -72,7 +33,7 @@ $no_hangul = '\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C  */  $no_cdm = '\x{20D0}-\x{20FF}';						// \p{block=Combining_Diacritical_Marks_For_Symbols}  $no_musical = '\x{1D100}-\x{1D1FF}';					// \p{block=Musical_Symbols} -$no_ancient_greek_musical = '\x{1D200}-\x{1D24F}';	// \p{block=Ancient_Greek_Musical_Notation}	 +$no_ancient_greek_musical = '\x{1D200}-\x{1D24F}';	// \p{block=Ancient_Greek_Musical_Notation}  /* Remove certain exceptions:  ** U+0640 ARABIC TATWEEL  ** U+07FA NKO LAJANYALAN diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 30f9734efd..d2d5b503a2 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -2851,10 +2851,13 @@ function get_preg_expression($mode)  		// Whoa these look impressive!  		// The code to generate the following two regular expressions which match valid IPv4/IPv6 addresses  		// can be found in the develop directory + +		// @deprecated  		case 'ipv4':  			return '#^(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$#';  		break; +		// @deprecated  		case 'ipv6':  			return '#^(?:(?:(?:[\dA-F]{1,4}:){6}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:::(?:[\dA-F]{1,4}:){0,5}(?:[\dA-F]{1,4}(?::[\dA-F]{1,4})?|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:):(?:[\dA-F]{1,4}:){4}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,2}:(?:[\dA-F]{1,4}:){3}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,3}:(?:[\dA-F]{1,4}:){2}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,4}:(?:[\dA-F]{1,4}:)(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,5}:(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,6}:[\dA-F]{1,4})|(?:(?:[\dA-F]{1,4}:){1,7}:)|(?:::))$#i';  		break; @@ -2980,165 +2983,26 @@ function short_ipv6($ip, $length)  * @return mixed		false if specified address is not valid,  *					string otherwise  */ -function phpbb_ip_normalise($address) +function phpbb_ip_normalise(string $address)  { -	$address = trim($address); +	$ip_normalised = false; -	if (empty($address) || !is_string($address)) +	if (filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4))  	{ -		return false; +		$ip_normalised = $address;  	} - -	if (preg_match(get_preg_expression('ipv4'), $address)) +	else if (filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6))  	{ -		return $address; -	} - -	return phpbb_inet_ntop(phpbb_inet_pton($address)); -} - -/** -* Wrapper for inet_ntop() -* -* Converts a packed internet address to a human readable representation -* inet_ntop() is supported by PHP since 5.1.0, since 5.3.0 also on Windows. -* -* @param string $in_addr	A 32bit IPv4, or 128bit IPv6 address. -* -* @return mixed		false on failure, -*					string otherwise -*/ -function phpbb_inet_ntop($in_addr) -{ -	$in_addr = bin2hex($in_addr); - -	switch (strlen($in_addr)) -	{ -		case 8: -			return implode('.', array_map('hexdec', str_split($in_addr, 2))); - -		case 32: -			if (substr($in_addr, 0, 24) === '00000000000000000000ffff') -			{ -				return phpbb_inet_ntop(pack('H*', substr($in_addr, 24))); -			} +		$ip_normalised = inet_ntop(inet_pton($address)); -			$parts = str_split($in_addr, 4); -			$parts = preg_replace('/^0+(?!$)/', '', $parts); -			$ret = implode(':', $parts); - -			$matches = array(); -			preg_match_all('/(?<=:|^)(?::?0){2,}/', $ret, $matches, PREG_OFFSET_CAPTURE); -			$matches = $matches[0]; - -			if (empty($matches)) -			{ -				return $ret; -			} - -			$longest_match = ''; -			$longest_match_offset = 0; -			foreach ($matches as $match) -			{ -				if (strlen($match[0]) > strlen($longest_match)) -				{ -					$longest_match = $match[0]; -					$longest_match_offset = $match[1]; -				} -			} - -			$ret = substr_replace($ret, '', $longest_match_offset, strlen($longest_match)); - -			if ($longest_match_offset == strlen($ret)) -			{ -				$ret .= ':'; -			} - -			if ($longest_match_offset == 0) -			{ -				$ret = ':' . $ret; -			} - -			return $ret; - -		default: -			return false; -	} -} - -/** -* Wrapper for inet_pton() -* -* Converts a human readable IP address to its packed in_addr representation -* inet_pton() is supported by PHP since 5.1.0, since 5.3.0 also on Windows. -* -* @param string $address	A human readable IPv4 or IPv6 address. -* -* @return mixed		false if address is invalid, -*					in_addr representation of the given address otherwise (string) -*/ -function phpbb_inet_pton($address) -{ -	$ret = ''; -	if (preg_match(get_preg_expression('ipv4'), $address)) -	{ -		foreach (explode('.', $address) as $part) +		// If is ipv4 +		if (stripos($ip_normalised, '::ffff:') === 0)  		{ -			$ret .= ($part <= 0xF ? '0' : '') . dechex($part); +			$ip_normalised = substr($ip_normalised, 7);  		} - -		return pack('H*', $ret);  	} -	if (preg_match(get_preg_expression('ipv6'), $address)) -	{ -		$parts = explode(':', $address); -		$missing_parts = 8 - count($parts) + 1; - -		if (substr($address, 0, 2) === '::') -		{ -			++$missing_parts; -		} - -		if (substr($address, -2) === '::') -		{ -			++$missing_parts; -		} - -		$embedded_ipv4 = false; -		$last_part = end($parts); - -		if (preg_match(get_preg_expression('ipv4'), $last_part)) -		{ -			$parts[count($parts) - 1] = ''; -			$last_part = phpbb_inet_pton($last_part); -			$embedded_ipv4 = true; -			--$missing_parts; -		} - -		foreach ($parts as $i => $part) -		{ -			if (strlen($part)) -			{ -				$ret .= str_pad($part, 4, '0', STR_PAD_LEFT); -			} -			else if ($i && $i < count($parts) - 1) -			{ -				$ret .= str_repeat('0000', $missing_parts); -			} -		} - -		$ret = pack('H*', $ret); - -		if ($embedded_ipv4) -		{ -			$ret .= $last_part; -		} - -		return $ret; -	} - -	return false; +	return $ip_normalised;  }  // Handler, header and footer diff --git a/phpBB/includes/functions_compatibility.php b/phpBB/includes/functions_compatibility.php index 1f9131c9c0..2578290875 100644 --- a/phpBB/includes/functions_compatibility.php +++ b/phpBB/includes/functions_compatibility.php @@ -623,3 +623,39 @@ function phpbb_checkdnsrr($host, $type = 'MX')  {  	return checkdnsrr($host, $type);  } + +/* + * Wrapper for inet_ntop() + * + * Converts a packed internet address to a human readable representation + * inet_ntop() is supported by PHP since 5.1.0, since 5.3.0 also on Windows. + * + * @param string $in_addr	A 32bit IPv4, or 128bit IPv6 address. + * + * @return mixed		false on failure, + *					string otherwise +  * + * @deprecated 3.3.0-b2 (To be removed: 4.0.0) + */ +function phpbb_inet_ntop($in_addr) +{ +	return inet_ntop($in_addr); +} + +/** + * Wrapper for inet_pton() + * + * Converts a human readable IP address to its packed in_addr representation + * inet_pton() is supported by PHP since 5.1.0, since 5.3.0 also on Windows. + * + * @param string $address	A human readable IPv4 or IPv6 address. + * + * @return mixed		false if address is invalid, + *					in_addr representation of the given address otherwise (string) + * + * @deprecated 3.3.0-b2 (To be removed: 4.0.0) + */ +function phpbb_inet_pton($address) +{ +	return inet_pton($address); +} diff --git a/phpBB/includes/functions_transfer.php b/phpBB/includes/functions_transfer.php index 7427b89917..f0070b4b1e 100644 --- a/phpBB/includes/functions_transfer.php +++ b/phpBB/includes/functions_transfer.php @@ -810,7 +810,7 @@ class ftp_fsock extends transfer  			$server_ip = substr($socket_name, 0, strrpos($socket_name, ':'));  		} -		if (!isset($server_ip) || preg_match(get_preg_expression('ipv4'), $server_ip)) +		if (isset($server_ip) && filter_var($server_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) // ipv4  		{  			// Passive mode  			$this->_send_command('PASV', '', false); @@ -831,7 +831,7 @@ class ftp_fsock extends transfer  			$server_ip = $temp[0] . '.' . $temp[1] . '.' . $temp[2] . '.' . $temp[3];  			$server_port = $temp[4] * 256 + $temp[5];  		} -		else +		else // ipv6  		{  			// Extended Passive Mode - RFC2428  			$this->_send_command('EPSV', '', false); diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index 7dd850111e..5c94a90d9d 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -1455,12 +1455,7 @@ function user_unban($mode, $ban)  */  function user_ipwhois($ip)  { -	if (empty($ip)) -	{ -		return ''; -	} - -	if (!preg_match(get_preg_expression('ipv4'), $ip) && !preg_match(get_preg_expression('ipv6'), $ip)) +	if (!filter_var($ip, FILTER_VALIDATE_IP))  	{  		return '';  	} diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php index ba200f38df..7c76c08b73 100644 --- a/phpBB/phpbb/session.php +++ b/phpBB/phpbb/session.php @@ -250,8 +250,7 @@ class session  			$ips = explode(' ', $this->forwarded_for);  			foreach ($ips as $ip)  			{ -				// check IPv4 first, the IPv6 is hopefully only going to be used very seldom -				if (!empty($ip) && !preg_match(get_preg_expression('ipv4'), $ip) && !preg_match(get_preg_expression('ipv6'), $ip)) +				if (!filter_var($ip, FILTER_VALIDATE_IP))  				{  					// contains invalid data, don't use the forwarded for header  					$this->forwarded_for = ''; @@ -311,49 +310,17 @@ class session  		foreach ($ips as $ip)  		{ -			if (function_exists('phpbb_ip_normalise')) -			{ -				// Normalise IP address -				$ip = phpbb_ip_normalise($ip); - -				if (empty($ip)) -				{ -					// IP address is invalid. -					break; -				} - -				// IP address is valid. -				$this->ip = $ip; +			// Normalise IP address +			$ip = phpbb_ip_normalise($ip); -				// Skip legacy code. -				continue; -			} - -			if (preg_match(get_preg_expression('ipv4'), $ip)) -			{ -				$this->ip = $ip; -			} -			else if (preg_match(get_preg_expression('ipv6'), $ip)) +			if ($ip === false)  			{ -				// Quick check for IPv4-mapped address in IPv6 -				if (stripos($ip, '::ffff:') === 0) -				{ -					$ipv4 = substr($ip, 7); - -					if (preg_match(get_preg_expression('ipv4'), $ipv4)) -					{ -						$ip = $ipv4; -					} -				} - -				$this->ip = $ip; -			} -			else -			{ -				// We want to use the last valid address in the chain -				// Leave foreach loop when address is invalid +				// IP address is invalid.  				break;  			} + +			// IP address is valid. +			$this->ip = $ip;  		}  		$this->load = false; diff --git a/tests/network/inet_ntop_pton_test.php b/tests/network/inet_ntop_pton_test.php deleted file mode 100644 index dbd58ce783..0000000000 --- a/tests/network/inet_ntop_pton_test.php +++ /dev/null @@ -1,56 +0,0 @@ -<?php -/** -* -* This file is part of the phpBB Forum Software package. -* -* @copyright (c) phpBB Limited <https://www.phpbb.com> -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -class phpbb_network_inet_ntop_pton_test extends phpbb_test_case -{ -	public function data_provider() -	{ -		return array( -			array('127.0.0.1',						'7f000001'), -			array('192.232.131.223',				'c0e883df'), -			array('13.1.68.3',						'0d014403'), -			array('129.144.52.38',					'81903426'), - -			array('2001:280:0:10::5',				'20010280000000100000000000000005'), -			array('fe80::200:4cff:fefe:172f',		'fe8000000000000002004cfffefe172f'), - -			array('::',								'00000000000000000000000000000000'), -			array('::1',							'00000000000000000000000000000001'), -			array('1::',							'00010000000000000000000000000000'), - -			array('1:1:0:0:1::',					'00010001000000000001000000000000'), - -			array('0:2:3:4:5:6:7:8',				'00000002000300040005000600070008'), -			array('1:2:0:4:5:6:7:8',				'00010002000000040005000600070008'), -			array('1:2:3:4:5:6:7:0',				'00010002000300040005000600070000'), - -			array('2001:0:0:1::1',					'20010000000000010000000000000001'), -		); -	} - -	/** -	* @dataProvider data_provider -	*/ -	public function test_inet_ntop($address, $hex) -	{ -		$this->assertEquals($address, phpbb_inet_ntop(pack('H*', $hex))); -	} - -	/** -	* @dataProvider data_provider -	*/ -	public function test_inet_pton($address, $hex) -	{ -		$this->assertEquals($hex, bin2hex(phpbb_inet_pton($address))); -	} -}  | 
