phpBB

Code Changes

File: includes/message_parser.php

  Unmodified   Added   Modified   Removed
Line 102Line 102
	/**
* Init bbcode data for later parsing
*/

	/**
* Init bbcode data for later parsing
*/

	function bbcode_init()

	function bbcode_init($allow_custom_bbcode = true)

	{
static $rowset;

// This array holds all bbcode data. BBCodes will be processed in this
// order, so it is important to keep [code] in first position and
// [quote] in second position.

	{
static $rowset;

// This array holds all bbcode data. BBCodes will be processed in this
// order, so it is important to keep [code] in first position and
// [quote] in second position.

 
		// To parse multiline URL we enable dotall option setting only for URL text
// but not for link itself, thus [url][/url] is not affected.

		$this->bbcodes = array(

		$this->bbcodes = array(

			'code'			=> array('bbcode_id' => 8,	'regexp' => array('#\[code(?:=([a-z]+))?\](.+\[/code\])#ise' => "\$this->bbcode_code('\$1', '\$2')")),
'quote' => array('bbcode_id' => 0, 'regexp' => array('#\[quote(?:="(.*?)")?\](.+)\[/quote\]#ise' => "\$this->bbcode_quote('\$0')")),
'attachment' => array('bbcode_id' => 12, 'regexp' => array('#\[attachment=([0-9]+)\](.*?)\[/attachment\]#ise' => "\$this->bbcode_attachment('\$1', '\$2')")),
'b' => array('bbcode_id' => 1, 'regexp' => array('#\[b\](.*?)\[/b\]#ise' => "\$this->bbcode_strong('\$1')")),
'i' => array('bbcode_id' => 2, 'regexp' => array('#\[i\](.*?)\[/i\]#ise' => "\$this->bbcode_italic('\$1')")),
'url' => array('bbcode_id' => 3, 'regexp' => array('#\[url(=(.*))?\](.*)\[/url\]#iUe' => "\$this->validate_url('\$2', '\$3')")),
'img' => array('bbcode_id' => 4, 'regexp' => array('#\[img\](.*)\[/img\]#iUe' => "\$this->bbcode_img('\$1')")),
'size' => array('bbcode_id' => 5, 'regexp' => array('#\[size=([\-\+]?\d+)\](.*?)\[/size\]#ise' => "\$this->bbcode_size('\$1', '\$2')")),
'color' => array('bbcode_id' => 6, 'regexp' => array('!\[color=(#[0-9a-f]{6}|[a-z\-]+)\](.*?)\[/color\]!ise' => "\$this->bbcode_color('\$1', '\$2')")),
'u' => array('bbcode_id' => 7, 'regexp' => array('#\[u\](.*?)\[/u\]#ise' => "\$this->bbcode_underline('\$1')")),
'list' => array('bbcode_id' => 9, 'regexp' => array('#\[list(?:=(?:[a-z0-9]|disc|circle|square))?].*\[/list]#ise' => "\$this->bbcode_parse_list('\$0')")),
'email' => array('bbcode_id' => 10, 'regexp' => array('#\[email=?(.*?)?\](.*?)\[/email\]#ise' => "\$this->validate_email('\$1', '\$2')")),
'flash' => array('bbcode_id' => 11, 'regexp' => array('#\[flash=([0-9]+),([0-9]+)\](.*?)\[/flash\]#ie' => "\$this->bbcode_flash('\$1', '\$2', '\$3')"))

			'code'			=> array('bbcode_id' => 8,	'regexp' => array('#\[code(?:=([a-z]+))?\](.+\[/code\])#uise' => "\$this->bbcode_code('\$1', '\$2')")),
'quote' => array('bbcode_id' => 0, 'regexp' => array('#\[quote(?:="(.*?)")?\](.+)\[/quote\]#uise' => "\$this->bbcode_quote('\$0')")),
'attachment' => array('bbcode_id' => 12, 'regexp' => array('#\[attachment=([0-9]+)\](.*?)\[/attachment\]#uise' => "\$this->bbcode_attachment('\$1', '\$2')")),
'b' => array('bbcode_id' => 1, 'regexp' => array('#\[b\](.*?)\[/b\]#uise' => "\$this->bbcode_strong('\$1')")),
'i' => array('bbcode_id' => 2, 'regexp' => array('#\[i\](.*?)\[/i\]#uise' => "\$this->bbcode_italic('\$1')")),
'url' => array('bbcode_id' => 3, 'regexp' => array('#\[url(=(.*))?\](?(1)((?s).*(?-s))|(.*))\[/url\]#uiUe' => "\$this->validate_url('\$2', ('\$3') ? '\$3' : '\$4')")),
'img' => array('bbcode_id' => 4, 'regexp' => array('#\[img\](.*)\[/img\]#uiUe' => "\$this->bbcode_img('\$1')")),
'size' => array('bbcode_id' => 5, 'regexp' => array('#\[size=([\-\+]?\d+)\](.*?)\[/size\]#uise' => "\$this->bbcode_size('\$1', '\$2')")),
'color' => array('bbcode_id' => 6, 'regexp' => array('!\[color=(#[0-9a-f]{3}|#[0-9a-f]{6}|[a-z\-]+)\](.*?)\[/color\]!uise' => "\$this->bbcode_color('\$1', '\$2')")),
'u' => array('bbcode_id' => 7, 'regexp' => array('#\[u\](.*?)\[/u\]#uise' => "\$this->bbcode_underline('\$1')")),
'list' => array('bbcode_id' => 9, 'regexp' => array('#\[list(?:=(?:[a-z0-9]|disc|circle|square))?].*\[/list]#uise' => "\$this->bbcode_parse_list('\$0')")),
'email' => array('bbcode_id' => 10, 'regexp' => array('#\[email=?(.*?)?\](.*?)\[/email\]#uise' => "\$this->validate_email('\$1', '\$2')")),
'flash' => array('bbcode_id' => 11, 'regexp' => array('#\[flash=([0-9]+),([0-9]+)\](.*?)\[/flash\]#uie' => "\$this->bbcode_flash('\$1', '\$2', '\$3')"))

		);

// Zero the parsed items array

		);

// Zero the parsed items array

Line 131Line 133
		foreach ($this->bbcodes as $tag => $bbcode_data)
{
$this->parsed_items[$tag] = 0;

		foreach ($this->bbcodes as $tag => $bbcode_data)
{
$this->parsed_items[$tag] = 0;

 
		}

if (!$allow_custom_bbcode)
{
return;

		}

if (!is_array($rowset))

		}

if (!is_array($rowset))

Line 300Line 307

if ($config['max_' . $this->mode . '_img_height'] || $config['max_' . $this->mode . '_img_width'])
{


if ($config['max_' . $this->mode . '_img_height'] || $config['max_' . $this->mode . '_img_width'])
{

			$stats = @getimagesize($in);

			$stats = @getimagesize(htmlspecialchars_decode($in));


if ($stats === false)
{


if ($stats === false)
{

Line 348Line 355

// Do not allow 0-sizes generally being entered
if ($width <= 0 || $height <= 0)


// Do not allow 0-sizes generally being entered
if ($width <= 0 || $height <= 0)

 
		{
return '[flash=' . $width . ',' . $height . ']' . $in . '[/flash]';
}

$in = str_replace(' ', '%20', $in);

// Make sure $in is a URL.
if (!preg_match('#^' . get_preg_expression('url') . '$#i', $in) &&
!preg_match('#^' . get_preg_expression('www_url') . '$#i', $in))

		{
return '[flash=' . $width . ',' . $height . ']' . $in . '[/flash]';
}

		{
return '[flash=' . $width . ',' . $height . ']' . $in . '[/flash]';
}

Line 391Line 407

/**
* Parse code text from code tag


/**
* Parse code text from code tag

	* @private

	* @access private

	*/
function bbcode_parse_code($stx, &$code)
{

	*/
function bbcode_parse_code($stx, &$code)
{

Line 604Line 620
					$out .= array_pop($list_end_tags) . ']';
$tok = '[';
}

					$out .= array_pop($list_end_tags) . ']';
$tok = '[';
}

				else if (preg_match('#^list(=[0-9a-z])?$#i', $buffer, $m))

				else if (preg_match('#^list(=[0-9a-z]+)?$#i', $buffer, $m))

				{
// sub-list, add a closing tag

				{
// sub-list, add a closing tag

					if (empty($m[1]) || preg_match('/^(?:disc|square|circle)$/i', $m[1]))

					if (empty($m[1]) || preg_match('/^=(?:disc|square|circle)$/i', $m[1]))

					{
array_push($list_end_tags, '/list:u:' . $this->bbcode_uid);
}

					{
array_push($list_end_tags, '/list:u:' . $this->bbcode_uid);
}

Line 695Line 711
		* [quote="[i]test[/i]"]test[/quote] (correct: parsed)
* [quote="[quote]test[/quote]"]test[/quote] (correct: parsed - Username displayed as [quote]test[/quote])
* #20735 - [quote]test[/[/b]quote] test [/quote][/quote] test - (correct: quoted: "test[/[/b]quote] test" / non-quoted: "[/quote] test" - also failed if layout distorted)

		* [quote="[i]test[/i]"]test[/quote] (correct: parsed)
* [quote="[quote]test[/quote]"]test[/quote] (correct: parsed - Username displayed as [quote]test[/quote])
* #20735 - [quote]test[/[/b]quote] test [/quote][/quote] test - (correct: quoted: "test[/[/b]quote] test" / non-quoted: "[/quote] test" - also failed if layout distorted)

 
		* #40565 - [quote="a"]a[/quote][quote="a]a[/quote] (correct: first quote tag parsed, second quote tag unparsed)

		*/

$in = str_replace("\r\n", "\n", str_replace('\"', '"', trim($in)));

		*/

$in = str_replace("\r\n", "\n", str_replace('\"', '"', trim($in)));

Line 705Line 722
		}

// To let the parser not catch tokens within quote_username quotes we encode them before we start this...

		}

// To let the parser not catch tokens within quote_username quotes we encode them before we start this...

		$in = preg_replace('#quote=&quot;(.*?)&quot;\]#ie', "'quote=&quot;' . str_replace(array('[', ']'), array('&#91;', '&#93;'), '\$1') . '&quot;]'", $in);

		$in = preg_replace('#quote=&quot;(.*?)&quot;\]#ie', "'quote=&quot;' . str_replace(array('[', ']', '\\\"'), array('&#91;', '&#93;', '\"'), '\$1') . '&quot;]'", $in);


$tok = ']';
$out = '[';


$tok = ']';
$out = '[';

Line 857Line 874
			}
}
while ($in);

			}
}
while ($in);

 

$out .= $buffer;


if (sizeof($close_tags))
{


if (sizeof($close_tags))
{

Line 1049Line 1068
	{
// Init BBCode UID
$this->bbcode_uid = substr(base_convert(unique_id(), 16, 36), 0, BBCODE_UID_LEN);

	{
// Init BBCode UID
$this->bbcode_uid = substr(base_convert(unique_id(), 16, 36), 0, BBCODE_UID_LEN);


if ($message)
{

 
			$this->message = $message;

			$this->message = $message;

		}

 
	}

/**

	}

/**

Line 1062Line 1077
	function parse($allow_bbcode, $allow_magic_url, $allow_smilies, $allow_img_bbcode = true, $allow_flash_bbcode = true, $allow_quote_bbcode = true, $allow_url_bbcode = true, $update_this_message = true, $mode = 'post')
{
global $config, $db, $user;

	function parse($allow_bbcode, $allow_magic_url, $allow_smilies, $allow_img_bbcode = true, $allow_flash_bbcode = true, $allow_quote_bbcode = true, $allow_url_bbcode = true, $update_this_message = true, $mode = 'post')
{
global $config, $db, $user;


$mode = ($mode != 'post') ? 'sig' : 'post';

 

$this->mode = $mode;


$this->mode = $mode;

 

foreach (array('chars', 'smilies', 'urls', 'font_size', 'img_height', 'img_width') as $key)
{
if (!isset($config['max_' . $mode . '_' . $key]))
{
$config['max_' . $mode . '_' . $key] = 0;
}
}


$this->allow_img_bbcode = $allow_img_bbcode;
$this->allow_flash_bbcode = $allow_flash_bbcode;


$this->allow_img_bbcode = $allow_img_bbcode;
$this->allow_flash_bbcode = $allow_flash_bbcode;

Line 1090Line 1111
		$replace = array("\\1&#058;");
$this->message = preg_replace($match, $replace, trim($this->message));


		$replace = array("\\1&#058;");
$this->message = preg_replace($match, $replace, trim($this->message));


		// Message length check. 0 disables this check completely.
if ($config['max_' . $mode . '_chars'] > 0)
{
$msg_len = ($mode == 'post') ? utf8_strlen($this->message) : utf8_strlen(preg_replace('#\[\/?[a-z\*\+\-]+(=[\S]+)?\]#ius', ' ', $this->message));

		// Store message length...
$message_length = ($mode == 'post') ? utf8_strlen($this->message) : utf8_strlen(preg_replace('#\[\/?[a-z\*\+\-]+(=[\S]+)?\]#ius', ' ', $this->message));







			if ((!$msg_len && $mode !== 'sig') || $config['max_' . $mode . '_chars'] && $msg_len > $config['max_' . $mode . '_chars'])


		// Maximum message length check. 0 disables this check completely.
if ((int) $config['max_' . $mode . '_chars'] > 0 && $message_length > (int) $config['max_' . $mode . '_chars'])

			{

			{

				$this->warn_msg[] = (!$msg_len) ? $user->lang['TOO_FEW_CHARS'] : sprintf($user->lang['TOO_MANY_CHARS_' . strtoupper($mode)], $msg_len, $config['max_' . $mode . '_chars']);

			$this->warn_msg[] = sprintf($user->lang['TOO_MANY_CHARS_' . strtoupper($mode)], $message_length, (int) $config['max_' . $mode . '_chars']);

				return (!$update_this_message) ? $return_message : $this->warn_msg;

				return (!$update_this_message) ? $return_message : $this->warn_msg;

			}

 
		}


		}


		// Check for "empty" message
if ($mode !== 'sig' && utf8_clean_string($this->message) === '')

		// Minimum message length check for post only
if ($mode === 'post')

		{

		{

			$this->warn_msg[] = $user->lang['TOO_FEW_CHARS'];



			if (!$message_length || $message_length < (int) $config['min_post_chars'])
{
$this->warn_msg[] = (!$message_length) ? $user->lang['TOO_FEW_CHARS'] : sprintf($user->lang['TOO_FEW_CHARS_LIMIT'], $message_length, (int) $config['min_post_chars']);

			return (!$update_this_message) ? $return_message : $this->warn_msg;

			return (!$update_this_message) ? $return_message : $this->warn_msg;

 
			}

		}

// Prepare BBcode (just prepares some tags for better parsing)

		}

// Prepare BBcode (just prepares some tags for better parsing)

Line 1149Line 1171
			{
$num_urls += preg_match_all('#\<!-- ([lmwe]) --\>.*?\<!-- \1 --\>#', $this->message, $matches);
}

			{
$num_urls += preg_match_all('#\<!-- ([lmwe]) --\>.*?\<!-- \1 --\>#', $this->message, $matches);
}

 
		}

// Check for "empty" message. We do not check here for maximum length, because bbcode, smilies, etc. can add to the length.
// The maximum length check happened before any parsings.
if ($mode === 'post' && utf8_clean_string($this->message) === '')
{
$this->warn_msg[] = $user->lang['TOO_FEW_CHARS'];
return (!$update_this_message) ? $return_message : $this->warn_msg;

		}

// Check number of links

		}

// Check number of links

Line 1270Line 1300
			{
case 'mssql':
case 'mssql_odbc':

			{
case 'mssql':
case 'mssql_odbc':

 
				case 'mssqlnative':

					$sql = 'SELECT *
FROM ' . SMILIES_TABLE . '
ORDER BY LEN(code) DESC';

					$sql = 'SELECT *
FROM ' . SMILIES_TABLE . '
ORDER BY LEN(code) DESC';

Line 1298Line 1329
				}

// (assertion)

				}

// (assertion)

				$match[] = '(?<=^|[\n .])' . preg_quote($row['code'], '#') . '(?![^<>]*>)';

				$match[] = preg_quote($row['code'], '#');

				$replace[] = '<!-- s' . $row['code'] . ' --><img src="{SMILIES_PATH}/' . $row['smiley_url'] . '" alt="' . $row['code'] . '" title="' . $row['emotion'] . '" /><!-- s' . $row['code'] . ' -->';
}
$db->sql_freeresult($result);

				$replace[] = '<!-- s' . $row['code'] . ' --><img src="{SMILIES_PATH}/' . $row['smiley_url'] . '" alt="' . $row['code'] . '" title="' . $row['emotion'] . '" /><!-- s' . $row['code'] . ' -->';
}
$db->sql_freeresult($result);

Line 1308Line 1339
		{
if ($max_smilies)
{

		{
if ($max_smilies)
{

				$num_matches = preg_match_all('#' . implode('|', $match) . '#', $this->message, $matches);



				// 'u' modifier has been added to correctly parse smilies within unicode strings
// For details: http://tracker.phpbb.com/browse/PHPBB3-10117
$num_matches = preg_match_all('#(?<=^|[\n .])(?:' . implode('|', $match) . ')(?![^<>]*>)#u', $this->message, $matches);

				unset($matches);

if ($num_matches !== false && $num_matches > $max_smilies)

				unset($matches);

if ($num_matches !== false && $num_matches > $max_smilies)

Line 1319Line 1352
			}

// Make sure the delimiter # is added in front and at the end of every element within $match

			}

// Make sure the delimiter # is added in front and at the end of every element within $match

			$this->message = trim(preg_replace(explode(chr(0), '#' . implode('#' . chr(0) . '#', $match) . '#'), $replace, $this->message));




			// 'u' modifier has been added to correctly parse smilies within unicode strings
// For details: http://tracker.phpbb.com/browse/PHPBB3-10117

$this->message = trim(preg_replace(explode(chr(0), '#(?<=^|[\n .])' . implode('(?![^<>]*>)#u' . chr(0) . '#(?<=^|[\n .])', $match) . '(?![^<>]*>)#u'), $replace, $this->message));

		}
}


		}
}


Line 1612Line 1648
		$this->message = $poll['poll_option_text'];
$bbcode_bitfield = $this->bbcode_bitfield;


		$this->message = $poll['poll_option_text'];
$bbcode_bitfield = $this->bbcode_bitfield;


		$poll['poll_option_text'] = $this->parse($poll['enable_bbcode'], ($config['allow_post_links']) ? $poll['enable_urls'] : false, $poll['enable_smilies'], $poll['img_status'], false, false, $config['allow_post_links'], false);

		$poll['poll_option_text'] = $this->parse($poll['enable_bbcode'], ($config['allow_post_links']) ? $poll['enable_urls'] : false, $poll['enable_smilies'], $poll['img_status'], false, false, $config['allow_post_links'], false, 'poll');


$bbcode_bitfield = base64_encode(base64_decode($bbcode_bitfield) | base64_decode($this->bbcode_bitfield));
$this->message = $tmp_message;


$bbcode_bitfield = base64_encode(base64_decode($bbcode_bitfield) | base64_decode($this->bbcode_bitfield));
$this->message = $tmp_message;

Line 1635Line 1671
			{
$this->warn_msg[] = $user->lang['POLL_TITLE_TOO_LONG'];
}

			{
$this->warn_msg[] = $user->lang['POLL_TITLE_TOO_LONG'];
}

			$poll['poll_title'] = $this->parse($poll['enable_bbcode'], ($config['allow_post_links']) ? $poll['enable_urls'] : false, $poll['enable_smilies'], $poll['img_status'], false, false, $config['allow_post_links'], false);

			$poll['poll_title'] = $this->parse($poll['enable_bbcode'], ($config['allow_post_links']) ? $poll['enable_urls'] : false, $poll['enable_smilies'], $poll['img_status'], false, false, $config['allow_post_links'], false, 'poll');

			if (strlen($poll['poll_title']) > 255)
{
$this->warn_msg[] = $user->lang['POLL_TITLE_COMP_TOO_LONG'];

			if (strlen($poll['poll_title']) > 255)
{
$this->warn_msg[] = $user->lang['POLL_TITLE_COMP_TOO_LONG'];