diff options
author | stevendegroote <stevendegroote@gmail.com> | 2019-09-17 23:15:54 +0200 |
---|---|---|
committer | stevendegroote <stevendegroote@gmail.com> | 2019-09-17 23:15:54 +0200 |
commit | f8967fec78d826ea8d9ca34f65966ff8a7674b47 (patch) | |
tree | f9c5f408e7764ec6343e084e7fc6d62d07e3400f /phpBB/includes/functions_user.php | |
parent | ce93b224107a65b43253c36812b636321eb55a78 (diff) | |
parent | 4db585a4cb2e5359074a82ef088574609155294b (diff) | |
download | forums-f8967fec78d826ea8d9ca34f65966ff8a7674b47.tar forums-f8967fec78d826ea8d9ca34f65966ff8a7674b47.tar.gz forums-f8967fec78d826ea8d9ca34f65966ff8a7674b47.tar.bz2 forums-f8967fec78d826ea8d9ca34f65966ff8a7674b47.tar.xz forums-f8967fec78d826ea8d9ca34f65966ff8a7674b47.zip |
Merge branch '3.2.x' into ticket/16159
Diffstat (limited to 'phpBB/includes/functions_user.php')
-rw-r--r-- | phpBB/includes/functions_user.php | 214 |
1 files changed, 135 insertions, 79 deletions
diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index c746bd0e4c..3bf4aa16b7 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -26,8 +26,10 @@ if (!defined('IN_PHPBB')) * @param array &$user_id_ary The user ids to check or empty if usernames used * @param array &$username_ary The usernames to check or empty if user ids used * @param mixed $user_type Array of user types to check, false if not restricting by user type +* @param boolean $update_references If false, the supplied array is unset and appears unchanged from where it was called +* @return boolean|string Returns false on success, error string on failure */ -function user_get_id_name(&$user_id_ary, &$username_ary, $user_type = false) +function user_get_id_name(&$user_id_ary, &$username_ary, $user_type = false, $update_references = false) { global $db; @@ -50,7 +52,13 @@ function user_get_id_name(&$user_id_ary, &$username_ary, $user_type = false) } $sql_in = ($which_ary == 'user_id_ary') ? array_map('intval', ${$which_ary}) : array_map('utf8_clean_string', ${$which_ary}); - unset(${$which_ary}); + + // By unsetting the array here, the values passed in at the point user_get_id_name() was called will be retained. + // Otherwise, if we don't unset (as the array was passed by reference) the original array will be updated below. + if ($update_references === false) + { + unset(${$which_ary}); + } $user_id_ary = $username_ary = array(); @@ -170,7 +178,7 @@ function user_update_name($old_name, $new_name) * Adds an user * * @param mixed $user_row An array containing the following keys (and the appropriate values): username, group_id (the group to place the user in), user_email and the user_type(usually 0). Additional entries not overridden by defaults will be forwarded. -* @param string $cp_data custom profile fields, see custom_profile::build_insert_sql_array +* @param array $cp_data custom profile fields, see custom_profile::build_insert_sql_array * @param array $notifications_data The notifications settings for the new user * @return the new user's ID. */ @@ -260,7 +268,7 @@ function user_add($user_row, $cp_data = false, $notifications_data = null) $remaining_vars = array_diff(array_keys($user_row), array_keys($sql_ary)); // Now fill our sql array with the remaining vars - if (sizeof($remaining_vars)) + if (count($remaining_vars)) { foreach ($remaining_vars as $key) { @@ -272,8 +280,8 @@ function user_add($user_row, $cp_data = false, $notifications_data = null) * Use this event to modify the values to be inserted when a user is added * * @event core.user_add_modify_data - * @var array user_row Array of user details submited to user_add - * @var array cp_data Array of Custom profile fields submited to user_add + * @var array user_row Array of user details submitted to user_add + * @var array cp_data Array of Custom profile fields submitted to user_add * @var array sql_ary Array of data to be inserted when a user is added * @var array notifications_data Array of notification data to be inserted when a user is added * @since 3.1.0-a1 @@ -289,7 +297,7 @@ function user_add($user_row, $cp_data = false, $notifications_data = null) $user_id = $db->sql_nextid(); // Insert Custom Profile Fields - if ($cp_data !== false && sizeof($cp_data)) + if ($cp_data !== false && count($cp_data)) { $cp_data['user_id'] = (int) $user_id; @@ -376,6 +384,19 @@ function user_add($user_row, $cp_data = false, $notifications_data = null) ); } + /** + * Modify the notifications data to be inserted in the database when a user is added + * + * @event core.user_add_modify_notifications_data + * @var array user_row Array of user details submitted to user_add + * @var array cp_data Array of Custom profile fields submitted to user_add + * @var array sql_ary Array of data to be inserted when a user is added + * @var array notifications_data Array of notification data to be inserted when a user is added + * @since 3.2.2-RC1 + */ + $vars = array('user_row', 'cp_data', 'sql_ary', 'notifications_data'); + extract($phpbb_dispatcher->trigger_event('core.user_add_modify_notifications_data', compact($vars))); + // Subscribe user to notifications if necessary if (!empty($notifications_data)) { @@ -388,12 +409,12 @@ function user_add($user_row, $cp_data = false, $notifications_data = null) } /** - * Event that returns user id, user detals and user CPF of newly registared user + * Event that returns user id, user details and user CPF of newly registered user * * @event core.user_add_after - * @var int user_id User id of newly registared user - * @var array user_row Array of user details submited to user_add - * @var array cp_data Array of Custom profile fields submited to user_add + * @var int user_id User id of newly registered user + * @var array user_row Array of user details submitted to user_add + * @var array cp_data Array of Custom profile fields submitted to user_add * @since 3.1.0-b5 */ $vars = array('user_id', 'user_row', 'cp_data'); @@ -448,9 +469,11 @@ function user_delete($mode, $user_ids, $retain_username = true) * @var array user_ids IDs of the deleted user * @var mixed retain_username True if username should be retained * or false if not + * @var array user_rows Array containing data of the deleted users * @since 3.1.0-a1 + * @changed 3.2.4-RC1 Added user_rows */ - $vars = array('mode', 'user_ids', 'retain_username'); + $vars = array('mode', 'user_ids', 'retain_username', 'user_rows'); extract($phpbb_dispatcher->trigger_event('core.delete_user_before', compact($vars))); // Before we begin, we will remove the reports the user issued. @@ -468,7 +491,7 @@ function user_delete($mode, $user_ids, $retain_username = true) } $db->sql_freeresult($result); - if (sizeof($report_posts)) + if (count($report_posts)) { $report_posts = array_unique($report_posts); $report_topics = array_unique($report_topics); @@ -488,7 +511,7 @@ function user_delete($mode, $user_ids, $retain_username = true) } $db->sql_freeresult($result); - if (sizeof($keep_report_topics)) + if (count($keep_report_topics)) { $report_topics = array_diff($report_topics, $keep_report_topics); } @@ -500,7 +523,7 @@ function user_delete($mode, $user_ids, $retain_username = true) WHERE ' . $db->sql_in_set('post_id', $report_posts); $db->sql_query($sql); - if (sizeof($report_topics)) + if (count($report_topics)) { $sql = 'UPDATE ' . TOPICS_TABLE . ' SET topic_reported = 0 @@ -651,8 +674,30 @@ function user_delete($mode, $user_ids, $retain_username = true) delete_posts('poster_id', $user_ids); } - $table_ary = array(USERS_TABLE, USER_GROUP_TABLE, TOPICS_WATCH_TABLE, FORUMS_WATCH_TABLE, ACL_USERS_TABLE, TOPICS_TRACK_TABLE, TOPICS_POSTED_TABLE, FORUMS_TRACK_TABLE, PROFILE_FIELDS_DATA_TABLE, MODERATOR_CACHE_TABLE, DRAFTS_TABLE, BOOKMARKS_TABLE, SESSIONS_KEYS_TABLE, PRIVMSGS_FOLDER_TABLE, PRIVMSGS_RULES_TABLE); - + $table_ary = [ + USERS_TABLE, + USER_GROUP_TABLE, + TOPICS_WATCH_TABLE, + FORUMS_WATCH_TABLE, + ACL_USERS_TABLE, + TOPICS_TRACK_TABLE, + TOPICS_POSTED_TABLE, + FORUMS_TRACK_TABLE, + PROFILE_FIELDS_DATA_TABLE, + MODERATOR_CACHE_TABLE, + DRAFTS_TABLE, + BOOKMARKS_TABLE, + SESSIONS_KEYS_TABLE, + PRIVMSGS_FOLDER_TABLE, + PRIVMSGS_RULES_TABLE, + $phpbb_container->getParameter('tables.auth_provider_oauth_token_storage'), + $phpbb_container->getParameter('tables.auth_provider_oauth_states'), + $phpbb_container->getParameter('tables.auth_provider_oauth_account_assoc'), + $phpbb_container->getParameter('tables.user_notifications') + ]; + + // Ignore errors on deleting from non-existent tables, e.g. when migrating + $db->sql_return_on_error(true); // Delete the miscellaneous (non-post) data for the user foreach ($table_ary as $table) { @@ -660,6 +705,7 @@ function user_delete($mode, $user_ids, $retain_username = true) WHERE " . $user_id_sql; $db->sql_query($sql); } + $db->sql_return_on_error(); $cache->destroy('sql', MODERATOR_CACHE_TABLE); @@ -767,7 +813,7 @@ function user_active_flip($mode, $user_id_ary, $reason = INACTIVE_MANUAL) $user_id_ary = array($user_id_ary); } - if (!sizeof($user_id_ary)) + if (!count($user_id_ary)) { return; } @@ -825,7 +871,7 @@ function user_active_flip($mode, $user_id_ary, $reason = INACTIVE_MANUAL) $vars = array('mode', 'reason', 'activated', 'deactivated', 'user_id_ary', 'sql_statements'); extract($phpbb_dispatcher->trigger_event('core.user_active_flip_before', compact($vars))); - if (sizeof($sql_statements)) + if (count($sql_statements)) { foreach ($sql_statements as $user_id => $sql_ary) { @@ -903,7 +949,7 @@ function user_ban($mode, $ban, $ban_len, $ban_len_other, $ban_exclude, $ban_reas else { $ban_other = explode('-', $ban_len_other); - if (sizeof($ban_other) == 3 && ((int) $ban_other[0] < 9999) && + if (count($ban_other) == 3 && ((int) $ban_other[0] < 9999) && (strlen($ban_other[0]) == 4) && (strlen($ban_other[1]) == 2) && (strlen($ban_other[2]) == 2)) { $ban_end = max($current_time, $user->create_datetime() @@ -971,7 +1017,7 @@ function user_ban($mode, $ban, $ban_len, $ban_len_other, $ban_exclude, $ban_reas } // Make sure we have been given someone to ban - if (!sizeof($sql_usernames)) + if (!count($sql_usernames)) { trigger_error('NO_USER_SPECIFIED', E_USER_WARNING); } @@ -982,7 +1028,7 @@ function user_ban($mode, $ban, $ban_len, $ban_len_other, $ban_exclude, $ban_reas // Do not allow banning yourself, the guest account, or founders. $non_bannable = array($user->data['user_id'], ANONYMOUS); - if (sizeof($founder)) + if (count($founder)) { $sql .= ' AND ' . $db->sql_in_set('user_id', array_merge(array_keys($founder), $non_bannable), true); } @@ -1122,14 +1168,14 @@ function user_ban($mode, $ban, $ban_len, $ban_len_other, $ban_exclude, $ban_reas continue; } - if (!sizeof($founder) || !in_array($ban_item, $founder)) + if (!count($founder) || !in_array($ban_item, $founder)) { $banlist_ary[] = $ban_item; } } } - if (sizeof($ban_list) == 0) + if (count($ban_list) == 0) { trigger_error('NO_EMAILS_DEFINED', E_USER_WARNING); } @@ -1176,7 +1222,7 @@ function user_ban($mode, $ban, $ban_len, $ban_len_other, $ban_exclude, $ban_reas $banlist_ary_tmp = array_intersect($banlist_ary, $banlist_ary_tmp); - if (sizeof($banlist_ary_tmp)) + if (count($banlist_ary_tmp)) { // One or more entities are already banned/excluded, delete the existing bans, so they can be re-inserted with the given new length $sql = 'DELETE FROM ' . BANLIST_TABLE . ' @@ -1190,7 +1236,7 @@ function user_ban($mode, $ban, $ban_len, $ban_len_other, $ban_exclude, $ban_reas $db->sql_freeresult($result); // We have some entities to ban - if (sizeof($banlist_ary)) + if (count($banlist_ary)) { $sql_ary = array(); @@ -1318,7 +1364,7 @@ function user_unban($mode, $ban) $unban_sql = array_map('intval', $ban); - if (sizeof($unban_sql)) + if (count($unban_sql)) { // Grab details of bans for logging information later switch ($mode) @@ -1414,21 +1460,14 @@ function user_ipwhois($ip) return ''; } - if (preg_match(get_preg_expression('ipv4'), $ip)) - { - // IPv4 address - $whois_host = 'whois.arin.net.'; - } - else if (preg_match(get_preg_expression('ipv6'), $ip)) - { - // IPv6 address - $whois_host = 'whois.sixxs.net.'; - } - else + if (!preg_match(get_preg_expression('ipv4'), $ip) && !preg_match(get_preg_expression('ipv6'), $ip)) { return ''; } + // IPv4 & IPv6 addresses + $whois_host = 'whois.arin.net.'; + $ipwhois = ''; if (($fsk = @fsockopen($whois_host, 43))) @@ -1582,7 +1621,7 @@ function validate_num($num, $optional = false, $min = 0, $max = 1E99) function validate_date($date_string, $optional = false) { $date = explode('-', $date_string); - if ((empty($date) || sizeof($date) != 3) && $optional) + if ((empty($date) || count($date) != 3) && $optional) { return false; } @@ -1604,7 +1643,7 @@ function validate_date($date_string, $optional = false) } } - if (sizeof($date) != 3 || !checkdate($date[1], $date[0], $date[2])) + if (count($date) != 3 || !checkdate($date[1], $date[0], $date[2])) { return 'INVALID'; } @@ -1679,17 +1718,21 @@ function phpbb_validate_timezone($timezone) return (in_array($timezone, phpbb_get_timezone_identifiers($timezone))) ? false : 'TIMEZONE_INVALID'; } -/** -* Check to see if the username has been taken, or if it is disallowed. -* Also checks if it includes the " character, which we don't allow in usernames. -* Used for registering, changing names, and posting anonymously with a username -* -* @param string $username The username to check -* @param string $allowed_username An allowed username, default being $user->data['username'] -* -* @return mixed Either false if validation succeeded or a string which will be used as the error message (with the variable name appended) -*/ -function validate_username($username, $allowed_username = false) +/*** + * Validate Username + * + * Check to see if the username has been taken, or if it is disallowed. + * Also checks if it includes the " character or the 4-bytes Unicode ones + * (aka emojis) which we don't allow in usernames. + * Used for registering, changing names, and posting anonymously with a username + * + * @param string $username The username to check + * @param string $allowed_username An allowed username, default being $user->data['username'] + * + * @return mixed Either false if validation succeeded or a string which will be + * used as the error message (with the variable name appended) + */ +function validate_username($username, $allowed_username = false, $allow_all_names = false) { global $config, $db, $user, $cache; @@ -1701,6 +1744,14 @@ function validate_username($username, $allowed_username = false) return false; } + // The very first check is for + // out-of-bounds characters that are currently + // not supported by utf8_bin in MySQL + if (preg_match('/[\x{10000}-\x{10FFFF}]/u', $username)) + { + return 'INVALID_EMOJIS'; + } + // ... fast checks first. if (strpos($username, '"') !== false || strpos($username, '"') !== false || empty($clean_username)) { @@ -1764,13 +1815,16 @@ function validate_username($username, $allowed_username = false) return 'USERNAME_TAKEN'; } - $bad_usernames = $cache->obtain_disallowed_usernames(); - - foreach ($bad_usernames as $bad_username) + if (!$allow_all_names) { - if (preg_match('#^' . $bad_username . '$#', $clean_username)) + $bad_usernames = $cache->obtain_disallowed_usernames(); + + foreach ($bad_usernames as $bad_username) { - return 'USERNAME_DISALLOWED'; + if (preg_match('#^' . $bad_username . '$#', $clean_username)) + { + return 'USERNAME_DISALLOWED'; + } } } @@ -1891,9 +1945,9 @@ function validate_user_email($email, $allowed_email = false) return $validate_email; } - if (($ban_reason = $user->check_ban(false, false, $email, true)) !== false) + if (($ban = $user->check_ban(false, false, $email, true)) !== false) { - return ($ban_reason === true) ? 'EMAIL_BANNED' : $ban_reason; + return ($ban === true) ? 'EMAIL_BANNED' : (!empty($ban['ban_give_reason']) ? $ban['ban_give_reason'] : $ban); } if (!$config['allow_emailreuse']) @@ -1944,7 +1998,7 @@ function validate_jabber($jid) $arr = explode('.', $realm); - if (sizeof($arr) == 0) + if (count($arr) == 0) { return 'WRONG_DATA'; } @@ -2268,7 +2322,7 @@ function group_create(&$group_id, $type, $name, $desc, $group_attributes, $allow $group_teampage = !empty($group_attributes['group_teampage']); unset($group_attributes['group_teampage']); - if (!sizeof($error)) + if (!count($error)) { $current_legend = \phpbb\groupposition\legend::GROUP_DISABLED; $current_teampage = \phpbb\groupposition\teampage::GROUP_DISABLED; @@ -2341,7 +2395,7 @@ function group_create(&$group_id, $type, $name, $desc, $group_attributes, $allow generate_text_for_storage($sql_ary['group_desc'], $sql_ary['group_desc_uid'], $sql_ary['group_desc_bitfield'], $sql_ary['group_desc_options'], $allow_desc_bbcode, $allow_desc_urls, $allow_desc_smilies); } - if (sizeof($group_attributes)) + if (count($group_attributes)) { // Merge them with $sql_ary to properly update the group $sql_ary = array_merge($sql_ary, $group_attributes); @@ -2467,7 +2521,7 @@ function group_create(&$group_id, $type, $name, $desc, $group_attributes, $allow // Set user attributes $sql_ary = array(); - if (sizeof($group_attributes)) + if (count($group_attributes)) { // Go through the user attributes array, check if a group attribute matches it and then set it. ;) foreach ($user_attribute_ary as $attribute) @@ -2487,7 +2541,7 @@ function group_create(&$group_id, $type, $name, $desc, $group_attributes, $allow } } - if (sizeof($sql_ary) && sizeof($user_ary)) + if (count($sql_ary) && count($user_ary)) { group_set_user_default($group_id, $user_ary, $sql_ary); } @@ -2498,7 +2552,7 @@ function group_create(&$group_id, $type, $name, $desc, $group_attributes, $allow group_update_listings($group_id); } - return (sizeof($error)) ? $error : false; + return (count($error)) ? $error : false; } @@ -2663,11 +2717,18 @@ function group_user_add($group_id, $user_id_ary = false, $username_ary = false, // We need both username and user_id info $result = user_get_id_name($user_id_ary, $username_ary); - if (!sizeof($user_id_ary) || $result !== false) + if (empty($user_id_ary) || $result !== false) { return 'NO_USER'; } + // Because the item that gets passed into the previous function is unset, the reference is lost and our original + // array is retained - so we know there's a problem if there's a different number of ids to usernames now. + if (count($user_id_ary) != count($username_ary)) + { + return 'GROUP_USERS_INVALID'; + } + // Remove users who are already members of this group $sql = 'SELECT user_id, group_leader FROM ' . USER_GROUP_TABLE . ' @@ -2691,7 +2752,7 @@ function group_user_add($group_id, $user_id_ary = false, $username_ary = false, $add_id_ary = array_diff($user_id_ary, $add_id_ary); // If we have no users - if (!sizeof($add_id_ary) && !sizeof($update_id_ary)) + if (!count($add_id_ary) && !count($update_id_ary)) { return 'GROUP_USERS_EXIST'; } @@ -2699,7 +2760,7 @@ function group_user_add($group_id, $user_id_ary = false, $username_ary = false, $db->sql_transaction('begin'); // Insert the new users - if (sizeof($add_id_ary)) + if (count($add_id_ary)) { $sql_ary = array(); @@ -2716,7 +2777,7 @@ function group_user_add($group_id, $user_id_ary = false, $username_ary = false, $db->sql_multi_insert(USER_GROUP_TABLE, $sql_ary); } - if (sizeof($update_id_ary)) + if (count($update_id_ary)) { $sql = 'UPDATE ' . USER_GROUP_TABLE . ' SET group_leader = 1 @@ -2808,7 +2869,7 @@ function group_user_del($group_id, $user_id_ary = false, $username_ary = false, // We need both username and user_id info $result = user_get_id_name($user_id_ary, $username_ary); - if (!sizeof($user_id_ary) || $result !== false) + if (empty($user_id_ary) || $result !== false) { return 'NO_USER'; } @@ -2884,7 +2945,7 @@ function group_user_del($group_id, $user_id_ary = false, $username_ary = false, foreach ($special_group_data as $gid => $default_data_ary) { - if (isset($sql_where_ary[$gid]) && sizeof($sql_where_ary[$gid])) + if (isset($sql_where_ary[$gid]) && count($sql_where_ary[$gid])) { remove_default_rank($group_id, $sql_where_ary[$gid]); remove_default_avatar($group_id, $sql_where_ary[$gid]); @@ -3043,7 +3104,7 @@ function group_user_attributes($action, $group_id, $user_id_ary = false, $userna // We need both username and user_id info $result = user_get_id_name($user_id_ary, $username_ary); - if (!sizeof($user_id_ary) || $result !== false) + if (empty($user_id_ary) || $result !== false) { return 'NO_USERS'; } @@ -3098,7 +3159,7 @@ function group_user_attributes($action, $group_id, $user_id_ary = false, $userna } $db->sql_freeresult($result); - if (!sizeof($user_id_ary)) + if (!count($user_id_ary)) { return false; } @@ -3139,7 +3200,7 @@ function group_user_attributes($action, $group_id, $user_id_ary = false, $userna $db->sql_freeresult($result); $result = user_get_id_name($user_id_ary, $username_ary); - if (!sizeof($user_id_ary) || $result !== false) + if (!count($user_id_ary) || $result !== false) { return 'NO_USERS'; } @@ -3502,7 +3563,7 @@ function group_update_listings($group_id) $hold_ary = $auth->acl_group_raw_data($group_id, array('a_', 'm_')); - if (!sizeof($hold_ary)) + if (empty($hold_ary)) { return; } @@ -3589,11 +3650,6 @@ function remove_newly_registered($user_id, $user_data = false) } } - if (empty($user_data['user_new'])) - { - return false; - } - $sql = 'SELECT group_id FROM ' . GROUPS_TABLE . " WHERE group_name = 'NEWLY_REGISTERED' |