|
@@ -826,7 +826,6 @@ function permute($array)
|
|
|
* - caches the from/to replace regular expressions so as not to reload them every time a string is parsed.
|
|
|
* - only parses smileys if smileys is true.
|
|
|
* - does nothing if the enableBBC setting is off.
|
|
|
- * - applies the fixLongWords magic if the setting is set to on.
|
|
|
* - uses the cache_id as a unique identifier to facilitate any caching it may do.
|
|
|
* -returns the modified message.
|
|
|
*
|
|
@@ -1607,7 +1606,7 @@ function parse_bbc($message, $smileys = true, $cache_id = '', $parse_tags = arra
|
|
|
}
|
|
|
|
|
|
// Shall we take the time to cache this?
|
|
|
- if ($cache_id != '' && !empty($modSettings['cache_enable']) && (($modSettings['cache_enable'] >= 2 && strlen($message) > 1000) || strlen($message) > 2400) && empty($parse_tags))
|
|
|
+ if ($cache_id != '' && !empty($modSettings['cache_enable']) && (($modSettings['cache_enable'] >= 2 && isset($message[1000])) || isset($message[2400])) && empty($parse_tags))
|
|
|
{
|
|
|
// It's likely this will change if the message is modified.
|
|
|
$cache_key = 'parse:' . $cache_id . '-' . md5(md5($message) . '-' . $smileys . (empty($disabled) ? '' : implode(',', array_keys($disabled))) . serialize($context['browser']) . $txt['lang_locale'] . $user_info['time_offset'] . $user_info['time_format']);
|
|
@@ -1657,22 +1656,6 @@ function parse_bbc($message, $smileys = true, $cache_id = '', $parse_tags = arra
|
|
|
// The non-breaking-space looks a bit different each time.
|
|
|
$non_breaking_space = $context['utf8'] ? '\x{A0}' : '\xA0';
|
|
|
|
|
|
- // This saves time by doing our break long words checks here.
|
|
|
- if (!empty($modSettings['fixLongWords']) && $modSettings['fixLongWords'] > 5)
|
|
|
- {
|
|
|
- if (isBrowser('gecko') || isBrowser('konqueror'))
|
|
|
- $breaker = '<span style="margin: 0 -0.5ex 0 0;"> </span>';
|
|
|
- // Opera...
|
|
|
- elseif (isBrowser('opera'))
|
|
|
- $breaker = '<span style="margin: 0 -0.65ex 0 -1px;"> </span>';
|
|
|
- // Internet Explorer...
|
|
|
- else
|
|
|
- $breaker = '<span style="width: 0; margin: 0 -0.6ex 0 -1px;"> </span>';
|
|
|
-
|
|
|
- // PCRE will not be happy if we don't give it a short.
|
|
|
- $modSettings['fixLongWords'] = (int) min(65535, $modSettings['fixLongWords']);
|
|
|
- }
|
|
|
-
|
|
|
$pos = -1;
|
|
|
while ($pos !== false)
|
|
|
{
|
|
@@ -1807,21 +1790,6 @@ function parse_bbc($message, $smileys = true, $cache_id = '', $parse_tags = arra
|
|
|
|
|
|
$data = strtr($data, array("\t" => ' '));
|
|
|
|
|
|
- if (!empty($modSettings['fixLongWords']) && $modSettings['fixLongWords'] > 5)
|
|
|
- {
|
|
|
- // The idea is, find words xx long, and then replace them with xx + space + more.
|
|
|
- if ($smcFunc['strlen']($data) > $modSettings['fixLongWords'])
|
|
|
- {
|
|
|
- // This is done in a roundabout way because $breaker has "long words" :P.
|
|
|
- $data = strtr($data, array($breaker => '< >', ' ' => $context['utf8'] ? "\xC2\xA0" : "\xA0"));
|
|
|
- $data = preg_replace(
|
|
|
- '~(?<=[>;:!? ' . $non_breaking_space . '\]()\n]|^)([\w' . ($context['utf8'] ? '\pL' : '') . '\.]{' . $modSettings['fixLongWords'] . ',})~e' . ($context['utf8'] ? 'u' : ''),
|
|
|
- 'preg_replace(\'/(.{' . ($modSettings['fixLongWords'] - 1) . '})/' . ($context['utf8'] ? 'u' : '') . '\', \'\\$1< >\', \'$1\')',
|
|
|
- $data);
|
|
|
- $data = strtr($data, array('< >' => $breaker, $context['utf8'] ? "\xC2\xA0" : "\xA0" => ' '));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
// If it wasn't changed, no copying or other boring stuff has to happen!
|
|
|
if ($data != substr($message, $last_pos, $pos - $last_pos))
|
|
|
{
|
|
@@ -1845,10 +1813,12 @@ function parse_bbc($message, $smileys = true, $cache_id = '', $parse_tags = arra
|
|
|
$pos2 = strpos($message, ']', $pos + 1);
|
|
|
if ($pos2 == $pos + 2)
|
|
|
continue;
|
|
|
+
|
|
|
$look_for = strtolower(substr($message, $pos + 2, $pos2 - $pos - 2));
|
|
|
|
|
|
$to_close = array();
|
|
|
$block_level = null;
|
|
|
+
|
|
|
do
|
|
|
{
|
|
|
$tag = array_pop($open_tags);
|
|
@@ -1944,14 +1914,16 @@ function parse_bbc($message, $smileys = true, $cache_id = '', $parse_tags = arra
|
|
|
$tag = null;
|
|
|
foreach ($bbc_codes[$tags] as $possible)
|
|
|
{
|
|
|
+ $pt_strlen = strlen($possible['tag']);
|
|
|
+
|
|
|
// Not a match?
|
|
|
- if (stripos($message, $possible['tag'], $pos + 1) !== $pos + 1)
|
|
|
+ if (strtolower(substr($message, $pos + 1, $pt_strlen)) != $possible['tag'])
|
|
|
continue;
|
|
|
|
|
|
- $next_c = substr($message, $pos + 1 + strlen($possible['tag']), 1);
|
|
|
+ $next_c = $message[$pos + 1 + $pt_strlen];
|
|
|
|
|
|
// A test validation?
|
|
|
- if (isset($possible['test']) && preg_match('~^' . $possible['test'] . '~', substr($message, $pos + 1 + strlen($possible['tag']) + 1)) == 0)
|
|
|
+ if (isset($possible['test']) && preg_match('~^' . $possible['test'] . '~', substr($message, $pos + 1 + $pt_strlen + 1)) === 0)
|
|
|
continue;
|
|
|
// Do we want parameters?
|
|
|
elseif (!empty($possible['parameters']))
|
|
@@ -1965,7 +1937,7 @@ function parse_bbc($message, $smileys = true, $cache_id = '', $parse_tags = arra
|
|
|
if (in_array($possible['type'], array('unparsed_equals', 'unparsed_commas', 'unparsed_commas_content', 'unparsed_equals_content', 'parsed_equals')) && $next_c != '=')
|
|
|
continue;
|
|
|
// Maybe we just want a /...
|
|
|
- if ($possible['type'] == 'closed' && $next_c != ']' && substr($message, $pos + 1 + strlen($possible['tag']), 2) != '/]' && substr($message, $pos + 1 + strlen($possible['tag']), 3) != ' /]')
|
|
|
+ if ($possible['type'] == 'closed' && $next_c != ']' && substr($message, $pos + 1 + $pt_strlen, 2) != '/]' && substr($message, $pos + 1 + $pt_strlen, 3) != ' /]')
|
|
|
continue;
|
|
|
// An immediate ]?
|
|
|
if ($possible['type'] == 'unparsed_content' && $next_c != ']')
|
|
@@ -1984,7 +1956,7 @@ function parse_bbc($message, $smileys = true, $cache_id = '', $parse_tags = arra
|
|
|
elseif (isset($inside['disallow_children']) && in_array($possible['tag'], $inside['disallow_children']))
|
|
|
continue;
|
|
|
|
|
|
- $pos1 = $pos + 1 + strlen($possible['tag']) + 1;
|
|
|
+ $pos1 = $pos + 1 + $pt_strlen + 1;
|
|
|
|
|
|
// Quotes can have alternate styling, we do this php-side due to all the permutations of quotes.
|
|
|
if ($possible['tag'] == 'quote')
|
|
@@ -2065,6 +2037,7 @@ function parse_bbc($message, $smileys = true, $cache_id = '', $parse_tags = arra
|
|
|
{
|
|
|
if ($message[$pos + 1] == '0' && !in_array($message[$pos - 1], array(';', ' ', "\t", '>')))
|
|
|
continue;
|
|
|
+
|
|
|
$tag = $itemcodes[$message[$pos + 1]];
|
|
|
|
|
|
// First let's set up the tree: it needs to be in a list, or after an li.
|
|
@@ -2157,6 +2130,9 @@ function parse_bbc($message, $smileys = true, $cache_id = '', $parse_tags = arra
|
|
|
else
|
|
|
$tag['content'] = $tag['disabled_content'];
|
|
|
}
|
|
|
+
|
|
|
+ // we use this alot
|
|
|
+ $tag_strlen = strlen($tag['tag']);
|
|
|
|
|
|
// The only special case is 'html', which doesn't need to close things.
|
|
|
if (!empty($tag['block_level']) && $tag['tag'] != 'html' && empty($inside['block_level']))
|
|
@@ -2169,8 +2145,9 @@ function parse_bbc($message, $smileys = true, $cache_id = '', $parse_tags = arra
|
|
|
for ($i = count($open_tags) - 1; $i > $n; $i--)
|
|
|
{
|
|
|
$message = substr($message, 0, $pos) . "\n" . $open_tags[$i]['after'] . "\n" . substr($message, $pos);
|
|
|
- $pos += strlen($open_tags[$i]['after']) + 2;
|
|
|
- $pos1 += strlen($open_tags[$i]['after']) + 2;
|
|
|
+ $ot_strlen = strlen($open_tags[$i]['after']);
|
|
|
+ $pos += $ot_strlen + 2;
|
|
|
+ $pos1 += $ot_strlen + 2;
|
|
|
|
|
|
// Trim or eat trailing stuff... see comment at the end of the big loop.
|
|
|
if (!empty($open_tags[$i]['block_level']) && substr($message, $pos, 6) == '<br />')
|
|
@@ -2193,7 +2170,7 @@ function parse_bbc($message, $smileys = true, $cache_id = '', $parse_tags = arra
|
|
|
// Don't parse the content, just skip it.
|
|
|
elseif ($tag['type'] == 'unparsed_content')
|
|
|
{
|
|
|
- $pos2 = stripos($message, '[/' . substr($message, $pos + 1, strlen($tag['tag'])) . ']', $pos1);
|
|
|
+ $pos2 = stripos($message, '[/' . substr($message, $pos + 1, $tag_strlen) . ']', $pos1);
|
|
|
if ($pos2 === false)
|
|
|
continue;
|
|
|
|
|
@@ -2206,7 +2183,7 @@ function parse_bbc($message, $smileys = true, $cache_id = '', $parse_tags = arra
|
|
|
$tag['validate']($tag, $data, $disabled);
|
|
|
|
|
|
$code = strtr($tag['content'], array('$1' => $data));
|
|
|
- $message = substr($message, 0, $pos) . "\n" . $code . "\n" . substr($message, $pos2 + 3 + strlen($tag['tag']));
|
|
|
+ $message = substr($message, 0, $pos) . "\n" . $code . "\n" . substr($message, $pos2 + 3 + $tag_strlen);
|
|
|
|
|
|
$pos += strlen($code) - 1 + 2;
|
|
|
$last_pos = $pos + 1;
|
|
@@ -2231,7 +2208,8 @@ function parse_bbc($message, $smileys = true, $cache_id = '', $parse_tags = arra
|
|
|
$pos2 = strpos($message, $quoted == false ? ']' : '"]', $pos1);
|
|
|
if ($pos2 === false)
|
|
|
continue;
|
|
|
- $pos3 = stripos($message, '[/' . substr($message, $pos + 1, strlen($tag['tag'])) . ']', $pos2);
|
|
|
+
|
|
|
+ $pos3 = stripos($message, '[/' . substr($message, $pos + 1, $tag_strlen) . ']', $pos2);
|
|
|
if ($pos3 === false)
|
|
|
continue;
|
|
|
|
|
@@ -2248,7 +2226,7 @@ function parse_bbc($message, $smileys = true, $cache_id = '', $parse_tags = arra
|
|
|
$tag['validate']($tag, $data, $disabled);
|
|
|
|
|
|
$code = strtr($tag['content'], array('$1' => $data[0], '$2' => $data[1]));
|
|
|
- $message = substr($message, 0, $pos) . "\n" . $code . "\n" . substr($message, $pos3 + 3 + strlen($tag['tag']));
|
|
|
+ $message = substr($message, 0, $pos) . "\n" . $code . "\n" . substr($message, $pos3 + 3 + $tag_strlen);
|
|
|
$pos += strlen($code) - 1 + 2;
|
|
|
}
|
|
|
// A closed tag, with no content or value.
|
|
@@ -2264,7 +2242,8 @@ function parse_bbc($message, $smileys = true, $cache_id = '', $parse_tags = arra
|
|
|
$pos2 = strpos($message, ']', $pos1);
|
|
|
if ($pos2 === false)
|
|
|
continue;
|
|
|
- $pos3 = stripos($message, '[/' . substr($message, $pos + 1, strlen($tag['tag'])) . ']', $pos2);
|
|
|
+
|
|
|
+ $pos3 = stripos($message, '[/' . substr($message, $pos + 1, $tag_strlen) . ']', $pos2);
|
|
|
if ($pos3 === false)
|
|
|
continue;
|
|
|
|
|
@@ -2278,7 +2257,7 @@ function parse_bbc($message, $smileys = true, $cache_id = '', $parse_tags = arra
|
|
|
$code = $tag['content'];
|
|
|
foreach ($data as $k => $d)
|
|
|
$code = strtr($code, array('$' . ($k + 1) => trim($d)));
|
|
|
- $message = substr($message, 0, $pos) . "\n" . $code . "\n" . substr($message, $pos3 + 3 + strlen($tag['tag']));
|
|
|
+ $message = substr($message, 0, $pos) . "\n" . $code . "\n" . substr($message, $pos3 + 3 + $tag_strlen);
|
|
|
$pos += strlen($code) - 1 + 2;
|
|
|
}
|
|
|
// This has parsed content, and a csv value which is unparsed.
|
|
@@ -2372,7 +2351,7 @@ function parse_bbc($message, $smileys = true, $cache_id = '', $parse_tags = arra
|
|
|
else
|
|
|
$message = strtr($message, array("\n" => ''));
|
|
|
|
|
|
- if (substr($message, 0, 1) == ' ')
|
|
|
+ if ($message[0] === ' ')
|
|
|
$message = ' ' . substr($message, 1);
|
|
|
|
|
|
// Cleanup whitespace.
|
|
@@ -2447,7 +2426,7 @@ function parsesmileys(&$message)
|
|
|
while ($row = $smcFunc['db_fetch_assoc']($result))
|
|
|
{
|
|
|
$smileysfrom[] = $row['code'];
|
|
|
- $smileysto[] = $row['filename'];
|
|
|
+ $smileysto[] = htmlspecialchars($row['filename']);
|
|
|
$smileysdescs[] = $row['description'];
|
|
|
}
|
|
|
$smcFunc['db_free_result']($result);
|
|
@@ -2464,14 +2443,17 @@ function parsesmileys(&$message)
|
|
|
// This smiley regex makes sure it doesn't parse smileys within code tags (so [url=mailto:[email protected]] doesn't parse the :D smiley)
|
|
|
$smileyPregReplacements = array();
|
|
|
$searchParts = array();
|
|
|
+ $smileys_path = htmlspecialchars($modSettings['smileys_url'] . '/' . $user_info['smiley_set'] . '/');
|
|
|
+
|
|
|
for ($i = 0, $n = count($smileysfrom); $i < $n; $i++)
|
|
|
{
|
|
|
- $smileyCode = '<img src="' . htmlspecialchars($modSettings['smileys_url'] . '/' . $user_info['smiley_set'] . '/' . $smileysto[$i]) . '" alt="' . strtr(htmlspecialchars($smileysfrom[$i], ENT_QUOTES), array(':' => ':', '(' => '(', ')' => ')', '$' => '$', '[' => '[')). '" title="' . strtr(htmlspecialchars($smileysdescs[$i]), array(':' => ':', '(' => '(', ')' => ')', '$' => '$', '[' => '[')) . '" class="smiley" />';
|
|
|
+ $specialChars = htmlspecialchars($smileysfrom[$i], ENT_QUOTES);
|
|
|
+ $smileyCode = '<img src="' . $smileys_path . $smileysto[$i] . '" alt="' . strtr($specialChars, array(':' => ':', '(' => '(', ')' => ')', '$' => '$', '[' => '[')). '" title="' . strtr(htmlspecialchars($smileysdescs[$i]), array(':' => ':', '(' => '(', ')' => ')', '$' => '$', '[' => '[')) . '" class="smiley" />';
|
|
|
|
|
|
$smileyPregReplacements[$smileysfrom[$i]] = $smileyCode;
|
|
|
|
|
|
$searchParts[] = preg_quote($smileysfrom[$i], '~');
|
|
|
- if ($smileysfrom[$i] != ($specialChars = htmlspecialchars($smileysfrom[$i], ENT_QUOTES)))
|
|
|
+ if ($smileysfrom[$i] != $specialChars)
|
|
|
{
|
|
|
$smileyPregReplacements[$specialChars] = $smileyCode;
|
|
|
$searchParts[] = preg_quote($specialChars, '~');
|
|
@@ -4288,11 +4270,11 @@ function replaceEntities__callback($matches)
|
|
|
$num = $matches[2][0] === 'x' ? hexdec(substr($matches[2], 1)) : (int) $matches[2];
|
|
|
|
|
|
// remove left to right / right to left overrides
|
|
|
- if ($num === 0x202D || $num === 0x202E)
|
|
|
+ if ($num === 0x202D || $num === 0x202E)
|
|
|
return '';
|
|
|
|
|
|
// Quote, Ampersand, Apostrophe, Less/Greater Than get html replaced
|
|
|
- if (in_array($num, array(0x22, 0x26, 0x27, 0x3C, 0x3E)))
|
|
|
+ if (in_array($num, array(0x22, 0x26, 0x27, 0x3C, 0x3E)))
|
|
|
return '&#' . $num . ';';
|
|
|
|
|
|
if (empty($context['utf8']))
|