diff --git a/phpBB/adm/admin_bbcodes.php b/phpBB/adm/admin_bbcodes.php
new file mode 100644
index 0000000000..b123d4862c
--- /dev/null
+++ b/phpBB/adm/admin_bbcodes.php
@@ -0,0 +1,416 @@
+acl_get('a_bbcode'))
+ {
+ return;
+ }
+
+ $filename = basename(__FILE__);
+ $module['POST']['BBCODES'] = $filename . $SID;
+
+ return;
+}
+
+define('IN_PHPBB', 1);
+
+// Include files
+$phpbb_root_path = '../';
+$phpEx = substr(strrchr(__FILE__, '.'), 1);
+require('pagestart.' . $phpEx);
+
+// Do we have general permissions?
+if (!$auth->acl_get('a_bbcode'))
+{
+ trigger_error($user->lang['NO_ADMIN']);
+}
+
+// Set up general vars
+$mode = (!empty($_REQUEST['mode'])) ? $_REQUEST['mode'] : '';
+$bbcode_id = (!empty($_REQUEST['bbcode'])) ? intval($_REQUEST['bbcode']) : 0;
+
+// Set up mode-specific vars
+switch ($mode)
+{
+ case 'add':
+ $bbcode_match = $bbcode_tpl = '';
+ break;
+
+ case 'edit':
+ $sql = 'SELECT bbcode_match, bbcode_tpl
+ FROM ' . BBCODES_TABLE . '
+ WHERE bbcode_id = ' . $bbcode_id;
+ $result = $db->sql_query($sql);
+ if (!$row = $db->sql_fetchrow($result))
+ {
+ trigger_error('BBCODE_NOT_EXIST');
+ }
+
+ $bbcode_match = $row['bbcode_match'];
+ $bbcode_tpl = htmlspecialchars($row['bbcode_tpl']);
+ break;
+
+ case 'modify':
+ $sql = 'SELECT bbcode_id
+ FROM ' . BBCODES_TABLE . '
+ WHERE bbcode_id = ' . $bbcode_id;
+ $result = $db->sql_query($sql);
+ if (!$row = $db->sql_fetchrow($result))
+ {
+ trigger_error('BBCODE_NOT_EXIST');
+ }
+
+ // No break here
+
+ case 'create':
+ $bbcode_match = htmlspecialchars(stripslashes($_POST['bbcode_match']));
+ $bbcode_tpl = stripslashes($_POST['bbcode_tpl']);
+ break;
+}
+
+// Do major work
+switch ($mode)
+{
+ case 'edit':
+ case 'add':
+ adm_page_header($user->lang['BBCODES']);
+
+?>
+
+
lang['BBCODES'] ?>
+
+lang['BBCODES_EXPLAIN'] ?>
+
+
+
+lang['BBCODES']);
+
+ $data = build_regexp($bbcode_match, $bbcode_tpl);
+
+ $sql_ary = array(
+ 'bbcode_tag' => $data['bbcode_tag'],
+ 'bbcode_match' => $bbcode_match,
+ 'bbcode_tpl' => $bbcode_tpl,
+ 'first_pass_match' => $data['first_pass_match'],
+ 'first_pass_replace' => $data['first_pass_replace'],
+ 'second_pass_match' => $data['second_pass_match'],
+ 'second_pass_replace' => $data['second_pass_replace']
+ );
+
+ if ($mode == 'create')
+ {
+ // TODO: look for SQL incompatibilities
+ // NOTE: I'm sure there was another simpler (and obvious) way of finding a suitable bbcode_id
+ $sql = 'SELECT b1.bbcode_id
+ FROM ' . BBCODES_TABLE . ' b1, ' . BBCODES_TABLE . ' b2
+ WHERE b2.bbcode_id > b1.bbcode_id
+ GROUP BY b1.bbcode_id
+ HAVING MIN(b2.bbcode_id) > b1.bbcode_id + 1
+ ORDER BY b1.bbcode_id ASC';
+ $result = $db->sql_query_limit($sql, 1);
+
+ if ($row = $db->sql_fetchrow($result))
+ {
+ $bbcode_id = $row['bbcode_id'] + 1;
+ }
+ else
+ {
+ $sql = 'SELECT MIN(bbcode_id) AS min_id, MAX(bbcode_id) AS max_id
+ FROM ' . BBCODES_TABLE;
+ $result = $db->sql_query($sql);
+ $row = $db->sql_fetchrow($result);
+
+ if (empty($row['min_id']) || $row['min_id'] > 12)
+ {
+ $bbcode_id = 12;
+ }
+ else
+ {
+ $bbcode_id = $row['max_id'] + 1;
+ }
+ }
+
+ if ($bbcode_id > 31)
+ {
+ trigger_error('TOO_MANY_BBCODES');
+ }
+
+ $sql_ary['bbcode_id'] = (int) $bbcode_id;
+
+ $db->sql_query('INSERT INTO ' . BBCODES_TABLE . $db->sql_build_array('INSERT', $sql_ary));
+ $lang = 'BBCODE_ADDED';
+ }
+ else
+ {
+ $db->sql_query('UPDATE ' . BBCODES_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE bbcode_id = ' . $bbcode_id);
+ $lang = 'BBCODE_EDITED';
+ }
+
+ trigger_error($lang);
+ break;
+
+ case 'delete':
+ $db->sql_query('DELETE FROM ' . BBCODES_TABLE . " WHERE bbcode_id = $bbcode_id");
+
+ // No break here
+
+ default:
+
+ adm_page_header($user->lang['BBCODES']);
+
+?>
+
+lang['BBCODES'] ?>
+
+lang['BBCODES_EXPLAIN'] ?>
+
+
+
+
+ array(
+ '!([a-z0-9]+://)?(.*?[^ \t\n\r<"]*)!ise' => "(('\$1') ? '\$1\$2' : 'http://\$2')"
+ ),
+ 'LOCAL_URL' => array(
+ '!([^:]+/[^ \t\n\r<"]*)!' => '$1'
+ ),
+ 'EMAIL' => array(
+ '!([a-z0-9]+[a-z0-9\-\._]*@(?:(?:[0-9]{1,3}\.){3,5}[0-9]{1,3}|[a-z0-9]+[a-z0-9\-\._]*\.[a-z]+))!i' => '$1'
+ ),
+ 'TEXT' => array(
+ '!(.*?)!es' => "str_replace('\\\"', '"', str_replace('\\'', ''', '\$1'))"
+ ),
+ 'COLOR' => array(
+ '!([a-z]+|#[0-9abcdef]+!i' => '$1'
+ ),
+ 'NUMBER' => array(
+ '!([0-9]+)!' => '$1'
+ )
+ );
+
+ if (preg_match_all('/\{(' . implode('|', array_keys($tokens)) . ')[0-9]*\}/i', $msg_bbcode, $m))
+ {
+ $pad = 0;
+ $modifiers = 'i';
+
+ foreach ($m[0] as $n => $token)
+ {
+ $token_type = $m[1][$n];
+
+ reset($tokens[$token_type]);
+ list($match, $replace) = each($tokens[$token_type]);
+
+ // Pad backreference numbers from tokens
+ if (preg_match_all('/(? $bbcode_tag,
+ 'first_pass_match' => $fp_match,
+ 'first_pass_replace' => $fp_replace,
+ 'second_pass_match' => $sp_match,
+ 'second_pass_replace' => $sp_replace
+ );
+}
+// End Functions
+// -----------------------------
+?>
\ No newline at end of file
diff --git a/phpBB/includes/bbcode.php b/phpBB/includes/bbcode.php
index 673513fd41..7ce2f59ec5 100644
--- a/phpBB/includes/bbcode.php
+++ b/phpBB/includes/bbcode.php
@@ -1,23 +1,15 @@
bbcode_bitfield & (1 << $bbcode_id))
{
- foreach ($this->bbcode_cache[$bbcode_id] as $type => $array)
+ if (!empty($this->bbcode_cache[$bbcode_id]))
{
- foreach ($array as $search => $replace)
+ foreach ($this->bbcode_cache[$bbcode_id] as $type => $array)
{
- ${$type}['search'][] = str_replace('$uid', $this->bbcode_uid, $search);
- ${$type}['replace'][] = $replace;
-
+ foreach ($array as $search => $replace)
+ {
+ ${$type}['search'][] = str_replace('$uid', $this->bbcode_uid, $search);
+ ${$type}['replace'][] = $replace;
+ }
}
}
}
@@ -88,7 +82,8 @@ class bbcode
$message = preg_replace($preg['search'], $preg['replace'], $message);
}
- return $message;
+ // Remove the uid from tags that have not been transformed into HTML
+ $message = str_replace(':' . $this->bbcode_uid, '', $message);
}
//
@@ -99,19 +94,17 @@ class bbcode
//
function bbcode_cache_init()
{
+ global $user, $phpbb_root_path;
+
if (empty($this->template_filename))
{
- global $user, $phpbb_root_path;
-
$style = 'primary';
if (!empty($user->theme['secondary']))
{
- $merged_bitfield = $user->theme['primary']['bbcode_bitfield'] | $user->theme['secondary']['bbcode_bitfield'];
+ // If the primary style has custom templates for BBCodes then we'll make sure
+ // the bbcode.html file is present, otherwise we'll use the secondary style
- // If any of styles has a specific template for any of applicable
- // bbcodes then load the primary bbcode.html if present, otherwise
- // load the secondary bbcode.html file
- if ($this->bbcode_bitfield & $merged_bitfield)
+ if ($this->bbcode_bitfield & $user->theme['primary']['bbcode_bitfield'])
{
$style = (file_exists($phpbb_root_path . 'styles/templates/' . $user->theme['primary']['template_path'] . '/bbcode.html')) ? 'primary' : 'secondary';
}
@@ -134,21 +127,20 @@ class bbcode
}
$bbcode_ids[$bbcode_id] = $bbcode_id;
- // WARNING: hardcoded values. it assumes that bbcodes with bbcode_id > 11 are user-defined bbcodes
if ($bbcode_id > 11)
{
- $sql .= (($sql) ? ',' : '') . $bbcode_id . ',';
+ $sql .= (($sql) ? ',' : '') . $bbcode_id;
}
}
-/*
+
if ($sql)
{
global $db;
$rowset = array();
- $sql = 'SELECT bbcode_id, second_pass_regexp, second_pass_replacement
+ $sql = 'SELECT *
FROM ' . BBCODES_TABLE . "
- WHERE bbcode_id IN ($sql);
+ WHERE bbcode_id IN ($sql)";
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
@@ -157,7 +149,6 @@ class bbcode
}
$db->sql_freeresult($result);
}
-*/
foreach ($bbcode_ids as $bbcode_id)
{
@@ -202,7 +193,7 @@ class bbcode
else
{
$this->bbcode_cache[$bbcode_id] = array('preg' => array(
- '#\[img:$uid\](.*?)\[/img:$uid\]#s' => str_replace('\\2', '[ img ]', $this->bbcode_tpl('url', $bbcode_id))
+ '#\[img:$uid\](.*?)\[/img:$uid\]#s' => str_replace('$2', '[ img ]', $this->bbcode_tpl('url', $bbcode_id))
));
}
break;
@@ -224,7 +215,7 @@ class bbcode
break;
case 8:
$this->bbcode_cache[$bbcode_id] = array('preg' => array(
- '#\[code(?:=([a-z]+))?:$uid\](.*?)\[/code:$uid\]#ise' => "\$this->bbcode_second_pass_code('\\1', '\\2')"
+ '#\[code(?:=([a-z]+))?:$uid\](.*?)\[/code:$uid\]#ise' => "\$this->bbcode_second_pass_code('\$1', '\$2')"
));
break;
case 9:
@@ -238,13 +229,13 @@ class bbcode
'[/*:m:$uid]' => $this->bbcode_tpl('listitem_close', $bbcode_id)
),
'preg' => array(
- '#\[list=([^\[]+):$uid\]#e' => "\$this->bbcode_list('\\1')",
+ '#\[list=([^\[]+):$uid\]#e' => "\$this->bbcode_list('\$1')",
)
);
break;
case 10:
$this->bbcode_cache[$bbcode_id] = array('preg' => array(
- '#\[email:$uid\]((.*?))\[/email:$uid\]#is' => $this->bbcode_tpl('email', $bbcode_id),
+ '#\[email:$uid\]((.*?))\[/email:$uid\]#is' => $this->bbcode_tpl('email', $bbcode_id),
'#\[email=([^\[]+):$uid\](.*?)\[/email:$uid\]#is' => $this->bbcode_tpl('email', $bbcode_id)
));
break;
@@ -258,20 +249,67 @@ class bbcode
else
{
$this->bbcode_cache[$bbcode_id] = array('preg' => array(
- '#\[flash=([0-9]+),([0-9]+):$uid\](.*?)\[/flash:$uid\]#' => str_replace('\\1', '\\3', str_replace('\\2', '[ flash ]', $this->bbcode_tpl('url', $bbcode_id)))
+ '#\[flash=([0-9]+),([0-9]+):$uid\](.*?)\[/flash:$uid\]#' => str_replace('$1', '$3', str_replace('$2', '[ flash ]', $this->bbcode_tpl('url', $bbcode_id)))
));
}
break;
default:
if (isset($rowset[$bbcode_id]))
{
- $this->bbcode_cache[$bbcode_id] = array(
- 'preg' => array($rowset[$bbcode_id]['second_pass_regexp'], $rowset[$bbcode_id]['second_pass_replacement'])
- );
+ if ($this->template_bitfield & (1 << $bbcode_id))
+ {
+ // The bbcode requires a custom template to be loaded
+
+ if (!$bbcode_tpl = $this->bbcode_tpl($rowset[$bbcode_id]['bbcode_tag'], $bbcode_id))
+ {
+ // For some reason, the required template seems not to be available,
+ // use the default template
+
+ $bbcode_tpl = (!empty($rowset[$bbcode_id]['second_pass_replace'])) ? $rowset[$bbcode_id]['second_pass_replace'] : $rowset[$bbcode_id]['bbcode_tpl'];
+ }
+ else
+ {
+ // In order to use templates with custom bbcodes we need
+ // to replace all {VARS} to corresponding backreferences
+ // Note that backreferences are numbered from bbcode_match
+
+ if (preg_match_all('/\{(URL|EMAIL|TEXT|COLOR|NUMBER)[0-9]*\}/', $rowset[$bbcode_id]['bbcode_match'], $m))
+ {
+ foreach ($m[0] as $i => $tok)
+ {
+ $bbcode_tpl = str_replace($tok, '$' . ($i + 1), $bbcode_tpl);
+ }
+ }
+ }
+ }
+ else
+ {
+ // Default template
+
+ $bbcode_tpl = (!empty($rowset[$bbcode_id]['second_pass_replace'])) ? $rowset[$bbcode_id]['second_pass_replace'] : $rowset[$bbcode_id]['bbcode_tpl'];
+ }
+
+ // Replace {L_*} lang strings
+ $bbcode_tpl = preg_replace('/{L_([A-Z_]+)}/e', "(!empty(\$user->lang['\$1'])) ? \$user->lang['\$1'] : ucwords(strtolower(str_replace'_', ' ', '\$1')))", $bbcode_tpl);
+
+ if (!empty($rowset[$bbcode_id]['second_pass_replace']))
+ {
+ // The custom BBCode requires second-pass pattern replacements
+
+ $this->bbcode_cache[$bbcode_id] = array(
+ 'preg' => array($rowset[$bbcode_id]['second_pass_match'] => $bbcode_tpl)
+ );
+ }
+ else
+ {
+ $this->bbcode_cache[$bbcode_id] = array(
+ 'str' => array($rowset[$bbcode_id]['second_pass_match'] => $bbcode_tpl)
+ );
+ }
}
else
{
- $this->bbcode_cache[$bbcode_id] = array();
+ $this->bbcode_cache[$bbcode_id] = FALSE;
}
}
}
@@ -284,21 +322,21 @@ class bbcode
static $bbcode_hardtpl = array(
'b_open' => '',
'b_close' => '',
- 'i_open' => '',
- 'i_close' => '',
+ 'i_open' => '',
+ 'i_close' => '',
'u_open' => '',
'u_close' => '',
- 'url' => '\2',
- 'img' => '
',
- 'size' => '\2',
- 'color' => '\2',
- 'email' => '\2'
+ 'url' => '$2',
+ 'img' => '
',
+ 'size' => '$2',
+ 'color' => '$2',
+ 'email' => '$2'
);
}
if ($bbcode_id != -1 && !($this->template_bitfield & (1 << $bbcode_id)))
{
- return $bbcode_hardtpl[$tpl_name];
+ return (isset($bbcode_hardtpl[$tpl_name])) ? $bbcode_hardtpl[$tpl_name] : FALSE;
}
if (empty($this->bbcode_template))
@@ -318,28 +356,28 @@ class bbcode
$tpl = preg_replace("/\n[\n\r\s\t]*/", '', $tpl);
// Turn template blocks into PHP assignment statements for the values of $bbcode_tpl..
- $tpl = preg_replace('#(.*?)#', "\n" . "\$this->bbcode_template['\\1'] = \$this->bbcode_tpl_replace('\\1','\\2');", $tpl);
+ $tpl = preg_replace('#(.*?)#', "\n" . "\$this->bbcode_template['\$1'] = \$this->bbcode_tpl_replace('\$1','\$2');", $tpl);
$this->bbcode_template = array();
eval($tpl);
}
- return $this->bbcode_template[$tpl_name];
+ return (isset($this->bbcode_template[$tpl_name])) ? $this->bbcode_template[$tpl_name] : ((isset($bbcode_hardtpl[$tpl_name])) ? $bbcode_hardtpl[$tpl_name] : FALSE);
}
function bbcode_tpl_replace($tpl_name, $tpl)
{
static $replacements = array(
- 'quote_username_open' => array('{USERNAME}' => '\\1'),
- 'color' => array('{COLOR}' => '\\1', 'TEXT' => '\\2'),
- 'size' => array('{SIZE}' => '\\1', 'TEXT' => '\\2'),
- 'img' => array('{URL}' => '\\1'),
- 'flash' => array('{WIDTH}' => '\\1', '{HEIGHT}' => '\\2', '{URL}' => '\\3'),
- 'url' => array('{URL}' => '\\1', '{DESCRIPTION}' => '\\2'),
- 'email' => array('{EMAIL}' => '\\1', '{DESCRIPTION}' => '\\2')
+ 'quote_username_open' => array('{USERNAME}' => '$1'),
+ 'color' => array('{COLOR}' => '$1', '{TEXT}' => '$2'),
+ 'size' => array('{SIZE}' => '$1', '{TEXT}' => '$2'),
+ 'img' => array('{URL}' => '$1'),
+ 'flash' => array('{WIDTH}' => '$1', '{HEIGHT}' => '$2', '{URL}' => '$3'),
+ 'url' => array('{URL}' => '$1', '{DESCRIPTION}' => '$2'),
+ 'email' => array('{EMAIL}' => '$1', '{DESCRIPTION}' => '$2')
);
- $tpl = preg_replace('/{L_([A-Z_]+)}/e', "(!empty(\$user->lang['\\1'])) ? \$user->lang['\\1'] : ucwords(strtolower('\\1'))", $tpl);
+ $tpl = preg_replace('/{L_([A-Z_]+)}/e', "(!empty(\$user->lang['\$1'])) ? \$user->lang['\$1'] : ucwords(strtolower(str_replace('_', ' ', '\$1')))", $tpl);
if (!empty($replacements[$tpl_name]))
{
@@ -405,7 +443,9 @@ class bbcode
function bbcode_second_pass_code($type, $code)
{
- $code = stripslashes($code);
+ // when using the /e modifier, preg_replace slashes double-quotes but does not
+ // seem to slash anything else
+ $code = str_replace('\"', '"', $code);
switch ($type)
{
diff --git a/phpBB/includes/message_parser.php b/phpBB/includes/message_parser.php
index 16b6208975..450656d8e7 100644
--- a/phpBB/includes/message_parser.php
+++ b/phpBB/includes/message_parser.php
@@ -1,31 +1,21 @@
message_mode = $message_type;
@@ -116,7 +108,7 @@ class parse_message
if (sizeof($allowed_tags))
{
- $this->message = preg_replace('#<(\/?)(' . str_replace('*', '.*?', implode('|', $allowed_tags)) . ')>#is', '<\1\2>', $this->message);
+ $this->message = preg_replace('#<(\/?)(' . str_replace('*', '.*?', implode('|', $allowed_tags)) . ')>#is', '<$1$2>', $this->message);
}
}
}
@@ -170,27 +162,29 @@ class parse_message
// 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.
$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')")),
- 'b' => array('bbcode_id' => 1, 'regexp' => array('#\[b\](.*?)\[/b\]#is' => '[b:' . $this->bbcode_uid . ']\1[/b:' . $this->bbcode_uid . ']')),
- 'i' => array('bbcode_id' => 2, 'regexp' => array('#\[i\](.*?)\[/i\]#is' => '[i:' . $this->bbcode_uid . ']\1[/i:' . $this->bbcode_uid . ']')),
- 'url' => array('bbcode_id' => 3, 'regexp' => array('#\[url=?(.*?)?\](.*?)\[/url\]#ise' => "\$this->validate_url('\\1', '\\2')")),
- 'img' => array('bbcode_id' => 4, 'regexp' => array('#\[img\](https?://)([a-z0-9\-\.,\?!%\*_:;~\\&$@/=\+]+)\[/img\]#i' => '[img:' . $this->bbcode_uid . ']\1\2[/img:' . $this->bbcode_uid . ']')),
- 'size' => array('bbcode_id' => 5, 'regexp' => array('#\[size=([\-\+]?[1-2]?[0-9])\](.*?)\[/size\]#is' => '[size=\1:' . $this->bbcode_uid . ']\2[/size:' . $this->bbcode_uid . ']')),
- 'color' => array('bbcode_id' => 6, 'regexp' => array('!\[color=(#[0-9A-F]{6}|[a-z\-]+)\](.*?)\[/color\]!is' => '[color=\1:' . $this->bbcode_uid . ']\2[/color:' . $this->bbcode_uid . ']')),
- 'u' => array('bbcode_id' => 7, 'regexp' => array('#\[u\](.*?)\[/u\]#is' => '[u:' . $this->bbcode_uid . ']\1[/u:' . $this->bbcode_uid . ']')),
- 'list' => array('bbcode_id' => 9, 'regexp' => array('#\[list(=[a-z|0-9|(?:disc|circle|square))]+)?\].*\[/list\]#ise' => "\$this->bbcode_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\]#i' => '[flash=\1,\2:' . $this->bbcode_uid . ']\3[/flash:' . $this->bbcode_uid . ']'))
+ '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')")),
+ 'b' => array('bbcode_id' => 1, 'regexp' => array('#\[b\](.*?)\[/b\]#is' => '[b:' . $this->bbcode_uid . ']$1[/b:' . $this->bbcode_uid . ']')),
+ 'i' => array('bbcode_id' => 2, 'regexp' => array('#\[i\](.*?)\[/i\]#is' => '[i:' . $this->bbcode_uid . ']$1[/i:' . $this->bbcode_uid . ']')),
+ 'url' => array('bbcode_id' => 3, 'regexp' => array('#\[url=?(.*?)?\](.*?)\[/url\]#ise' => "\$this->validate_url('\$1', '\$2')")),
+ 'img' => array('bbcode_id' => 4, 'regexp' => array('#\[img\](https?://)([a-z0-9\-\.,\?!%\*_:;~\\&$@/=\+]+)\[/img\]#i' => '[img:' . $this->bbcode_uid . ']$1$2[/img:' . $this->bbcode_uid . ']')),
+ 'size' => array('bbcode_id' => 5, 'regexp' => array('#\[size=([\-\+]?[1-2]?[0-9])\](.*?)\[/size\]#is' => '[size=$1:' . $this->bbcode_uid . ']$2[/size:' . $this->bbcode_uid . ']')),
+ 'color' => array('bbcode_id' => 6, 'regexp' => array('!\[color=(#[0-9A-F]{6}|[a-z\-]+)\](.*?)\[/color\]!is' => '[color=$1:' . $this->bbcode_uid . ']$2[/color:' . $this->bbcode_uid . ']')),
+ 'u' => array('bbcode_id' => 7, 'regexp' => array('#\[u\](.*?)\[/u\]#is' => '[u:' . $this->bbcode_uid . ']$1[/u:' . $this->bbcode_uid . ']')),
+ 'list' => array('bbcode_id' => 9, 'regexp' => array('#\[list(=[a-z|0-9|(?:disc|circle|square))]+)?\].*\[/list\]#ise' => "\$this->bbcode_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\]#i' => '[flash=$1,$2:' . $this->bbcode_uid . ']$3[/flash:' . $this->bbcode_uid . ']'))
);
-/**************
if (!isset($rowset))
{
global $db;
$rowset = array();
- $result = $db->sql_query('SELECT * FROM ' . BBCODES_TABLE);
+ $sql = 'SELECT bbcode_id, bbcode_tag, first_pass_match, first_pass_replace
+ FROM ' . BBCODES_TABLE;
+
+ $result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
$rowset[] = $row;
@@ -198,19 +192,19 @@ class parse_message
}
foreach ($rowset as $row)
{
- $this->bbcodes[$row['bbcode_name']] = array(
- 'bbcode_id' => $row['bbcode_id'],
- 'regexp' => array($row['first_pass_regexp'] => str_replace('$uid', $this->bbcode_uid, $row['first_pass_replacement']))
+ $this->bbcodes[$row['bbcode_tag']] = array(
+ 'bbcode_id' => intval($row['bbcode_id']),
+ 'regexp' => array($row['first_pass_match'] => str_replace('$uid', $this->bbcode_uid, $row['first_pass_replace']))
);
}
-**************/
}
// Expects the argument to start right after the opening [code] tag and to end with [/code]
function bbcode_code($stx, $in)
{
- // if I remember correctly, preg_replace() will slash passed vars
- $in = str_replace("\r\n", "\n", stripslashes($in));
+ // when using the /e modifier, preg_replace slashes double-quotes but does not
+ // seem to slash anything else
+ $in = str_replace("\r\n", "\n", str_replace('\"', '"', $in));
$out = '';
do
@@ -237,7 +231,7 @@ class parse_message
}
$code = substr($code, 0, -7);
- $code = preg_replace('#^[\r\n]*(.*?)[\n\r\s\t]*$#s', '\1', $code);
+ $code = preg_replace('#^[\r\n]*(.*?)[\n\r\s\t]*$#s', '$1', $code);
switch (strtolower($stx))
{
@@ -273,12 +267,18 @@ class parse_message
$str_to[] = '';
$str_from[] = '<?php ';
$str_to[] = '';
- $str_from[] = '?>';
- $str_to[] = '';
}
$code = str_replace($str_from, $str_to, $code);
- $code = preg_replace('#^()\n?(.*?)\n?()$#is', '\1\2\3', $code);
+ $code = preg_replace('#^()\n?(.*?)\n?()$#is', '$1$2$3', $code);
+
+ if ($remove_tags)
+ {
+ $code = preg_replace('#()?\?>#', '', $code);
+ }
+
+ $code = preg_replace('#^(.*)#s', '$2', $code);
+ $code = preg_replace('#(?:[\n\r\s\t]| )*$#', '', $code);
$out .= "[code=$stx:" . $this->bbcode_uid . ']' . trim($code) . '[/code:' . $this->bbcode_uid . ']';
break;
@@ -308,7 +308,8 @@ class parse_message
$tok = ']';
$out = '[';
- $in = substr(stripslashes($in), 1);
+
+ $in = substr(str_replace('\"', '"', $in), 1);
$list_end_tags = $item_end_tags = array();
do
@@ -423,7 +424,7 @@ class parse_message
$tok = ']';
$out = '[';
- $in = substr(stripslashes($in), 1);
+ $in = substr(str_replace('\"', '"', $in), 1);
$close_tags = $error_ary = array();
$buffer = '';
@@ -472,7 +473,7 @@ class parse_message
if (!empty($m[1]))
{
- $username = preg_replace('#\[(?!b|i|u|color|url|email|/b|/i|/u|/color|/url|/email)#iU', '[\1', $m[1]);
+ $username = preg_replace('#\[(?!b|i|u|color|url|email|/b|/i|/u|/color|/url|/email)#iU', '[$1', $m[1]);
$end_tags = array();
$error = FALSE;
@@ -547,10 +548,29 @@ class parse_message
function validate_email($var1, $var2)
{
- $var1 = stripslashes($var1);
- $var2 = stripslashes($var2);
+ $txt = stripslashes($var2);
+ $email = ($var1 != '') ? stripslashes($var1) : stripslashes($var2);
- $retval = '[email' . $var1 . ':' . $this->bbcode_uid . ']' . $var2 . '[/email:' . $this->bbcode_uid . ']';
+ $validated = TRUE;
+
+ if (!preg_match('!([a-z0-9]+[a-z0-9\-\._]*@(?:(?:[0-9]{1,3}\.){3,5}[0-9]{1,3}|[a-z0-9]+[a-z0-9\-\._]*\.[a-z]+))!i', $email))
+ {
+ $validated = FALSE;
+ }
+
+ if (!$validated)
+ {
+ return '[email' . (($var1) ? "=$var1" : '') . ']' . $var2 . '[/email]';
+ }
+
+ if ($var1)
+ {
+ $retval = '[email=' . $email . ':' . $this->bbcode_uid . ']' . $txt . '[/email:' . $this->bbcode_uid . ']';
+ }
+ else
+ {
+ $retval = '[email:' . $this->bbcode_uid . ']' . $email . '[/email:' . $this->bbcode_uid . ']';
+ }
return $retval;
}
@@ -587,20 +607,20 @@ class parse_message
$replace = array();
// relative urls for this board
- $match[] = '#(^|[\n ])' . $server_protocol . trim($config['server_name']) . $server_port . preg_replace('/^\/?(.*?)(\/)?$/', '\1', trim($config['script_path'])) . '/([^ \t\n\r <"\']+)#i';
- $replace[] = '\1';
+ $match[] = '#(^|[\n ])' . $server_protocol . trim($config['server_name']) . $server_port . preg_replace('/^\/?(.*?)(\/)?$/', '$1', trim($config['script_path'])) . '/([^ \t\n\r <"\']+)#i';
+ $replace[] = '$1';
// matches a xxxx://aaaaa.bbb.cccc. ...
$match[] = '#(^|[\n ])([\w]+?://.*?[^ \t\n\r<"]*)#ie';
- $replace[] = "'\\1' . ((strlen('\\2') > 55) ? substr('\\2', 0, 39) . ' ... ' . substr('\\2', -10) : '\\2') . ''";
+ $replace[] = "'\$1' . ((strlen('\$2') > 55) ? substr('\$2', 0, 39) . ' ... ' . substr('\$2', -10) : '\$2') . ''";
// matches a "www.xxxx.yyyy[/zzzz]" kinda lazy URL thing
$match[] = '#(^|[\n ])(www\.[\w\-]+\.[\w\-.\~]+(?:/[^ \t\n\r<"]*)?)#ie';
- $replace[] = "'\\1' . ((strlen('\\2') > 55) ? substr(str_replace(' ', '%20', '\\2'), 0, 39) . ' ... ' . substr('\\2', -10) : '\\2') . ''";
+ $replace[] = "'\$1' . ((strlen('\$2') > 55) ? substr(str_replace(' ', '%20', '\$2'), 0, 39) . ' ... ' . substr('\$2', -10) : '\$2') . ''";
// matches an email@domain type address at the start of a line, or after a space.
$match[] = '#(^|[\n ])([a-z0-9&\-_.]+?@[\w\-]+\.([\w\-\.]+\.)?[\w]+)#ie';
- $replace[] = "'\\1' . ((strlen('\\2') > 55) ? substr('\\2', 0, 39) . ' ... ' . substr('\\2', -10) : '\\2') . ''";
+ $replace[] = "'\$1' . ((strlen('\$2') > 55) ? substr('\$2', 0, 39) . ' ... ' . substr('\$2', -10) : '\$2') . ''";
$this->message = preg_replace($match, $replace, $this->message);
}
@@ -622,6 +642,7 @@ class parse_message
if ($row = $db->sql_fetchrow($result))
{
$match = $replace = array();
+
do
{
$match[] = '#(' . preg_quote($row['code'], '#') . ')#';
@@ -643,7 +664,6 @@ class parse_message
$this->message = preg_replace($match, $replace, ' ' . $this->message . ' ');
}
- $db->sql_freeresult($result);
}
function parse_attachments($mode, $post_id, $submit, $preview, $refresh)
@@ -956,7 +976,7 @@ class fulltext_search
{
$sql = 'SELECT word_id, word_text
FROM ' . SEARCH_WORD_TABLE . '
- WHERE word_text IN (' . implode(', ', preg_replace('#^(.*)$#', '\'\1\'', $unique_add_words)) . ")";
+ WHERE word_text IN (' . implode(', ', preg_replace('#^(.*)$#', '\'$1\'', $unique_add_words)) . ")";
$result = $db->sql_query($sql);
$word_ids = array();
@@ -976,13 +996,13 @@ class fulltext_search
case 'mysql':
case 'mysql4':
$sql = 'INSERT INTO ' . SEARCH_WORD_TABLE . ' (word_text)
- VALUES ' . implode(', ', preg_replace('#^(.*)$#', '(\'\1\')', $new_words));
+ VALUES ' . implode(', ', preg_replace('#^(.*)$#', '(\'$1\')', $new_words));
$db->sql_query($sql);
break;
case 'mssql':
case 'sqlite':
- $sql = 'INSERT INTO ' . SEARCH_WORD_TABLE . ' (word_text) ' . implode(' UNION ALL ', preg_replace('#^(.*)$#', "SELECT '\\1'", $new_words));
+ $sql = 'INSERT INTO ' . SEARCH_WORD_TABLE . ' (word_text) ' . implode(' UNION ALL ', preg_replace('#^(.*)$#', "SELECT '\$1'", $new_words));
$db->sql_query($sql);
break;
@@ -1029,7 +1049,7 @@ class fulltext_search
$sql = 'INSERT INTO ' . SEARCH_MATCH_TABLE . " (post_id, word_id, title_match)
SELECT $post_id, word_id, $title_match
FROM " . SEARCH_WORD_TABLE . '
- WHERE word_text IN (' . implode(', ', preg_replace('#^(.*)$#', '\'\1\'', $word_ary)) . ')';
+ WHERE word_text IN (' . implode(', ', preg_replace('#^(.*)$#', '\'$1\'', $word_ary)) . ')';
$db->sql_query($sql);
}
}