- 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
This commit is contained in:
Nils Adermann 2007-05-13 16:15:20 +00:00
parent b8daa78709
commit 4b876ffee5
8 changed files with 180 additions and 35 deletions

View file

@ -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);

View file

@ -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<!-- $tag --><a$class href=\"$url\">$text</a><!-- $tag -->$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<!-- l --><a$local_class href=\"' . append_sid('\$2/' . preg_replace('/(&amp;|\?)sid=[0-9a-f]{32}$/', '', preg_replace('/(&amp;|\?)sid=[0-9a-f]{32}&amp;/', '\\\\1', '\$3'))) . '\">' . ((strlen('\$3')) ? preg_replace('/(&amp;|\?)sid=[0-9a-f]{32}$/', '', preg_replace('/(&amp;|\?)sid=[0-9a-f]{32}&amp;/', '\\\\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('&', '&amp;', substr(str_replace('&amp;', '&', '\$2'), 0, 39)) . ' ... ' . str_replace('&', '&amp;', substr(str_replace('&amp;', '&', '\$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('&', '&amp;', substr(str_replace('&amp;', '&', '\$2'), 0, 39)) . ' ... ' . str_replace('&', '&amp;', substr(str_replace('&amp;', '&', '\$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);
@ -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

View file

@ -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, '&quot;:' . $this->bbcode_uid . ']') !== false)
{
$this->message = str_replace('&quot;:' . $this->bbcode_uid . ']', '"&amp;quot;:' . $this->bbcode_uid . ']', $this->message);
$replaced = true;
}
$this->magic_url(generate_board_url());
// Revert our change above
if ($replaced)
{
$this->message = str_replace('"&amp;quot;:' . $this->bbcode_uid . ']', '&quot;:' . $this->bbcode_uid . ']', $this->message);
}
if ($config['max_' . $mode . '_urls'])
{
$num_urls += preg_match_all('#\<!-- ([lmwe]) --\>.*?\<!-- \1 --\>#', $this->message, $matches);

View file

@ -124,6 +124,7 @@ class fulltext_native extends search_backend
break;
case '(':
$open_bracket = $i;
$space = false;
break;
case '|':
$keywords[$i] = ' ';

View file

@ -230,8 +230,16 @@ class session
// check on bots if admin requires this
// $quadcheck = ($config['ip_check_bot'] && $this->data['user_type'] & USER_BOT) ? 4 : $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...
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)) : '';

View file

