aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB/includes')
-rw-r--r--phpBB/includes/acp/acp_bbcodes.php5
-rw-r--r--phpBB/includes/acp/acp_forums.php43
-rw-r--r--phpBB/includes/functions.php328
-rw-r--r--phpBB/includes/functions_compatibility.php58
-rw-r--r--phpBB/includes/functions_transfer.php4
-rw-r--r--phpBB/includes/functions_user.php9
-rw-r--r--phpBB/includes/utf/utf_tools.php43
7 files changed, 139 insertions, 351 deletions
diff --git a/phpBB/includes/acp/acp_bbcodes.php b/phpBB/includes/acp/acp_bbcodes.php
index 5360ab0f7b..a67f3c54f9 100644
--- a/phpBB/includes/acp/acp_bbcodes.php
+++ b/phpBB/includes/acp/acp_bbcodes.php
@@ -211,11 +211,6 @@ class acp_bbcodes
$test = $data['bbcode_tag'];
}
- if (!preg_match('%\\[' . $test . '[^]]*].*?\\[/' . $test . ']%s', $bbcode_match))
- {
- trigger_error($user->lang['BBCODE_OPEN_ENDED_TAG'] . adm_back_link($this->u_action), E_USER_WARNING);
- }
-
if (strlen($data['bbcode_tag']) > 16)
{
trigger_error($user->lang['BBCODE_TAG_TOO_LONG'] . adm_back_link($this->u_action), E_USER_WARNING);
diff --git a/phpBB/includes/acp/acp_forums.php b/phpBB/includes/acp/acp_forums.php
index 9044cd0e97..572ae3692a 100644
--- a/phpBB/includes/acp/acp_forums.php
+++ b/phpBB/includes/acp/acp_forums.php
@@ -131,11 +131,11 @@ class acp_forums
'forum_rules_link' => $request->variable('forum_rules_link', ''),
'forum_image' => $request->variable('forum_image', ''),
'forum_style' => $request->variable('forum_style', 0),
- 'display_subforum_list' => $request->variable('display_subforum_list', false),
- 'display_on_index' => $request->variable('display_on_index', false),
+ 'display_subforum_list' => $request->variable('display_subforum_list', true),
+ 'display_on_index' => $request->variable('display_on_index', true),
'forum_topics_per_page' => $request->variable('topics_per_page', 0),
'enable_indexing' => $request->variable('enable_indexing', true),
- 'enable_icons' => $request->variable('enable_icons', false),
+ 'enable_icons' => $request->variable('enable_icons', true),
'enable_prune' => $request->variable('enable_prune', false),
'enable_post_review' => $request->variable('enable_post_review', true),
'enable_quick_reply' => $request->variable('enable_quick_reply', false),
@@ -454,10 +454,10 @@ class acp_forums
'forum_image' => '',
'forum_style' => 0,
'display_subforum_list' => true,
- 'display_on_index' => false,
+ 'display_on_index' => true,
'forum_topics_per_page' => 0,
'enable_indexing' => true,
- 'enable_icons' => false,
+ 'enable_icons' => true,
'enable_prune' => false,
'prune_days' => 7,
'prune_viewed' => 7,
@@ -986,10 +986,20 @@ class acp_forums
$errors[] = $user->lang['FORUM_NAME_EMPTY'];
}
- // No Emojis
+ /**
+ * Replace Emojis and other 4bit UTF-8 chars not allowed by MySql to UCR / NCR.
+ * Using their Numeric Character Reference's Hexadecimal notation.
+ */
+ $forum_data_ary['forum_name'] = utf8_encode_ucr($forum_data_ary['forum_name']);
+
+ /**
+ * This should never happen again.
+ * Leaving the fallback here just in case there will be the need of it.
+ */
if (preg_match_all('/[\x{10000}-\x{10FFFF}]/u', $forum_data_ary['forum_name'], $matches))
{
$character_list = implode('<br>', $matches[0]);
+
$errors[] = $user->lang('FORUM_NAME_EMOJI', $character_list);
}
@@ -1423,8 +1433,8 @@ class acp_forums
* This event may be triggered, when a forum is deleted
*
* @event core.acp_manage_forums_move_children
- * @var int from_id If of the current parent forum
- * @var int to_id If of the new parent forum
+ * @var int from_id Id of the current parent forum
+ * @var int to_id Id of the new parent forum
* @var array errors Array of errors, should be strings and not
* language key.
* @since 3.1.0-a1
@@ -1529,8 +1539,8 @@ class acp_forums
* Event when we move content from one forum to another
*
* @event core.acp_manage_forums_move_content
- * @var int from_id If of the current parent forum
- * @var int to_id If of the new parent forum
+ * @var int from_id Id of the current parent forum
+ * @var int to_id Id of the new parent forum
* @var bool sync Shall we sync the "to"-forum's data
* @var array errors Array of errors, should be strings and not
* language key. If this array is not empty,
@@ -1576,6 +1586,19 @@ class acp_forums
$db->sql_query($sql);
}
+ /**
+ * Event when content has been moved from one forum to another
+ *
+ * @event core.acp_manage_forums_move_content_after
+ * @var int from_id Id of the current parent forum
+ * @var int to_id Id of the new parent forum
+ * @var bool sync Shall we sync the "to"-forum's data
+ *
+ * @since 3.2.9-RC1
+ */
+ $vars = array('from_id', 'to_id', 'sync');
+ extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_move_content_after', compact($vars)));
+
if ($sync)
{
// Delete ghost topics that link back to the same forum then resync counters
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index 3227a21e26..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,331 +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);
-
- if (empty($address) || !is_string($address))
- {
- return false;
- }
+ $ip_normalised = false;
- if (preg_match(get_preg_expression('ipv4'), $address))
+ if (filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4))
{
- return $address;
+ $ip_normalised = $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))
+ else if (filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6))
{
- 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)));
- }
-
- $parts = str_split($in_addr, 4);
- $parts = preg_replace('/^0+(?!$)/', '', $parts);
- $ret = implode(':', $parts);
+ $ip_normalised = inet_ntop(inet_pton($address));
- $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)
- {
- $ret .= ($part <= 0xF ? '0' : '') . dechex($part);
- }
-
- 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) === '::')
+ // If is ipv4
+ if (stripos($ip_normalised, '::ffff:') === 0)
{
- ++$missing_parts;
+ $ip_normalised = substr($ip_normalised, 7);
}
-
- 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;
-}
-
-/**
-* Wrapper for php's checkdnsrr function.
-*
-* @param string $host Fully-Qualified Domain Name
-* @param string $type Resource record type to lookup
-* Supported types are: MX (default), A, AAAA, NS, TXT, CNAME
-* Other types may work or may not work
-*
-* @return mixed true if entry found,
-* false if entry not found,
-* null if this function is not supported by this environment
-*
-* Since null can also be returned, you probably want to compare the result
-* with === true or === false,
-*/
-function phpbb_checkdnsrr($host, $type = 'MX')
-{
- // The dot indicates to search the DNS root (helps those having DNS prefixes on the same domain)
- if (substr($host, -1) == '.')
- {
- $host_fqdn = $host;
- $host = substr($host, 0, -1);
- }
- else
- {
- $host_fqdn = $host . '.';
- }
- // $host has format some.host.example.com
- // $host_fqdn has format some.host.example.com.
-
- // If we're looking for an A record we can use gethostbyname()
- if ($type == 'A' && function_exists('gethostbyname'))
- {
- return (@gethostbyname($host_fqdn) == $host_fqdn) ? false : true;
- }
-
- if (function_exists('checkdnsrr'))
- {
- return checkdnsrr($host_fqdn, $type);
- }
-
- if (function_exists('dns_get_record'))
- {
- // dns_get_record() expects an integer as second parameter
- // We have to convert the string $type to the corresponding integer constant.
- $type_constant = 'DNS_' . $type;
- $type_param = (defined($type_constant)) ? constant($type_constant) : DNS_ANY;
-
- // dns_get_record() might throw E_WARNING and return false for records that do not exist
- $resultset = @dns_get_record($host_fqdn, $type_param);
-
- if (empty($resultset) || !is_array($resultset))
- {
- return false;
- }
- else if ($type_param == DNS_ANY)
- {
- // $resultset is a non-empty array
- return true;
- }
-
- foreach ($resultset as $result)
- {
- if (
- isset($result['host']) && $result['host'] == $host &&
- isset($result['type']) && $result['type'] == $type
- )
- {
- return true;
- }
- }
-
- return false;
- }
-
- // If we're on Windows we can still try to call nslookup via exec() as a last resort
- if (DIRECTORY_SEPARATOR == '\\' && function_exists('exec'))
- {
- @exec('nslookup -type=' . escapeshellarg($type) . ' ' . escapeshellarg($host_fqdn), $output);
-
- // If output is empty, the nslookup failed
- if (empty($output))
- {
- return NULL;
- }
-
- foreach ($output as $line)
- {
- $line = trim($line);
-
- if (empty($line))
- {
- continue;
- }
-
- // Squash tabs and multiple whitespaces to a single whitespace.
- $line = preg_replace('/\s+/', ' ', $line);
-
- switch ($type)
- {
- case 'MX':
- if (stripos($line, "$host MX") === 0)
- {
- return true;
- }
- break;
-
- case 'NS':
- if (stripos($line, "$host nameserver") === 0)
- {
- return true;
- }
- break;
-
- case 'TXT':
- if (stripos($line, "$host text") === 0)
- {
- return true;
- }
- break;
-
- case 'CNAME':
- if (stripos($line, "$host canonical name") === 0)
- {
- return true;
- }
- break;
-
- default:
- case 'AAAA':
- // AAAA records returned by nslookup on Windows XP/2003 have this format.
- // Later Windows versions use the A record format below for AAAA records.
- if (stripos($line, "$host AAAA IPv6 address") === 0)
- {
- return true;
- }
- // No break
-
- case 'A':
- if (!empty($host_matches))
- {
- // Second line
- if (stripos($line, "Address: ") === 0)
- {
- return true;
- }
- else
- {
- $host_matches = false;
- }
- }
- else if (stripos($line, "Name: $host") === 0)
- {
- // First line
- $host_matches = true;
- }
- break;
- }
- }
-
- return false;
}
- return NULL;
+ return $ip_normalised;
}
// Handler, header and footer
diff --git a/phpBB/includes/functions_compatibility.php b/phpBB/includes/functions_compatibility.php
index b5b60e118e..2578290875 100644
--- a/phpBB/includes/functions_compatibility.php
+++ b/phpBB/includes/functions_compatibility.php
@@ -601,3 +601,61 @@ function upload_attachment($form_name, $forum_id, $local = false, $local_storage
return $file;
}
+
+/**
+* Wrapper for php's checkdnsrr function.
+*
+* @param string $host Fully-Qualified Domain Name
+* @param string $type Resource record type to lookup
+* Supported types are: MX (default), A, AAAA, NS, TXT, CNAME
+* Other types may work or may not work
+*
+* @return mixed true if entry found,
+* false if entry not found,
+* null if this function is not supported by this environment
+*
+* Since null can also be returned, you probably want to compare the result
+* with === true or === false,
+*
+* @deprecated 3.3.0-b2 (To be removed: 4.0.0)
+*/
+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 e0b6a9d0c6..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 '';
}
@@ -1910,7 +1905,7 @@ function phpbb_validate_email($email, $config = null)
{
list(, $domain) = explode('@', $email);
- if (phpbb_checkdnsrr($domain, 'A') === false && phpbb_checkdnsrr($domain, 'MX') === false)
+ if (checkdnsrr($domain, 'A') === false && checkdnsrr($domain, 'MX') === false)
{
return 'DOMAIN_NO_MX_RECORD';
}
diff --git a/phpBB/includes/utf/utf_tools.php b/phpBB/includes/utf/utf_tools.php
index 89de454427..bb155aeae5 100644
--- a/phpBB/includes/utf/utf_tools.php
+++ b/phpBB/includes/utf/utf_tools.php
@@ -418,24 +418,43 @@ function utf8_recode($string, $encoding)
}
/**
-* Replace all UTF-8 chars that are not in ASCII with their NCR
-*
-* @param string $text UTF-8 string in NFC
-* @return string ASCII string using NCRs for non-ASCII chars
-*/
+ * Replace some special UTF-8 chars that are not in ASCII with their UCR.
+ * using their Numeric Character Reference's Hexadecimal notation.
+ *
+ * Doesn't interfere with Japanese or Cyrillic etc.
+ * Unicode character visualization will depend on the character support
+ * of your web browser and the fonts installed on your system.
+ *
+ * @see https://en.wikibooks.org/wiki/Unicode/Character_reference/1F000-1FFFF
+ *
+ * @param string $text UTF-8 string in NFC
+ * @return string ASCII string using NCR for non-ASCII chars
+ */
+function utf8_encode_ucr($text)
+{
+ return preg_replace_callback('/[\\xF0-\\xF4].../', 'utf8_encode_ncr_callback', $text);
+}
+
+/**
+ * Replace all UTF-8 chars that are not in ASCII with their NCR
+ * using their Numeric Character Reference's Hexadecimal notation.
+ *
+ * @param string $text UTF-8 string in NFC
+ * @return string ASCII string using NCRs for non-ASCII chars
+ */
function utf8_encode_ncr($text)
{
return preg_replace_callback('#[\\xC2-\\xF4][\\x80-\\xBF]{1,3}#', 'utf8_encode_ncr_callback', $text);
}
/**
-* Callback used in encode_ncr()
-*
-* Takes a UTF-8 char and replaces it with its NCR. Attention, $m is an array
-*
-* @param array $m 0-based numerically indexed array passed by preg_replace_callback()
-* @return string A HTML NCR if the character is valid, or the original string otherwise
-*/
+ * Callback used in utf8_encode_ncr() and utf8_encode_ucr()
+ *
+ * Takes a UTF-8 char and replaces it with its NCR. Attention, $m is an array
+ *
+ * @param array $m 0-based numerically indexed array passed by preg_replace_callback()
+ * @return string A HTML NCR if the character is valid, or the original string otherwise
+ */
function utf8_encode_ncr_callback($m)
{
return '&#' . utf8_ord($m[0]) . ';';