1
0
mirror of https://github.com/phpbb/phpbb.git synced 2025-07-30 21:40:43 +02:00

BBCode parser + decoder, missing some tags and mildly broken at this time

git-svn-id: file:///svn/phpbb/trunk@3812 89ea8834-ac86-4346-8a33-228a782c2dd0
This commit is contained in:
Ludovic Arnaud
2003-04-11 00:19:29 +00:00
parent f17c36cea4
commit 4f55c9fb81
5 changed files with 479 additions and 570 deletions

View File

@@ -26,15 +26,26 @@ class parse_message
var $bbcode_tpl = null;
var $message_mode = 0; // MSG_POST/MSG_PM
//----
var $bbcode_uid = '';
var $bbcode_bitfield = 0;
var $bbcode_array = array();
var $message = '';
//----
function parse_message($message_type)
{
$this->message_mode = $message_type;
$this->bbcode_uid = substr(md5(time()), 0, BBCODE_UID_LEN);
}
function parse(&$message, $html, $bbcode, $uid, $url, $smilies)
{
global $config, $db, $user;
$this->message = $message;
$this->bbcode_uid = $uid;
$warn_msg = '';
// Do some general 'cleanup' first before processing message,
@@ -81,7 +92,10 @@ class parse_message
}
$warn_msg .= (($warn_msg != '') ? '<br />' : '') . $this->html($message, $html);
$warn_msg .= (($warn_msg != '') ? '<br />' : '') . $this->bbcode($message, $bbcode, $uid);
if ($bbcode)
{
$warn_msg .= (($warn_msg != '') ? '<br />' : '') . $this->bbcode($message);
}
$warn_msg .= (($warn_msg != '') ? '<br />' : '') . $this->emoticons($message, $smilies);
$warn_msg .= (($warn_msg != '') ? '<br />' : '') . $this->magic_url($message, $url);
@@ -109,10 +123,209 @@ class parse_message
return;
}
function bbcode(&$message, $bbcode, $uid)
function bbcode(&$message)
{
global $config;
// DEBUG
$this->message = $message;
// Warning, Least-Significant-Bit first
$bbcode_bitfield = str_repeat('0', 32);
if (empty($this->bbcode_array))
{
$this->bbcode_init();
}
$size = strlen($this->message);
foreach ($this->bbcode_array as $offset => $row)
{
$parse = FALSE;
foreach ($row as $regex => $replacement)
{
$this->message = preg_replace($regex, $replacement, $this->message);
// Since we add bbcode_uid to all tags, the message length will increase whenever a tag is found
$new_size = strlen($this->message);
if ($size != $new_size)
{
$parse = TRUE;
}
}
$bbcode_bitfield{$offset} = ($parse) ? '1' : '0';
}
// LSB becomes MSB then we convert it to decimal
$this->bbcode_bitfield = bindec(strrev($bbcode_bitfield));
// DEBUG
$message = $this->message;
}
function bbcode_init()
{
// Always parse [code] first
$this->bbcode_array = array(
8 => array('#\[code\](.+\[/code\])#ise' => '$this->bbcode_code("\1")'),
10 => array('#\[email(=.*?)?\](.*?)\[/email\]#ise' => '$this->validate_email("\1", "\2")'),
9 => array('#\[list(=[a-z|0-1]+)?\].*\[/list\]#ise' => '$this->bbcode_list("\0")'),
7 => array('#\[u\](.*?)\[/u\]#is' => '[u:' . $this->bbcode_uid . ']\1[/u:' . $this->bbcode_uid . ']'),
6 => array('!\[color=(#[0-9A-F]{6}|[a-z\-]+)\](.*?)\[/color\]!is'
=> '[color=\1:' . $this->bbcode_uid . ']\2[/color:' . $this->bbcode_uid . ']'),
5 => array('#\[size=([\-\+]?[1-2]?[0-9])\](.*?)\[/size\]#is'
=> '[size=\1:' . $this->bbcode_uid . ']\2[/size:' . $this->bbcode_uid . ']'),
4 => array('#\[img\](https?://)([a-z0-9\-\.,\?!%\*_:;~\\&$@/=\+]+)\[/img\]#i'
=> '[img:' . $this->bbcode_uid . ']\1\2[/img:' . $this->bbcode_uid . ']'),
3 => array('#\[url=?(.*?)?\](.*?)\[/url\]#ise' => '$this->validate_url("\1", "\2")'),
2 => array('#\[i\](.*?)\[/i\]#is' => '[i:' . $this->bbcode_uid . ']\1[/i:' . $this->bbcode_uid . ']'),
1 => array('#\[b\](.*?)\[/b\]#is' => '[b:' . $this->bbcode_uid . ']\1[/b:' . $this->bbcode_uid . ']'),
0 => array('#\[quote(=".*?")?\](.*?)\[/quote\]#is' => '[quote:' . $this->bbcode_uid . '\1]\2[/quote:' . $this->bbcode_uid . ']')
);
/**************
global $db;
$result = $db->sql_query('SELECT bbcode_id, first_pass_regexp, first_pass_replacement FROM ' . BBCODES_TABLE);
while ($row = $db->sql_fetchrow($result))
{
$this->bbcode_array[$row['bbcode_id']] = array($row['first_pass_regexp'] => $row['first_pass_replacement']);
}
**************/
}
function bbcode_code($in)
{
$str_from = array('<', '>', '"', ':', '[', ']', '(', ')', '{', '}', '.', '@');
$str_to = array('&lt;', '&gt;', '&quot;', '&#58;', '&#91;', '&#93;', '&#40;', '&#41;', '&#123;', '&#125;', '&#46;', '&#64;');
// if I remember correctly, preg_replace() will slash passed vars
$in = stripslashes($in);
$out = '';
do
{
$pos = strpos($in, '[/code]') + 7;
$buffer = substr($in, 0, $pos);
$in = substr($in, $pos);
while ($in)
{
$pos = strpos($in, '[/code]') + 7;
$sub_buffer = substr($in, 0, $pos);
if (preg_match('#\[code\]#i', $sub_buffer))
{
break;
}
else
{
$in = substr($in, $pos);
$buffer .= $sub_buffer;
}
}
$buffer = substr($buffer, 0, -7);
$out .= '[code:' . $this->bbcode_uid . ']' . str_replace($str_from, $str_to, $buffer) . '[/code:' . $this->bbcode_uid . ']';
$pos = strpos($in, '[code]');
if ($pos !== FALSE)
{
$out .= substr($in, 0, $pos);
$in = substr($in, $pos + 6);
}
}
while ($in);
return $out;
}
function bbcode_list($in)
{
$tok = ']';
$out = '[';
// if I remember correctly, preg_replace() will slash passed vars
$in = stripslashes($in);
$in = substr($in, 1);
$close_tags = array();
do
{
$pos = strlen($in);
for ($i = 0; $i < strlen($tok); ++$i)
{
$tmp_pos = strpos($in, $tok{$i});
if ($tmp_pos !== FALSE && $tmp_pos < $pos)
{
$pos = $tmp_pos;
}
}
$buffer = substr($in, 0, $pos);
$tok = $in{$pos};
$in = substr($in, $pos + 1);
if ($tok == ']')
{
if ($buffer == '/list' && count($close_tags))
{
$tag = array_pop($close_tags);
$out .= $tag;
$tok = '[';
}
elseif (preg_match('/list(=?(?:[0-9]|[a-z]|))/i', $buffer, $m))
{
array_push($close_tags, (($m[1]) ? '/list:o:' . $this->bbcode_uid . ']' : '/list:u:' . $this->bbcode_uid . ']'));
$out .= $buffer . ':' . $this->bbcode_uid . ']';
$tok = '[';
}
else
{
if ($buffer == '*' && count($close_tags))
{
$buffer = '*:' . $this->bbcode_uid;
}
$out .= $buffer . $tok;
$tok = '[]';
}
}
else
{
$out .= $buffer . $tok;
$tok = ($tok == '[') ? ']' : '[]';
}
}
while ($in);
// Close tags left = some tags still open
if (count($close_tags))
{
$out .= '[' . implode('[', $close_tags);
}
return $out;
}
function validate_email($var1, $var2)
{
$retval = '[email' . $var1 . ':' . $this->bbcode_uid . ']' . $var2 . '[/email:' . $this->bbcode_uid . ']';
return $retval;
}
function validate_url($var1, $var2)
{
$url = (empty($var1)) ? stripslashes($var2) : stripslashes($var1);
// Put validation regexps here
$valid = FALSE;
if (preg_match('#^http(s?)://#i', $url))
{
$valid = TRUE;
}
if ($valid)
{
return (empty($var1)) ? '[url:' . $this->bbcode_uid . ']' . $url . '[/url:' . $this->bbcode_uid . ']' : "[url=$url:" . $this->bbcode_uid . ']' . $var2 . '[/url:' . $this->bbcode_uid . ']';
}
return '[url' . $var1 . ']' . $var2 . '[/url]';
}
// Replace magic urls of form http://xxx.xxx., www.xxx. and xxx@xxx.xxx.