diff options
Diffstat (limited to 'phpBB/includes')
24 files changed, 367 insertions, 113 deletions
diff --git a/phpBB/includes/acp/acp_forums.php b/phpBB/includes/acp/acp_forums.php index f2f1bd80e2..4d9b9f01e0 100644 --- a/phpBB/includes/acp/acp_forums.php +++ b/phpBB/includes/acp/acp_forums.php @@ -1642,6 +1642,9 @@ class acp_forums  		delete_attachments('topic', $topic_ids, false); +		// Delete shadow topics pointing to topics in this forum +		delete_topic_shadows($forum_id); +  		// Before we remove anything we make sure we are able to adjust the post counts later. ;)  		$sql = 'SELECT poster_id  			FROM ' . POSTS_TABLE . ' diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index 1f10893781..9e8a4c80b9 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -319,10 +319,7 @@ class acp_users  								$server_url = generate_board_url(); -								$user_actkey = gen_rand_string(10); -								$key_len = 54 - (strlen($server_url)); -								$key_len = ($key_len > 6) ? $key_len : 6; -								$user_actkey = substr($user_actkey, 0, $key_len); +								$user_actkey = gen_rand_string(mt_rand(6, 10));  								$email_template = ($user_row['user_type'] == USER_NORMAL) ? 'user_reactivate_account' : 'user_resend_inactive';  								if ($user_row['user_type'] == USER_NORMAL) diff --git a/phpBB/includes/cache.php b/phpBB/includes/cache.php index 6b1e078ca4..b50fab4ca2 100644 --- a/phpBB/includes/cache.php +++ b/phpBB/includes/cache.php @@ -88,7 +88,14 @@ class cache extends acm  			{  				if ($unicode)  				{ -					$censors['match'][] = '#(?<![\p{Nd}\p{L}_])(' . str_replace('\*', '[\p{Nd}\p{L}_]*?', preg_quote($row['word'], '#')) . ')(?![\p{Nd}\p{L}_])#iu'; +					// Unescape the asterisk to simplify further conversions +					$row['word'] = str_replace('\*', '*', preg_quote($row['word'], '#')); +					 +					// Replace the asterisk inside the pattern, at the start and at the end of it with regexes +					$row['word'] = preg_replace(array('#(?<=[\p{Nd}\p{L}_])\*(?=[\p{Nd}\p{L}_])#iu', '#^\*#', '#\*$#'), array('([\x20]*?|[\p{Nd}\p{L}_-]*?)', '[\p{Nd}\p{L}_-]*?', '[\p{Nd}\p{L}_-]*?'), $row['word']); + +					// Generate the final substitution +					$censors['match'][] = '#(?<![\p{Nd}\p{L}_-])(' . $row['word'] . ')(?![\p{Nd}\p{L}_-])#iu';  				}  				else  				{ diff --git a/phpBB/includes/captcha/plugins/captcha_abstract.php b/phpBB/includes/captcha/plugins/captcha_abstract.php index e7b8742b05..21cacd730c 100644 --- a/phpBB/includes/captcha/plugins/captcha_abstract.php +++ b/phpBB/includes/captcha/plugins/captcha_abstract.php @@ -59,7 +59,7 @@ class phpbb_default_captcha  	{  		global $user; -		$this->code = gen_rand_string(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS)); +		$this->code = gen_rand_string_friendly(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS));  		$this->seed = hexdec(substr(unique_id(), 4, 10));  		// compute $seed % 0x7fffffff @@ -235,7 +235,7 @@ class phpbb_default_captcha  	{  		global $db, $user; -		$this->code = gen_rand_string(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS)); +		$this->code = gen_rand_string_friendly(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS));  		$this->confirm_id = md5(unique_id($user->ip));  		$this->seed = hexdec(substr(unique_id(), 4, 10));  		$this->solved = 0; @@ -259,7 +259,7 @@ class phpbb_default_captcha  	{  		global $db, $user; -		$this->code = gen_rand_string(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS)); +		$this->code = gen_rand_string_friendly(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS));  		$this->seed = hexdec(substr(unique_id(), 4, 10));  		$this->solved = 0;  		// compute $seed % 0x7fffffff @@ -281,7 +281,7 @@ class phpbb_default_captcha  	{  		global $db, $user; -		$this->code = gen_rand_string(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS)); +		$this->code = gen_rand_string_friendly(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS));  		$this->seed = hexdec(substr(unique_id(), 4, 10));  		$this->solved = 0;  		// compute $seed % 0x7fffffff diff --git a/phpBB/includes/db/mssqlnative.php b/phpBB/includes/db/mssqlnative.php index 98e22d4412..44d5722e4f 100644..100755 --- a/phpBB/includes/db/mssqlnative.php +++ b/phpBB/includes/db/mssqlnative.php @@ -503,6 +503,7 @@ class dbal_mssqlnative extends dbal  	{  		$errors = @sqlsrv_errors(SQLSRV_ERR_ERRORS);  		$error_message = ''; +		$code = 0;  		if ($errors != null)  		{ @@ -510,6 +511,7 @@ class dbal_mssqlnative extends dbal  			{  				$error_message .= "SQLSTATE: ".$error[ 'SQLSTATE']."\n";  				$error_message .= "code: ".$error[ 'code']."\n"; +				$code = $error['code'];  				$error_message .= "message: ".$error[ 'message']."\n";  			}  			$this->last_error_result = $error_message; @@ -519,7 +521,11 @@ class dbal_mssqlnative extends dbal  		{  			$error = (isset($this->last_error_result) && $this->last_error_result) ? $this->last_error_result : array();  		} -		return $error; + +		return array( +			'message'	=> $error, +			'code'		=> $code, +		);  	}  	/** diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index fe80880789..0f6f992069 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -195,10 +195,27 @@ function set_config_count($config_name, $increment, $is_dynamic = false)  /**  * Generates an alphanumeric random string of given length +* +* @return string  */  function gen_rand_string($num_chars = 8)  { +	// [a, z] + [0, 9] = 36 +	return substr(strtoupper(base_convert(unique_id(), 16, 36)), 0, $num_chars); +} + +/** +* Generates a user-friendly alphanumeric random string of given length +* We remove 0 and O so users cannot confuse those in passwords etc. +* +* @return string +*/ +function gen_rand_string_friendly($num_chars = 8) +{  	$rand_str = unique_id(); + +	// Remove Z and Y from the base_convert(), replace 0 with Z and O with Y +	// [a, z] + [0, 9] - {z, y} = [a, z] + [0, 9] - {0, o} = 34  	$rand_str = str_replace(array('0', 'O'), array('Z', 'Y'), strtoupper(base_convert($rand_str, 16, 34)));  	return substr($rand_str, 0, $num_chars); @@ -2519,6 +2536,11 @@ function build_url($strip_vars = false)  			$key = $arguments[0];  			unset($arguments[0]); +			if ($key === '') +			{ +				continue; +			} +  			$query[$key] = implode('=', $arguments);  		} @@ -3355,7 +3377,9 @@ function get_preg_expression($mode)  	switch ($mode)  	{  		case 'email': -			return '(?:[a-z0-9\'\.\-_\+\|]++|&)+@[a-z0-9\-]+\.(?:[a-z0-9\-]+\.)*[a-z]+'; +			// Regex written by James Watts and Francisco Jose Martin Moreno +			// http://fightingforalostcause.net/misc/2006/compare-email-regex.php +			return '([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*(?:[\w\!\#$\%\'\*\+\-\/\=\?\^\`{\|\}\~]|&)+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,6})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)';  		break;  		case 'bbcode_htm': @@ -3438,26 +3462,110 @@ function short_ipv6($ip, $length)  /**  * Wrapper for php's checkdnsrr function.  * -* The windows failover is from the php manual -* Please make sure to check the return value for === true and === false, since NULL could -* be returned too. +* @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  * -* @return true if entry found, false if not, 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, +* +* @author bantu  */ -function phpbb_checkdnsrr($host, $type = '') +function phpbb_checkdnsrr($host, $type = 'MX')  { -	$type = (!$type) ? 'MX' : $type; +	// 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. -	// Call checkdnsrr() if available. This is also the case on Windows with PHP 5.3 or later. -	if (function_exists('checkdnsrr')) +	// If we're looking for an A record we can use gethostbyname() +	if ($type == 'A' && function_exists('gethostbyname'))  	{ -		// The dot indicates to search the DNS root (helps those having DNS prefixes on the same domain) -		return checkdnsrr($host . '.', $type); +		return (@gethostbyname($host_fqdn) == $host_fqdn) ? false : true;  	} -	else if (DIRECTORY_SEPARATOR == '\\' && function_exists('exec')) + +	// checkdnsrr() is available on Windows since PHP 5.3, +	// but until 5.3.3 it only works for MX records +	// See: http://bugs.php.net/bug.php?id=51844 + +	// Call checkdnsrr() if  +	// we're looking for an MX record or +	// we're not on Windows or +	// we're running a PHP version where #51844 has been fixed + +	// checkdnsrr() supports AAAA since 5.0.0 +	// checkdnsrr() supports TXT since 5.2.4 +	if ( +		($type == 'MX' || DIRECTORY_SEPARATOR != '\\' || version_compare(PHP_VERSION, '5.3.3', '>=')) && +		($type != 'AAAA' || version_compare(PHP_VERSION, '5.0.0', '>=')) && +		($type != 'TXT' || version_compare(PHP_VERSION, '5.2.4', '>=')) && +		function_exists('checkdnsrr') +	)  	{ -		// @exec('nslookup -retry=1 -timout=1 -type=' . escapeshellarg($type) . ' ' . escapeshellarg($host), $output); -		@exec('nslookup -type=' . escapeshellarg($type) . ' ' . escapeshellarg($host) . '.', $output); +		return checkdnsrr($host_fqdn, $type); +	} + +	// dns_get_record() is available since PHP 5; since PHP 5.3 also on Windows, +	// but on Windows it does not work reliable for AAAA records before PHP 5.3.1 + +	// Call dns_get_record() if  +	// we're not looking for an AAAA record or +	// we're not on Windows or +	// we're running a PHP version where AAAA lookups work reliable +	if ( +		($type != 'AAAA' || DIRECTORY_SEPARATOR != '\\' || version_compare(PHP_VERSION, '5.3.1', '>=')) && +		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)) @@ -3467,15 +3575,66 @@ function phpbb_checkdnsrr($host, $type = '')  		foreach ($output as $line)  		{ -			if (!trim($line)) +			$line = trim($line); + +			if (empty($line))  			{  				continue;  			} -			// Valid records begin with host name: -			if (strpos($line, $host) === 0) +			// Squash tabs and multiple whitespaces to a single whitespace. +			$line = preg_replace('/\s+/', ' ', $line); + +			switch ($type)  			{ -				return true; +				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; +					} + +				default: +				case 'A': +				case 'AAAA': +					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;  			}  		} diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index 4cd2962e3b..3178d35c34 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -573,8 +573,8 @@ function move_posts($post_ids, $topic_id, $auto_sync = true)  	while ($row = $db->sql_fetchrow($result))  	{ -		$forum_ids[] = $row['forum_id']; -		$topic_ids[] = $row['topic_id']; +		$forum_ids[] = (int) $row['forum_id']; +		$topic_ids[] = (int) $row['topic_id'];  	}  	$db->sql_freeresult($result); @@ -591,7 +591,7 @@ function move_posts($post_ids, $topic_id, $auto_sync = true)  	}  	$sql = 'UPDATE ' . POSTS_TABLE . ' -		SET forum_id = ' . $forum_row['forum_id'] . ", topic_id = $topic_id +		SET forum_id = ' . (int) $forum_row['forum_id'] . ", topic_id = $topic_id  		WHERE " . $db->sql_in_set('post_id', $post_ids);  	$db->sql_query($sql); @@ -602,7 +602,7 @@ function move_posts($post_ids, $topic_id, $auto_sync = true)  	if ($auto_sync)  	{ -		$forum_ids[] = $forum_row['forum_id']; +		$forum_ids[] = (int) $forum_row['forum_id'];  		sync('topic_reported', 'topic_id', $topic_ids);  		sync('topic_attachment', 'topic_id', $topic_ids); @@ -1125,53 +1125,65 @@ function delete_attachments($mode, $ids, $resync = true)  }  /** -* Remove topic shadows +* Deletes shadow topics pointing to a specified forum. +* +* @param int		$forum_id		The forum id +* @param string		$sql_more		Additional WHERE statement, e.g. t.topic_time < (time() - 1234) +* @param bool		$auto_sync		Will call sync() if this is true +* +* @return array		Array with affected forums +* +* @author bantu  */ -function delete_topic_shadows($max_age, $forum_id = '', $auto_sync = true) +function delete_topic_shadows($forum_id, $sql_more = '', $auto_sync = true)  { -	$where = (is_array($forum_id)) ? 'AND ' . $db->sql_in_set('t.forum_id', array_map('intval', $forum_id)) : (($forum_id) ? 'AND t.forum_id = ' . (int) $forum_id : ''); +	global $db; -	switch ($db->sql_layer) +	if (!$forum_id)  	{ -		case 'mysql4': -		case 'mysqli': -			$sql = 'DELETE t.* -				FROM ' . TOPICS_TABLE . ' t, ' . TOPICS_TABLE . ' t2 -				WHERE t.topic_moved_id = t2.topic_id -					AND t.topic_time < ' . (time() - $max_age) -				. $where; -			$db->sql_query($sql); -		break; +		// Nothing to do. +		return; +	} -		default: -			$sql = 'SELECT t.topic_id -				FROM ' . TOPICS_TABLE . ' t, ' . TOPICS_TABLE . ' t2 -				WHERE t.topic_moved_id = t2.topic_id -					AND t.topic_time < ' . (time() - $max_age) -				. $where; -			$result = $db->sql_query($sql); +	// Set of affected forums we have to resync +	$sync_forum_ids = array(); -			$topic_ids = array(); -			while ($row = $db->sql_fetchrow($result)) -			{ -				$topic_ids[] = $row['topic_id']; -			} -			$db->sql_freeresult($result); +	// Amount of topics we select and delete at once. +	$batch_size = 500; -			if (sizeof($topic_ids)) -			{ -				$sql = 'DELETE FROM ' . TOPICS_TABLE . ' -					WHERE ' . $db->sql_in_set('topic_id', $topic_ids); -				$db->sql_query($sql); -			} -		break; +	do +	{ +		$sql = 'SELECT t2.forum_id, t2.topic_id +			FROM ' . TOPICS_TABLE . ' t2, ' . TOPICS_TABLE . ' t +			WHERE t2.topic_moved_id = t.topic_id +				AND t.forum_id = ' . (int) $forum_id . ' +				' . (($sql_more) ? 'AND ' . $sql_more : ''); +		$result = $db->sql_query_limit($sql, $batch_size); + +		$topic_ids = array(); +		while ($row = $db->sql_fetchrow($result)) +		{ +			$topic_ids[] = (int) $row['topic_id']; + +			$sync_forum_ids[(int) $row['forum_id']] = (int) $row['forum_id']; +		} +		$db->sql_freeresult($result); + +		if (!empty($topic_ids)) +		{ +			$sql = 'DELETE FROM ' . TOPICS_TABLE . ' +				WHERE ' . $db->sql_in_set('topic_id', $topic_ids); +			$db->sql_query($sql); +		}  	} +	while (sizeof($topic_ids) == $batch_size);  	if ($auto_sync)  	{ -		$where_type = ($forum_id) ? 'forum_id' : ''; -		sync('forum', $where_type, $forum_id, true, true); +		sync('forum', 'forum_id', $sync_forum_ids, true, true);  	} + +	return $sync_forum_ids;  }  /** diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index 5e6239b070..2de7e1b169 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -396,7 +396,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod  		}  		else  		{ -			$folder_alt = ($forum_unread) ? 'NEW_POSTS' : 'NO_NEW_POSTS'; +			$folder_alt = ($forum_unread) ? 'UNREAD_POSTS' : 'NO_UNREAD_POSTS';  		}  		// Create last post link information, if appropriate @@ -425,7 +425,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod  		$s_subforums_list = array();  		foreach ($subforums_list as $subforum)  		{ -			$s_subforums_list[] = '<a href="' . $subforum['link'] . '" class="subforum ' . (($subforum['unread']) ? 'unread' : 'read') . '" title="' . (($subforum['unread']) ? $user->lang['NEW_POSTS'] : $user->lang['NO_NEW_POSTS']) . '">' . $subforum['name'] . '</a>'; +			$s_subforums_list[] = '<a href="' . $subforum['link'] . '" class="subforum ' . (($subforum['unread']) ? 'unread' : 'read') . '" title="' . (($subforum['unread']) ? $user->lang['UNREAD_POSTS'] : $user->lang['NO_UNREAD_POSTS']) . '">' . $subforum['name'] . '</a>';  		}  		$s_subforums_list = (string) implode(', ', $s_subforums_list);  		$catless = ($row['parent_id'] == $root_data['forum_id']) ? true : false; @@ -854,7 +854,7 @@ function topic_status(&$topic_row, $replies, $unread_topic, &$folder_img, &$fold  		$folder_img = ($unread_topic) ? $folder_new : $folder; -		$folder_alt = ($unread_topic) ? 'NEW_POSTS' : (($topic_row['topic_status'] == ITEM_LOCKED) ? 'TOPIC_LOCKED' : 'NO_NEW_POSTS'); +		$folder_alt = ($unread_topic) ? 'UNREAD_POSTS' : (($topic_row['topic_status'] == ITEM_LOCKED) ? 'TOPIC_LOCKED' : 'NO_UNREAD_POSTS');  		// Posted image?  		if (!empty($topic_row['topic_posted']) && $topic_row['topic_posted']) diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php index 99883cd9ca..bb0d88ec1b 100644 --- a/phpBB/includes/functions_messenger.php +++ b/phpBB/includes/functions_messenger.php @@ -671,11 +671,18 @@ class queue  			$package_size = $data_ary['package_size'];  			$num_items = (!$package_size || sizeof($data_ary['data']) < $package_size) ? sizeof($data_ary['data']) : $package_size; +			/* +			* This code is commented out because it causes problems on some web hosts. +			* The core problem is rather restrictive email sending limits. +			* This code is nly useful if you have no such restrictions from the +			* web host and the package size setting is wrong. +  			// If the amount of emails to be sent is way more than package_size than we need to increase it to prevent backlogs...  			if (sizeof($data_ary['data']) > $package_size * 2.5)  			{  				$num_items = sizeof($data_ary['data']);  			} +			*/  			switch ($object)  			{ diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index f6f90575d4..5e25648eb8 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -2537,7 +2537,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u  	if ($mode == 'post' || $mode == 'reply' || $mode == 'quote')  	{  		// Mark this topic as posted to -		markread('post', $data['forum_id'], $data['topic_id'], $data['post_time']); +		markread('post', $data['forum_id'], $data['topic_id']);  	}  	// Mark this topic as read diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php index 4fc5034f7b..4c34bc92ca 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -1380,6 +1380,9 @@ function submit_pm($mode, $subject, &$data, $put_in_outbox = true)  		}  	} +	// First of all make sure the subject are having the correct length. +	$subject = truncate_string($subject); +  	$db->sql_transaction('begin');  	$sql = ''; @@ -1751,6 +1754,8 @@ function message_history($msg_id, $user_id, $message_row, $folder, $in_post_mode  		return false;  	} +	$title = $row['message_subject']; +  	$rowset = array();  	$bbcode_bitfield = '';  	$folder_url = append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm') . '&folder='; @@ -1774,8 +1779,6 @@ function message_history($msg_id, $user_id, $message_row, $folder, $in_post_mode  	while ($row = $db->sql_fetchrow($result));  	$db->sql_freeresult($result); -	$title = $row['message_subject']; -  	if (sizeof($rowset) == 1 && !$in_post_mode)  	{  		return false; diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index 6f6d7526b7..d3594196b7 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -766,7 +766,8 @@ function user_ban($mode, $ban, $ban_len, $ban_len_other, $ban_exclude, $ban_reas  			if (sizeof($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, gmmktime(0, 0, 0, (int)$ban_other[1], (int)$ban_other[2], (int)$ban_other[0])); +				$time_offset = (isset($user->timezone) && isset($user->dst)) ? (int) $user->timezone + (int) $user->dst : 0; +				$ban_end = max($current_time, gmmktime(0, 0, 0, (int)$ban_other[1], (int)$ban_other[2], (int)$ban_other[0]) - $time_offset);  			}  			else  			{ @@ -1229,22 +1230,39 @@ function user_unban($mode, $ban)  }  /** -* Whois facility +* Internet Protocol Address Whois +* RFC3912: WHOIS Protocol Specification  * -* @link http://tools.ietf.org/html/rfc3912 RFC3912: WHOIS Protocol Specification +* @param string $ip		Ip address, either IPv4 or IPv6. +* +* @return string		Empty string if not a valid ip address. +*						Otherwise make_clickable()'ed whois result.  */  function user_ipwhois($ip)  { -	$ipwhois = ''; +	if (empty($ip)) +	{ +		return ''; +	} -	// Check IP -	// Only supporting IPv4 at the moment... -	if (empty($ip) || !preg_match(get_preg_expression('ipv4'), $ip)) +	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  	{  		return '';  	} -	if (($fsk = @fsockopen('whois.arin.net', 43))) +	$ipwhois = ''; + +	if (($fsk = @fsockopen($whois_host, 43)))  	{  		// CRLF as per RFC3912  		fputs($fsk, "$ip\r\n"); @@ -1257,7 +1275,7 @@ function user_ipwhois($ip)  	$match = array(); -	// Test for referrals from ARIN to other whois databases, roll on rwhois +	// Test for referrals from $whois_host to other whois databases, roll on rwhois  	if (preg_match('#ReferralServer: whois://(.+)#im', $ipwhois, $match))  	{  		if (strpos($match[1], ':') !== false) @@ -1285,7 +1303,7 @@ function user_ipwhois($ip)  			@fclose($fsk);  		} -		// Use the result from ARIN if we don't get any result here +		// Use the result from $whois_host if we don't get any result here  		$ipwhois = (empty($buffer)) ? $ipwhois : $buffer;  	} @@ -2352,7 +2370,7 @@ function avatar_process_user(&$error, $custom_userdata = false, $can_upload = nu  		}  		else  		{ -			list($sql_ary['user_avatar_width'], $sql_ary['user_avatar_height']) = getimagesize($phpbb_root_path . $config['avatar_gallery_path'] . '/' . $category . '/' . $sql_ary['user_avatar']); +			list($sql_ary['user_avatar_width'], $sql_ary['user_avatar_height']) = getimagesize($phpbb_root_path . $config['avatar_gallery_path'] . '/' . $category . '/' . urldecode($sql_ary['user_avatar']));  			$sql_ary['user_avatar'] = $category . '/' . $sql_ary['user_avatar'];  		}  	} diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php index 80c3559649..d5551f5114 100644 --- a/phpBB/includes/mcp/mcp_main.php +++ b/phpBB/includes/mcp/mcp_main.php @@ -1048,6 +1048,35 @@ function mcp_fork_topic($topic_ids)  		$total_posts = 0;  		$new_topic_id_list = array(); +		if ($topic_data['enable_indexing']) +		{ +			// Select the search method and do some additional checks to ensure it can actually be utilised +			$search_type = basename($config['search_type']); + +			if (!file_exists($phpbb_root_path . 'includes/search/' . $search_type . '.' . $phpEx)) +			{ +				trigger_error('NO_SUCH_SEARCH_MODULE'); +			} + +			if (!class_exists($search_type)) +			{ +				include("{$phpbb_root_path}includes/search/$search_type.$phpEx"); +			} + +			$error = false; +			$search = new $search_type($error); +			$search_mode = 'post'; + +			if ($error) +			{ +				trigger_error($error); +			} +		} +		else +		{ +			$search_type = false; +		} +  		foreach ($topic_data as $topic_id => $topic_row)  		{  			$sql_ary = array( @@ -1158,6 +1187,12 @@ function mcp_fork_topic($topic_ids)  				// Copy whether the topic is dotted  				markread('post', $to_forum_id, $new_topic_id, 0, $row['poster_id']); +				if ($search_type) +				{ +					$search->index($search_mode, $sql_ary['post_id'], $sql_ary['post_text'], $sql_ary['post_subject'], $sql_ary['poster_id'], ($topic_row['topic_type'] == POST_GLOBAL) ? 0 : $to_forum_id); +					$search_mode = 'reply'; // After one we index replies +				} +  				// Copy Attachments  				if ($row['post_attachment'])  				{ diff --git a/phpBB/includes/mcp/mcp_post.php b/phpBB/includes/mcp/mcp_post.php index fa44e006dd..7098b4bbce 100644 --- a/phpBB/includes/mcp/mcp_post.php +++ b/phpBB/includes/mcp/mcp_post.php @@ -176,7 +176,7 @@ function mcp_post_details($id, $mode, $action)  	}  	$template->assign_vars(array( -		'U_MCP_ACTION'			=> "$url&i=main&quickmod=1", // Use this for mode paramaters +		'U_MCP_ACTION'			=> "$url&i=main&quickmod=1&mode=post_details", // Use this for mode paramaters  		'U_POST_ACTION'			=> "$url&i=$id&mode=post_details", // Use this for action parameters  		'U_APPROVE_ACTION'		=> append_sid("{$phpbb_root_path}mcp.$phpEx", "i=queue&p=$post_id&f={$post_info['forum_id']}"), @@ -200,7 +200,7 @@ function mcp_post_details($id, $mode, $action)  		'U_VIEW_POST'			=> append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $post_info['forum_id'] . '&p=' . $post_info['post_id'] . '#p' . $post_info['post_id']),  		'U_VIEW_TOPIC'			=> append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $post_info['forum_id'] . '&t=' . $post_info['topic_id']), -		'MINI_POST_IMG'			=> ($post_unread) ? $user->img('icon_post_target_unread', 'NEW_POST') : $user->img('icon_post_target', 'POST'), +		'MINI_POST_IMG'			=> ($post_unread) ? $user->img('icon_post_target_unread', 'UNREAD_POST') : $user->img('icon_post_target', 'POST'),  		'RETURN_TOPIC'			=> sprintf($user->lang['RETURN_TOPIC'], '<a href="' . append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f={$post_info['forum_id']}&p=$post_id") . "#p$post_id\">", '</a>'),  		'RETURN_FORUM'			=> sprintf($user->lang['RETURN_FORUM'], '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", "f={$post_info['forum_id']}&start={$start}") . '">', '</a>'), diff --git a/phpBB/includes/mcp/mcp_queue.php b/phpBB/includes/mcp/mcp_queue.php index 8d9ece5205..e43881fab2 100644 --- a/phpBB/includes/mcp/mcp_queue.php +++ b/phpBB/includes/mcp/mcp_queue.php @@ -196,7 +196,7 @@ class mcp_queue  					'U_VIEW_POST'			=> $post_url,  					'U_VIEW_TOPIC'			=> $topic_url, -					'MINI_POST_IMG'			=> ($post_unread) ? $user->img('icon_post_target_unread', 'NEW_POST') : $user->img('icon_post_target', 'POST'), +					'MINI_POST_IMG'			=> ($post_unread) ? $user->img('icon_post_target_unread', 'UNREAD_POST') : $user->img('icon_post_target', 'POST'),  					'RETURN_QUEUE'			=> sprintf($user->lang['RETURN_QUEUE'], '<a href="' . append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue' . (($topic_id) ? '&mode=unapproved_topics' : '&mode=unapproved_posts')) . "&start=$start\">", '</a>'),  					'RETURN_POST'			=> sprintf($user->lang['RETURN_POST'], '<a href="' . $post_url . '">', '</a>'), @@ -691,16 +691,19 @@ function approve_post($post_id_list, $id, $mode)  	{  		$show_notify = false; -		foreach ($post_info as $post_data) +		if ($config['email_enable'] || $config['jab_enable'])  		{ -			if ($post_data['poster_id'] == ANONYMOUS) -			{ -				continue; -			} -			else +			foreach ($post_info as $post_data)  			{ -				$show_notify = true; -				break; +				if ($post_data['poster_id'] == ANONYMOUS) +				{ +					continue; +				} +				else +				{ +					$show_notify = true; +					break; +				}  			}  		} diff --git a/phpBB/includes/mcp/mcp_reports.php b/phpBB/includes/mcp/mcp_reports.php index e19fe96963..39d9fbd4af 100644 --- a/phpBB/includes/mcp/mcp_reports.php +++ b/phpBB/includes/mcp/mcp_reports.php @@ -205,7 +205,7 @@ class mcp_reports  					'U_VIEW_TOPIC'				=> append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $post_info['forum_id'] . '&t=' . $post_info['topic_id']),  					'EDIT_IMG'				=> $user->img('icon_post_edit', $user->lang['EDIT_POST']), -					'MINI_POST_IMG'			=> ($post_unread) ? $user->img('icon_post_target_unread', 'NEW_POST') : $user->img('icon_post_target', 'POST'), +					'MINI_POST_IMG'			=> ($post_unread) ? $user->img('icon_post_target_unread', 'UNREAD_POST') : $user->img('icon_post_target', 'POST'),  					'UNAPPROVED_IMG'		=> $user->img('icon_topic_unapproved', $user->lang['POST_UNAPPROVED']),  					'RETURN_REPORTS'			=> sprintf($user->lang['RETURN_REPORTS'], '<a href="' . append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=reports' . (($post_info['post_reported']) ? '&mode=reports' : '&mode=reports_closed') . '&start=' . $start . '&f=' . $post_info['forum_id']) . '">', '</a>'), diff --git a/phpBB/includes/mcp/mcp_topic.php b/phpBB/includes/mcp/mcp_topic.php index 9779478330..76cd9beb92 100644 --- a/phpBB/includes/mcp/mcp_topic.php +++ b/phpBB/includes/mcp/mcp_topic.php @@ -237,7 +237,7 @@ function mcp_topic_view($id, $mode, $action)  			'POST_ID'		=> $row['post_id'],  			'RETURN_TOPIC'	=> sprintf($user->lang['RETURN_TOPIC'], '<a href="' . append_sid("{$phpbb_root_path}viewtopic.$phpEx", 't=' . $topic_id) . '">', '</a>'), -			'MINI_POST_IMG'			=> ($post_unread) ? $user->img('icon_post_target_unread', 'NEW_POST') : $user->img('icon_post_target', 'POST'), +			'MINI_POST_IMG'			=> ($post_unread) ? $user->img('icon_post_target_unread', 'UNREAD_POST') : $user->img('icon_post_target', 'POST'),  			'S_POST_REPORTED'	=> ($row['post_reported']) ? true : false,  			'S_POST_UNAPPROVED'	=> ($row['post_approved']) ? false : true, diff --git a/phpBB/includes/search/fulltext_mysql.php b/phpBB/includes/search/fulltext_mysql.php index da3833754e..0be3a10e5f 100644 --- a/phpBB/includes/search/fulltext_mysql.php +++ b/phpBB/includes/search/fulltext_mysql.php @@ -122,7 +122,7 @@ class fulltext_mysql extends search_backend  		if ($terms == 'all')  		{ -			$match		= array('#\sand\s#iu', '#\sor\s#iu', '#\snot\s#iu', '#\+#', '#-#', '#\|#'); +			$match		= array('#\sand\s#iu', '#\sor\s#iu', '#\snot\s#iu', '#(^|\s)\+#', '#(^|\s)-#', '#(^|\s)\|#');  			$replace	= array(' +', ' |', ' -', ' +', ' -', ' |');  			$keywords = preg_replace($match, $replace, $keywords); diff --git a/phpBB/includes/search/fulltext_native.php b/phpBB/includes/search/fulltext_native.php index c89e92711e..727e3aaffb 100644 --- a/phpBB/includes/search/fulltext_native.php +++ b/phpBB/includes/search/fulltext_native.php @@ -83,7 +83,9 @@ class fulltext_native extends search_backend  	{  		global $db, $user, $config; -		$keywords = trim($this->cleanup($keywords, '+-|()*')); +		$tokens = '+-|()*'; + +		$keywords = trim($this->cleanup($keywords, $tokens));  		// allow word|word|word without brackets  		if ((strpos($keywords, ' ') === false) && (strpos($keywords, '|') !== false) && (strpos($keywords, '(') === false)) @@ -114,6 +116,15 @@ class fulltext_native extends search_backend  					case ' ':  						$keywords[$i] = '|';  					break; +					case '*': +						if ($i === 0 || ($keywords[$i - 1] !== '*' && strcspn($keywords[$i - 1], $tokens) === 0)) +						{ +							if ($i === $n - 1 || ($keywords[$i + 1] !== '*' && strcspn($keywords[$i + 1], $tokens) === 0)) +							{ +								$keywords = substr($keywords, 0, $i) . substr($keywords, $i + 1); +							} +						} +					break;  				}  			}  			else diff --git a/phpBB/includes/session.php b/phpBB/includes/session.php index d6f5bde997..7da72cb6d2 100644 --- a/phpBB/includes/session.php +++ b/phpBB/includes/session.php @@ -1831,7 +1831,7 @@ class user extends session  		// Is load exceeded?  		if ($config['limit_load'] && $this->load !== false)  		{ -			if ($this->load > floatval($config['limit_load']) && !defined('IN_LOGIN')) +			if ($this->load > floatval($config['limit_load']) && !defined('IN_LOGIN') && !defined('IN_ADMIN'))  			{  				// Set board disabled to true to let the admins/mods get the proper notification  				$config['board_disable'] = '1'; diff --git a/phpBB/includes/ucp/ucp_main.php b/phpBB/includes/ucp/ucp_main.php index 6ac2412ef0..a6f71669ce 100644 --- a/phpBB/includes/ucp/ucp_main.php +++ b/phpBB/includes/ucp/ucp_main.php @@ -119,7 +119,7 @@ class ucp_main  					$unread_topic = (isset($topic_tracking_info[$topic_id]) && $row['topic_last_post_time'] > $topic_tracking_info[$topic_id]) ? true : false;  					$folder_img = ($unread_topic) ? $folder_new : $folder; -					$folder_alt = ($unread_topic) ? 'NEW_POSTS' : (($row['topic_status'] == ITEM_LOCKED) ? 'TOPIC_LOCKED' : 'NO_NEW_POSTS'); +					$folder_alt = ($unread_topic) ? 'UNREAD_POSTS' : (($row['topic_status'] == ITEM_LOCKED) ? 'TOPIC_LOCKED' : 'NO_UNREAD_POSTS');  					if ($row['topic_status'] == ITEM_LOCKED)  					{ @@ -318,7 +318,7 @@ class ucp_main  						else  						{  							$folder_image = ($unread_forum) ? 'forum_unread' : 'forum_read'; -							$folder_alt = ($unread_forum) ? 'NEW_POSTS' : 'NO_NEW_POSTS'; +							$folder_alt = ($unread_forum) ? 'UNREAD_POSTS' : 'NO_UNREAD_POSTS';  						}  						// Create last post link information, if appropriate diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php index 363a4803b6..4fd25b7d1c 100644 --- a/phpBB/includes/ucp/ucp_profile.php +++ b/phpBB/includes/ucp/ucp_profile.php @@ -141,10 +141,7 @@ class ucp_profile  							$server_url = generate_board_url(); -							$user_actkey = gen_rand_string(10); -							$key_len = 54 - (strlen($server_url)); -							$key_len = ($key_len > 6) ? $key_len : 6; -							$user_actkey = substr($user_actkey, 0, $key_len); +							$user_actkey = gen_rand_string(mt_rand(6, 10));  							$messenger = new messenger(false); diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php index 9656a4a3af..7fd99da55a 100644 --- a/phpBB/includes/ucp/ucp_register.php +++ b/phpBB/includes/ucp/ucp_register.php @@ -286,11 +286,7 @@ class ucp_register  					$config['require_activation'] == USER_ACTIVATION_SELF ||  					$config['require_activation'] == USER_ACTIVATION_ADMIN) && $config['email_enable'])  				{ -					$user_actkey = gen_rand_string(10); -					$key_len = 54 - (strlen($server_url)); -					$key_len = ($key_len < 6) ? 6 : $key_len; -					$user_actkey = substr($user_actkey, 0, $key_len); - +					$user_actkey = gen_rand_string(mt_rand(6, 10));  					$user_type = USER_INACTIVE;  					$user_inactive_reason = INACTIVE_REGISTER;  					$user_inactive_time = time(); diff --git a/phpBB/includes/ucp/ucp_remind.php b/phpBB/includes/ucp/ucp_remind.php index f9b792de20..cb89ad99be 100644 --- a/phpBB/includes/ucp/ucp_remind.php +++ b/phpBB/includes/ucp/ucp_remind.php @@ -79,10 +79,10 @@ class ucp_remind  			// Make password at least 8 characters long, make it longer if admin wants to.  			// gen_rand_string() however has a limit of 12 or 13. -			$user_password = gen_rand_string(max(8, rand((int) $config['min_pass_chars'], (int) $config['max_pass_chars']))); +			$user_password = gen_rand_string_friendly(max(8, mt_rand((int) $config['min_pass_chars'], (int) $config['max_pass_chars'])));  			// For the activation key a random length between 6 and 10 will do. -			$user_actkey = gen_rand_string(rand(6, 10)); +			$user_actkey = gen_rand_string(mt_rand(6, 10));  			$sql = 'UPDATE ' . USERS_TABLE . "  				SET user_newpasswd = '" . $db->sql_escape(phpbb_hash($user_password)) . "', user_actkey = '" . $db->sql_escape($user_actkey) . "'  | 
