diff options
Diffstat (limited to 'phpBB/includes')
-rw-r--r-- | phpBB/includes/constants.php | 6 | ||||
-rw-r--r-- | phpBB/includes/functions.php | 150 | ||||
-rw-r--r-- | phpBB/includes/message_parser.php | 15 | ||||
-rwxr-xr-x | phpBB/includes/search/fulltext_native.php | 1 | ||||
-rw-r--r-- | phpBB/includes/session.php | 26 |
5 files changed, 170 insertions, 28 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 @@ -2600,6 +2600,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<!-- $tag --><a$class href=\"$url\">$text</a><!-- $tag -->$append"; + + return $html; +} + +/** * make_clickable function * * Replace magic urls of form http://xxx.xxx., www.xxx. and xxx@xxx.xxx. @@ -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<!-- l --><a$local_class href=\"' . append_sid('\$2/' . preg_replace('/(&|\?)sid=[0-9a-f]{32}$/', '', preg_replace('/(&|\?)sid=[0-9a-f]{32}&/', '\\\\1', '\$3'))) . '\">' . ((strlen('\$3')) ? preg_replace('/(&|\?)sid=[0-9a-f]{32}$/', '', preg_replace('/(&|\?)sid=[0-9a-f]{32}&/', '\\\\1', '\$3')) : '\$2/') . '</a><!-- l -->'"; + $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<!-- m --><a$class href=\"\$2\">' . ((strlen('\$2') > 55) ? str_replace('&', '&', substr(str_replace('&', '&', '\$2'), 0, 39)) . ' ... ' . str_replace('&', '&', substr(str_replace('&', '&', '\$2'), -10)) : '\$2') . '</a><!-- m -->'"; + $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<!-- w --><a$class href=\"http://\$2\">' . ((strlen('\$2') > 55) ? str_replace('&', '&', substr(str_replace('&', '&', '\$2'), 0, 39)) . ' ... ' . str_replace('&', '&', substr(str_replace('&', '&', '\$2'), -10)) : '\$2') . '</a><!-- w -->'"; + $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<!-- e --><a href=\"mailto:\$2\">' . ((strlen('\$2') > 55) ? substr('\$2', 0, 39) . ' ... ' . substr('\$2', -10) : '\$2') . '</a><!-- e -->'"; + $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); @@ -3304,6 +3411,33 @@ function get_preg_expression($mode) } /** +* 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('#\<!-- ([lmwe]) --\>.*?\<!-- \1 --\>#', $this->message, $matches); diff --git a/phpBB/includes/search/fulltext_native.php b/phpBB/includes/search/fulltext_native.php index 50bf7bcb2a..200d8d8f59 100755 --- a/phpBB/includes/search/fulltext_native.php +++ b/phpBB/includes/search/fulltext_native.php @@ -124,6 +124,7 @@ class fulltext_native extends search_backend break; case '(': $open_bracket = $i; + $space = false; break; case '|': $keywords[$i] = ' '; diff --git a/phpBB/includes/session.php b/phpBB/includes/session.php index 85ad21cabc..31ad37bc8d 100644 --- a/phpBB/includes/session.php +++ b/phpBB/includes/session.php @@ -229,9 +229,17 @@ class session // Validate IP length according to admin ... enforces an IP // check on bots if admin requires this // $quadcheck = ($config['ip_check_bot'] && $this->data['user_type'] & USER_BOT) ? 4 : $config['ip_check']; - - $s_ip = implode('.', array_slice(explode('.', $this->data['session_ip']), 0, $config['ip_check'])); - $u_ip = implode('.', array_slice(explode('.', $this->ip), 0, $config['ip_check'])); + + if (strpos($this->ip, ':') !== false && strpos($this->data['session_ip'], ':') !== false) + { + $s_ip = short_ipv6($this->data['session_ip'], $config['ip_check']); + $u_ip = short_ipv6($this->ip, $config['ip_check']); + } + else + { + $s_ip = implode('.', array_slice(explode('.', $this->data['session_ip']), 0, $config['ip_check'])); + $u_ip = implode('.', array_slice(explode('.', $this->ip), 0, $config['ip_check'])); + } $s_browser = ($config['browser_check']) ? strtolower(substr($this->data['session_browser'], 0, 149)) : ''; $u_browser = ($config['browser_check']) ? strtolower(substr($this->browser, 0, 149)) : ''; @@ -489,8 +497,16 @@ class session if ($this->data['is_bot'] && $bot == $this->data['user_id'] && $this->data['session_id']) { // Only assign the current session if the ip, browser and forwarded_for match... - $s_ip = implode('.', array_slice(explode('.', $this->data['session_ip']), 0, $config['ip_check'])); - $u_ip = implode('.', array_slice(explode('.', $this->ip), 0, $config['ip_check'])); + if (strpos($this->ip, ':') !== false && strpos($this->data['session_ip'], ':') !== false) + { + $s_ip = short_ipv6($this->data['session_ip'], $config['ip_check']); + $u_ip = short_ipv6($this->ip, $config['ip_check']); + } + else + { + $s_ip = implode('.', array_slice(explode('.', $this->data['session_ip']), 0, $config['ip_check'])); + $u_ip = implode('.', array_slice(explode('.', $this->ip), 0, $config['ip_check'])); + } $s_browser = ($config['browser_check']) ? strtolower(substr($this->data['session_browser'], 0, 149)) : ''; $u_browser = ($config['browser_check']) ? strtolower(substr($this->browser, 0, 149)) : ''; |