From e6421f9274d3932539974790db1fcf81027a4db5 Mon Sep 17 00:00:00 2001
From: Nils Adermann <naderman@naderman.de>
Date: Sat, 13 Jan 2007 22:32:03 +0000
Subject: [PATCH] - solved a problem with magic urls inside brackets, and with
 bbcodes being treated as IPv6 addresses - turn NOT IN () and IN () into 1=1
 and 1=0 so the database will understand it, instead of throwing an error in
 sql_in_set [Bug #7118] - some tiny fixes to fulltext_native

git-svn-id: file:///svn/phpbb/trunk@6886 89ea8834-ac86-4346-8a33-228a782c2dd0
---
 phpBB/develop/regex.php                   |  2 +-
 phpBB/includes/db/dbal.php                | 12 ++++++++++--
 phpBB/includes/functions.php              | 20 +++++++++++++-------
 phpBB/includes/search/fulltext_native.php | 19 +++++++++++--------
 4 files changed, 35 insertions(+), 18 deletions(-)

diff --git a/phpBB/develop/regex.php b/phpBB/develop/regex.php
index 1719fe03e9..7abecc9650 100644
--- a/phpBB/develop/regex.php
+++ b/phpBB/develop/regex.php
@@ -49,7 +49,7 @@ $scheme = '[a-z][a-z\d+\-.]*';
 $reg_name = "(?:[$unreserved$sub_delims|@]+|$pct_encoded)+"; // rfc: * instead of + and no "|" and no "@" (included instead of userinfo
 //$userinfo = "(?:(?:[$unreserved$sub_delims:]+|$pct_encoded))*";
 $ipv4_simple = '[0-9.]+';
-$ipv6_simple = '\[[a-z0-9.:]+\]';
+$ipv6_simple = '\[[a-z0-9.]+:[a-z0-9.]+:[a-z0-9.:]+\]';
 $host = "(?:$reg_name|$ipv4_simple|$ipv6_simple)";
 $port = '\d*';
 //$authority = "(?:$userinfo@)?$host(?::$port)?";
diff --git a/phpBB/includes/db/dbal.php b/phpBB/includes/db/dbal.php
index f4cbe0e2d4..1f48909d43 100644
--- a/phpBB/includes/db/dbal.php
+++ b/phpBB/includes/db/dbal.php
@@ -289,8 +289,16 @@ class dbal
 	{
 		if (!sizeof($array))
 		{
-			// Not optimal, but at least the backtrace should help in identifying where the problem lies.
-			$this->sql_error('No values specified for SQL IN comparison');
+			// NOT IN () actually means everything so use a tautology
+			if ($negate)
+			{
+				return '1=1';
+			}
+			// IN () actually means nothing so use a contradiction
+			else
+			{
+				return '1=0';
+			}
 		}
 
 		if (!is_array($array))
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index 8054870554..c9d820ae03 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -2385,15 +2385,15 @@ function make_clickable($text, $server_url = false)
 		// Be sure to not let the matches cross over. ;)
 
 		// relative urls for this board
-		$magic_url_match[] = '#(^|[\n\t (])(' . preg_quote($server_url, '#') . ')/(' . get_preg_expression('relative_url') . ')#ie';
+		$magic_url_match[] = '#(^|[\n\t (])(' . preg_quote($server_url, '#') . ')/(' . get_preg_expression('relative_url_inline') . ')#ie';
 		$magic_url_replace[] = "'\$1<!-- l --><a href=\"\$2/' . preg_replace('/(&amp;|\?)sid=[0-9a-f]{32}/', '\\\\1', '\$3') . '\">' . preg_replace('/(&amp;|\?)sid=[0-9a-f]{32}/', '\\\\1', '\$3') . '</a><!-- l -->'";
 
 		// matches a xxxx://aaaaa.bbb.cccc. ...
-		$magic_url_match[] = '#(^|[\n\t (])(' . get_preg_expression('url') . ')#ie';
+		$magic_url_match[] = '#(^|[\n\t (])(' . get_preg_expression('url_inline') . ')#ie';
 		$magic_url_replace[] = "'\$1<!-- m --><a href=\"\$2\">' . ((strlen('\$2') > 55) ? substr(str_replace('&amp;', '&', '\$2'), 0, 39) . ' ... ' . substr(str_replace('&amp;', '&', '\$2'), -10) : '\$2') . '</a><!-- m -->'";
 
 		// matches a "www.xxxx.yyyy[/zzzz]" kinda lazy URL thing
-		$magic_url_match[] = '#(^|[\n\t (])(' . get_preg_expression('www_url') . ')#ie';
+		$magic_url_match[] = '#(^|[\n\t (])(' . get_preg_expression('www_url_inline') . ')#ie';
 		$magic_url_replace[] = "'\$1<!-- w --><a href=\"http://\$2\">' . ((strlen('\$2') > 55) ? substr(str_replace('&amp;', '&', '\$2'), 0, 39) . ' ... ' . substr(str_replace('&amp;', '&', '\$2'), -10) : '\$2') . '</a><!-- w -->'";
 
 		// matches an email@domain type address at the start of a line, or after a space or after what might be a BBCode.
@@ -3001,7 +3001,7 @@ function get_backtrace()
 /**
 * This function returns a regular expression pattern for commonly used expressions
 * Use with / as delimiter for email mode and # for url modes
-* mode can be: email|bbcode_htm|url|www_url|relative_url
+* mode can be: email|bbcode_htm|url|url_inline|www_url|www_url_inline|relative_url|relative_url_inline
 */
 function get_preg_expression($mode)
 {
@@ -3022,16 +3022,22 @@ function get_preg_expression($mode)
 		break;
 
 		case 'url':
+		case 'url_inline':
+			$inline = ($mode == 'url') ? ')' : '';
 			// generated with regex generation file in the develop folder
-			return "[a-z][a-z\d+\-.]*:/{2}(?:(?:[a-z0-9\-._~!$&'()*+,;=|@]+|%[\dA-F]{2})+|[0-9.]+|\[[a-z0-9.:]+\])(?::\d*)?(?:/(?:[a-z0-9\-._~!$&'()*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[a-z0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[a-z0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?";
+			return "[a-z][a-z\d+\-.]*:/{2}(?:(?:[a-z0-9\-._~!$&'($inline*+,;=|@]+|%[\dA-F]{2})+|[0-9.]+|\[[a-z0-9.]+:[a-z0-9.]+:[a-z0-9.:]+\])(?::\d*)?(?:/(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?";
 		break;
 
 		case 'www_url':
-			return "www\.(?:[a-z0-9\-._~!$&'()*+,;=|@]+|%[\dA-F]{2})+(?::\d*)?(?:/(?:[a-z0-9\-._~!$&'()*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[a-z0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[a-z0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?";
+		case 'www_url_inline':
+			$inline = ($mode == 'www_url') ? ')' : '';
+			return "www\.(?:[a-z0-9\-._~!$&'($inline*+,;=|@]+|%[\dA-F]{2})+(?::\d*)?(?:/(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?";
 		break;
 
 		case 'relative_url':
-			return "(?:[a-z0-9\-._~!$&'()*+,;=:@|]+|%[\dA-F]{2})*(?:/(?:[a-z0-9\-._~!$&'()*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[a-z0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[a-z0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?";
+		case 'relative_url_inline':
+			$inline = ($mode == 'relative_url') ? ')' : '';
+			return "(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})*(?:/(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?";
 		break;
 	}
 
diff --git a/phpBB/includes/search/fulltext_native.php b/phpBB/includes/search/fulltext_native.php
index cbdef03b88..652495e734 100755
--- a/phpBB/includes/search/fulltext_native.php
+++ b/phpBB/includes/search/fulltext_native.php
@@ -80,7 +80,7 @@ class fulltext_native extends search_backend
 	*/
 	function split_keywords($keywords, $terms)
 	{
-		global $db, $config, $user;
+		global $db, $user;
 
 		$keywords = trim($this->cleanup($keywords, '+-|()*'));
 
@@ -273,16 +273,19 @@ class fulltext_native extends search_backend
 			// if this is an array of words then retrieve an id for each
 			if (is_array($word))
 			{
+				$non_common_words = array();
 				$id_words = array();
 				foreach ($word as $i => $word_part)
 				{
 					if (strpos($word_part, '*') !== false)
 					{
 						$id_words[] = '\'' . $db->sql_escape(str_replace('*', '%', $word_part)) . '\'';
+						$non_common_words[] = $word_part;
 					}
-					if (isset($words[$word_part]))
+					else if (isset($words[$word_part]))
 					{
 						$id_words[] = $words[$word_part];
+						$non_common_words[] = $word_part;
 					}
 				}
 				if (sizeof($id_words))
@@ -299,10 +302,11 @@ class fulltext_native extends search_backend
 					}
 				}
 				// throw an error if we shall not ignore unexistant words
-				else if (!$ignore_no_id)
+				else if (!$ignore_no_id && sizeof($non_common_words))
 				{
-					trigger_error(sprintf($user->lang['WORDS_IN_NO_POST'], implode(', ', $word)));
+					trigger_error(sprintf($user->lang['WORDS_IN_NO_POST'], implode(', ', $non_common_words)));
 				}
+				unset($non_common_words);
 			}
 			// else we only need one id
 			else if (($wildcard = strpos($word, '*') !== false) || isset($words[$word]))
@@ -930,8 +934,7 @@ class fulltext_native extends search_backend
 	*/
 	function split_message($text)
 	{
-		global $phpbb_root_path, $phpEx;
-		global $config, $user;
+		global $phpbb_root_path, $phpEx, $user;
 
 		$match = $words = array();
 
@@ -943,8 +946,8 @@ class fulltext_native extends search_backend
 		// BBcode
 		$match[] = '#\[\/?[a-z0-9\*\+\-]+(?:=.*?)?(?::[a-z])?(\:?[0-9a-z]{5,})\]#';
 
-		$min = $config['fulltext_native_min_chars'];
-		$max = $config['fulltext_native_max_chars'];
+		$min = $this->word_length['min'];
+		$max = $this->word_length['max'];
 
 		$isset_min = $min - 1;