diff options
Diffstat (limited to 'phpBB/includes/message_parser.php')
-rw-r--r-- | phpBB/includes/message_parser.php | 219 |
1 files changed, 216 insertions, 3 deletions
diff --git a/phpBB/includes/message_parser.php b/phpBB/includes/message_parser.php index fcbc470b93..e9f77cc3b4 100644 --- a/phpBB/includes/message_parser.php +++ b/phpBB/includes/message_parser.php @@ -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('<', '>', '"', ':', '[', ']', '(', ')', '{', '}', '.', '@'); + + // 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. |