@ -288,7 +288,7 @@ $lang = array_merge($lang, array(
'AUTH_METHOD' => 'Select an authentication method',
'APACHE_SETUP_BEFORE_USE' => 'You have to setup apache authentication before you switch phpBB to this authentication method. Keep in mind that the username you use for apache authentication has to be the same as your phpBB username.',
'APACHE_SETUP_BEFORE_USE' => 'You have to setup apache authentication before you switch phpBB to this authentication method. Keep in mind that the username you use for apache authentication has to be the same as your phpBB username. Apache authentication can only be used with mod_php (not with a CGI version) and safe_mode disabled.',
'LDAP_DN' => 'LDAP base <var>dn</var>',
'LDAP_DN_EXPLAIN' => 'This is the Distinguished Name, locating the user information, e.g. <samp>o=My Company,c=US</samp>.',
@ -357,7 +357,7 @@ $lang = array_merge($lang, array(
'FORWARDED_FOR_VALID' => 'Validated <var>X_FORWARDED_FOR</var> header',
'FORWARDED_FOR_VALID_EXPLAIN' => 'Sessions will only be continued if the sent <var>X_FORWARDED_FOR</var> header equals the one sent with the previous request. Bans will be checked against IPs in <var>X_FORWARDED_FOR</var> too.',
'IP_VALID' => 'Session IP validation',
'IP_VALID_EXPLAIN' => 'Determines how much of the users IP is used to validate a session; <samp>All</samp> compares the complete address, <samp>A.B.C</samp> the first x.x.x, <samp>A.B</samp> the first x.x, <samp>None</samp> disables checking.',
'IP_VALID_EXPLAIN' => 'Determines how much of the users IP is used to validate a session; <samp>All</samp> compares the complete address, <samp>A.B.C</samp> the first x.x.x, <samp>A.B</samp> the first x.x, <samp>None</samp> disables checking. On IPv6 addresses <samp>A.B.C</samp> compares the first 7 blocks and <samp>A.B</samp> the first 6 blocks.',
'MAX_LOGIN_ATTEMPTS' => 'Maximum number of login attempts',
'MAX_LOGIN_ATTEMPTS_EXPLAIN' => 'After this number of failed logins the user needs to additionally confirm his login visually (visual confirmation).',
'NO_IP_VALIDATION' => 'None',

View file

@ -135,7 +135,7 @@ if ($keywords || $author || $author_id || $search_id || $submit)
}
// Which forums should not be searched? Author searches are also carried out in unindexed forums
if (empty($search->search_query) && sizeof($author_id_ary))
if (empty($keywords) && sizeof($author_id_ary))
{
$ex_fid_ary = array_keys($auth->acl_getf('!f_read', true));
}
@ -460,7 +460,7 @@ if ($keywords || $author || $author_id || $search_id || $submit)
$u_search = append_sid("{$phpbb_root_path}search.$phpEx", $u_sort_param . $u_show_results);
$u_search .= ($search_id) ? '&amp;search_id=' . $search_id : '';
$u_search .= ($u_hilit) ? '&amp;keywords=' . $u_hilit : '';
$u_search .= ($u_hilit) ? '&amp;keywords=' . urlencode(htmlspecialchars_decode($search->search_query)) : '';
$u_search .= ($topic_id) ? '&amp;t=' . $topic_id : '';
$u_search .= ($author) ? '&amp;author=' . urlencode(htmlspecialchars_decode($author)) : '';
$u_search .= ($author_id) ? '&amp;author_id=' . $author_id : '';
@ -711,7 +711,8 @@ if ($keywords || $author || $author_id || $search_id || $submit)
$hilit_array = array_filter(explode('|', $hilit), 'strlen');
foreach ($hilit_array as $key => $value)
{
$hilit_array[$key] = str_replace('\*', '\w+?', preg_quote($value, '#'));
$hilit_array[$key] = str_replace('\*', '\w*?', preg_quote($value, '#'));
$hilit_array[$key] = preg_replace('#(^|\s)\\\\w\*\?(\s|$)#', '$1\w+?$2', $hilit_array[$key]);
}
$hilit = implode('|', $hilit_array);
}
@ -812,7 +813,7 @@ if ($keywords || $author || $author_id || $search_id || $submit)
$template->assign_block_vars('searchresults', array(
'S_IGNORE_POST' => true,
'L_IGNORE_POST' => sprintf($user->lang['POST_BY_FOE'], $row['username'], "<a href=\"$u_search&amp;p=" . $row['post_id'] . '&amp;view=show#p' . $row['post_id'] . '">', '</a>'))
'L_IGNORE_POST' => sprintf($user->lang['POST_BY_FOE'], $row['username'], "<a href=\"$u_search&amp;start=$start&amp;p=" . $row['post_id'] . '&amp;view=show#p' . $row['post_id'] . '">', '</a>'))
);
continue;

View file

@ -407,7 +407,9 @@ if ($hilit_words)
{
if (trim($word))
{
$highlight_match .= (($highlight_match != '') ? '|' : '') . str_replace('\*', '\w+?', preg_quote($word, '#'));
$word = str_replace('\*', '\w+?', preg_quote($word, '#'));
$word = preg_replace('#(^|\s)\\\\w\*\?(\s|$)#', '$1\w+?$2', $word);
$highlight_match .= (($highlight_match != '') ? '|' : '') . $word;
}
}