From 4b876ffee5b714bcd7fbf8eb2df022f32251a9ff Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Sun, 13 May 2007 16:15:20 +0000 Subject: [PATCH] - correctly transfer the search query across search result pages - changed highlighting so foo* will match foo again [Bug #10031] - restructured magic urls (functionality still mostly the same), added a check for entities in urls and punctuation at the end of magic urls [Bugs #10639, #10293] - undid the workaround for urls in quotes, as it's fixed by the new magic url handling - allow magic urls enclosed in BBCode [Bug #10319] - added handling for IPv6 addresses to the IP checking without adding extra options [Bug #9538] - correctly handle search in search results of search queries with brackets [Bug #10581] - added information about requirements for auth_apache [Bug #10107] git-svn-id: file:///svn/phpbb/trunk@7559 89ea8834-ac86-4346-8a33-228a782c2dd0 --- phpBB/includes/constants.php | 6 + phpBB/includes/functions.php | 150 ++++++++++++++++++++-- phpBB/includes/message_parser.php | 15 --- phpBB/includes/search/fulltext_native.php | 1 + phpBB/includes/session.php | 26 +++- phpBB/language/en/acp/board.php | 4 +- phpBB/search.php | 9 +- phpBB/viewtopic.php | 4 +- 8 files changed, 180 insertions(+), 35 deletions(-) diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php index 37b448df9f..3c049a1153 100644 --- a/phpBB/includes/constants.php +++ b/phpBB/includes/constants.php @@ -141,6 +141,12 @@ define('BBCODE_UID_LEN', 5); // Number of core BBCodes define('NUM_CORE_BBCODES', 12); +// Magic url types +define('MAGIC_URL_EMAIL', 1); +define('MAGIC_URL_FULL', 2); +define('MAGIC_URL_LOCAL', 3); +define('MAGIC_URL_WWW', 4); + // Profile Field Types define('FIELD_INT', 1); define('FIELD_STRING', 2); diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index c7d77da408..079d09ac94 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -2599,6 +2599,113 @@ function generate_text_for_edit($text, $uid, $flags) ); } +/** +* A subroutine of make_clickable used with preg_replace +* It places correct HTML around an url, shortens the displayed text +* and makes sure no entities are inside URLs +*/ +function make_clickable_callback($type, $whitespace, $url, $relative_url, $class) +{ + $append = ''; + $url = htmlspecialchars_decode($url); + $relative_url = htmlspecialchars_decode($relative_url); + + // make sure no HTML entities were matched + $chars = array('<', '>', '"'); + $split = false; + foreach ($chars as $char) + { + $next_split = strpos($url, $char); + if ($next_split !== false) + { + $split = ($split !== false) ? min($split, $next_split) : $next_split; + } + } + + if ($split !== false) + { + // an HTML entity was found, so the URL has to end before it + $append = substr($url, $split) . $relative_url; + $url = substr($url, 0, $split); + $relative_url = ''; + } + else if ($relative_url) + { + // same for $relative_url + $split = false; + foreach ($chars as $char) + { + $next_split = strpos($relative_url, $char); + if ($next_split !== false) + { + $split = ($split !== false) ? min($split, $next_split) : $next_split; + } + } + + if ($split !== false) + { + $append = substr($relative_url, $split); + $relative_url = substr($relative_url, 0, $split); + } + } + + // if the last character of the url is a punctuation mark, exclude it from the url + $last_char = ($relative_url) ? $relative_url[strlen($relative_url) - 1] : $url[strlen($url) - 1]; + + switch ($last_char) + { + case '.': + case '?': + case '!': + case ':': + case ',': + $append = $last_char; + if ($relative_url) + { + $relative_url = substr($relative_url, 0, -1); + } + else + { + $url = substr($url, 0, -1); + } + } + + switch ($type) + { + case MAGIC_URL_LOCAL: + $tag = 'l'; + $relative_url = preg_replace('/[&?]sid=[0-9a-f]{32}$/', '', preg_replace('/([&?])sid=[0-9a-f]{32}&/', '$1', $relative_url)); + $url = $url . '/' . $relative_url; + $text = ($relative_url) ? $relative_url : $url . '/'; + break; + + case MAGIC_URL_FULL: + $tag = 'm'; + $text = (strlen($url) > 55) ? substr($url, 0, 39) . ' ... ' . substr($url, -10) : $url; + break; + + case MAGIC_URL_WWW: + $tag = 'w'; + $url = 'http://' . $url; + $text = (strlen($url) > 55) ? substr($url, 0, 39) . ' ... ' . substr($url, -10) : $url; + break; + + case MAGIC_URL_EMAIL: + $tag = 'e'; + $url = 'mailto:' . $url; + $text = (strlen($url) > 55) ? substr($url, 0, 39) . ' ... ' . substr($url, -10) : $url; + break; + } + + $url = htmlspecialchars($url); + $text = htmlspecialchars($text); + $append = htmlspecialchars($append); + + $html = "$whitespace$text$append"; + + return $html; +} + /** * make_clickable function * @@ -2627,20 +2734,20 @@ function make_clickable($text, $server_url = false, $class = 'postlink') // 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_inline') . ')#ie'; - $magic_url_replace[] = "'\$1' . ((strlen('\$3')) ? preg_replace('/(&|\?)sid=[0-9a-f]{32}$/', '', preg_replace('/(&|\?)sid=[0-9a-f]{32}&/', '\\\\1', '\$3')) : '\$2/') . ''"; + $magic_url_match[] = '#(^|[\n\t (>\]])(' . preg_quote($server_url, '#') . ')/(' . get_preg_expression('relative_url_inline') . ')#ie'; + $magic_url_replace[] = "make_clickable_callback(MAGIC_URL_LOCAL, '\$1', '\$2', '\$3', '$local_class')"; // matches a xxxx://aaaaa.bbb.cccc. ... - $magic_url_match[] = '#(^|[\n\t (>])(' . get_preg_expression('url_inline') . ')#ie'; - $magic_url_replace[] = "'\$1' . ((strlen('\$2') > 55) ? str_replace('&', '&', substr(str_replace('&', '&', '\$2'), 0, 39)) . ' ... ' . str_replace('&', '&', substr(str_replace('&', '&', '\$2'), -10)) : '\$2') . ''"; + $magic_url_match[] = '#(^|[\n\t (>\]])(' . get_preg_expression('url_inline') . ')#ie'; + $magic_url_replace[] = "make_clickable_callback(MAGIC_URL_FULL, '\$1', '\$2', '', '$class')"; // matches a "www.xxxx.yyyy[/zzzz]" kinda lazy URL thing - $magic_url_match[] = '#(^|[\n\t (>])(' . get_preg_expression('www_url_inline') . ')#ie'; - $magic_url_replace[] = "'\$1' . ((strlen('\$2') > 55) ? str_replace('&', '&', substr(str_replace('&', '&', '\$2'), 0, 39)) . ' ... ' . str_replace('&', '&', substr(str_replace('&', '&', '\$2'), -10)) : '\$2') . ''"; + $magic_url_match[] = '#(^|[\n\t (>\]])(' . get_preg_expression('www_url_inline') . ')#ie'; + $magic_url_replace[] = "make_clickable_callback(MAGIC_URL_WWW, '\$1', '\$2', '', '$class')"; // matches an email@domain type address at the start of a line, or after a space or after what might be a BBCode. - $magic_url_match[] = '/(^|[\n\t (>])(' . get_preg_expression('email') . ')/ie'; - $magic_url_replace[] = "'\$1' . ((strlen('\$2') > 55) ? substr('\$2', 0, 39) . ' ... ' . substr('\$2', -10) : '\$2') . ''"; + $magic_url_match[] = '/(^|[\n\t (>\]])(' . get_preg_expression('email') . ')/ie'; + $magic_url_replace[] = "make_clickable_callback(MAGIC_URL_EMAIL, array('\$1', '\$2'), '')"; } return preg_replace($magic_url_match, $magic_url_replace, $text); @@ -3303,6 +3410,33 @@ function get_preg_expression($mode) return ''; } +/** +* Returns the first 4 blocks of the specified IPv6 address and as many +* as specified in the length paramater additional ones. +* If length is zero, then an empty string is returned. +*/ +function short_ipv6($ip, $length) +{ + if ($length < 1) + { + return ''; + } + + // extend IPv6 addresses + $blocks = substr_count($ip, ':') + 1; + if ($blocks < 9) + { + $ip = str_replace('::', ':' . str_repeat('0000:', 9 - $blocks), $ip); + } + if ($ip[0] == ':') + { + $ip = '0000' . $ip; + } + $ip = implode(':', array_slice(explode(':', $ip), 0, 4 + $length)); + + return $ip; +} + /** * Truncates string while retaining special characters if going over the max length * The default max length is 60 at the moment diff --git a/phpBB/includes/message_parser.php b/phpBB/includes/message_parser.php index 52bba31da3..9b3dcad871 100644 --- a/phpBB/includes/message_parser.php +++ b/phpBB/includes/message_parser.php @@ -1066,23 +1066,8 @@ class parse_message extends bbcode_firstpass // Parse URL's if ($allow_magic_url) { - $replaced = false; - - // We have the bbcode uid here, let's at least try to circumvent a specific bug... - if ($allow_bbcode && strpos($this->message, '[/quote:' . $this->bbcode_uid . ']') !== false && strpos($this->message, '":' . $this->bbcode_uid . ']') !== false) - { - $this->message = str_replace('":' . $this->bbcode_uid . ']', '"&quot;:' . $this->bbcode_uid . ']', $this->message); - $replaced = true; - } - $this->magic_url(generate_board_url()); - // Revert our change above - if ($replaced) - { - $this->message = str_replace('"&quot;:' . $this->bbcode_uid . ']', '":' . $this->bbcode_uid . ']', $this->message); - } - if ($config['max_' . $mode . '_urls']) { $num_urls += preg_match_all('#\