Merge pull request #3618 from marc1706/ticket/13832

[ticket/13832] Use preg_replace_callback instead of /e modifier
This commit is contained in:
Tristan Darricau 2015-06-24 16:36:15 +02:00
commit 6bcf12a558
5 changed files with 138 additions and 32 deletions

View file

@ -140,8 +140,12 @@ function html_entity_decode_utf8($string)
static $trans_tbl;
// replace numeric entities
$string = preg_replace('~&#x([0-9a-f]+);~ei', 'code2utf8(hexdec("\\1"))', $string);
$string = preg_replace('~&#([0-9]+);~e', 'code2utf8(\\1)', $string);
$string = preg_replace_callback('~&#x([0-9a-f]+);~i', function ($match) {
return code2utf8(hexdec($match[1]));
}, $string);
$string = preg_replace_callback('~&#([0-9]+);~', function ($match) {
return code2utf8($match[1]);
}, $string);
// replace literal entities
if (!isset($trans_tbl))

View file

@ -489,7 +489,9 @@ class acp_bbcodes
if (preg_match_all('/(?<!\\\\)\$([0-9]+)/', $replace, $repad))
{
$repad = $pad + sizeof(array_unique($repad[0]));
$replace = preg_replace('/(?<!\\\\)\$([0-9]+)/e', "'\${' . (\$1 + \$pad) . '}'", $replace);
$replace = preg_replace_callback('/(?<!\\\\)\$([0-9]+)/', function ($match) use ($pad) {
return '${' . ($match[1] + $pad) . '}';
}, $replace);
$pad = $repad;
}
@ -554,10 +556,18 @@ class acp_bbcodes
trigger_error($user->lang['BBCODE_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
}
$fp_match = preg_replace('#\[/?' . $bbcode_search . '#ie', "strtolower('\$0')", $fp_match);
$fp_replace = preg_replace('#\[/?' . $bbcode_search . '#ie', "strtolower('\$0')", $fp_replace);
$sp_match = preg_replace('#\[/?' . $bbcode_search . '#ie', "strtolower('\$0')", $sp_match);
$sp_replace = preg_replace('#\[/?' . $bbcode_search . '#ie', "strtolower('\$0')", $sp_replace);
$fp_match = preg_replace_callback('#\[/?' . $bbcode_search . '#i', function ($match) {
return strtolower($match[0]);
}, $fp_match);
$fp_replace = preg_replace_callback('#\[/?' . $bbcode_search . '#i', function ($match) {
return strtolower($match[0]);
}, $fp_replace);
$sp_match = preg_replace_callback('#\[/?' . $bbcode_search . '#i', function ($match) {
return strtolower($match[0]);
}, $sp_match);
$sp_replace = preg_replace_callback('#\[/?' . $bbcode_search . '#i', function ($match) {
return strtolower($match[0]);
}, $sp_replace);
return array(
'bbcode_tag' => $bbcode_tag,

View file

@ -110,7 +110,18 @@ class bbcode
$undid_bbcode_specialchars = true;
}
$message = preg_replace($preg['search'], $preg['replace'], $message);
foreach ($preg['search'] as $key => $search)
{
if (is_callable($preg['replace'][$key]))
{
$message = preg_replace_callback($search, $preg['replace'][$key], $message);
}
else
{
$message = preg_replace($search, $preg['replace'][$key], $message);
}
}
$preg = array('search' => array(), 'replace' => array());
}
}
@ -214,7 +225,9 @@ class bbcode
'[/quote:$uid]' => $this->bbcode_tpl('quote_close', $bbcode_id)
),
'preg' => array(
'#\[quote(?:=&quot;(.*?)&quot;)?:$uid\]((?!\[quote(?:=&quot;.*?&quot;)?:$uid\]).)?#ise' => "\$this->bbcode_second_pass_quote('\$1', '\$2')"
'#\[quote(?:=&quot;(.*?)&quot;)?:$uid\]((?!\[quote(?:=&quot;.*?&quot;)?:$uid\]).)?#is' => function ($match) {
return $this->bbcode_second_pass_quote($match[1], $match[2]);
},
)
);
break;
@ -293,7 +306,9 @@ class bbcode
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\]#is' => function ($match) {
return $this->bbcode_second_pass_code($match[1], $match[2]);
},
)
);
break;
@ -303,7 +318,9 @@ class bbcode
'preg' => array(
'#(\[\/?(list|\*):[mou]?:?$uid\])[\n]{1}#' => "\$1",
'#(\[list=([^\[]+):$uid\])[\n]{1}#' => "\$1",
'#\[list=([^\[]+):$uid\]#e' => "\$this->bbcode_list('\$1')",
'#\[list=([^\[]+):$uid\]#' => function ($match) {
return $this->bbcode_list($match[1]);
},
),
'str' => array(
'[list:$uid]' => $this->bbcode_tpl('ulist_open_default', $bbcode_id),
@ -387,7 +404,9 @@ class bbcode
}
// Replace {L_*} lang strings
$bbcode_tpl = preg_replace('/{L_([A-Z0-9_]+)}/e', "(!empty(\$user->lang['\$1'])) ? \$user->lang['\$1'] : ucwords(strtolower(str_replace('_', ' ', '\$1')))", $bbcode_tpl);
$bbcode_tpl = preg_replace_callback('/{L_([A-Z0-9_]+)}/', function ($match) use ($user) {
return (!empty($user->lang[$match[1]])) ? $user->lang($match[1]) : ucwords(strtolower(str_replace('_', ' ', $match[1])));
}, $bbcode_tpl);
if (!empty($rowset[$bbcode_id]['second_pass_replace']))
{
@ -511,7 +530,9 @@ class bbcode
'email' => array('{EMAIL}' => '$1', '{DESCRIPTION}' => '$2')
);
$tpl = preg_replace('/{L_([A-Z0-9_]+)}/e', "(!empty(\$user->lang['\$1'])) ? \$user->lang['\$1'] : ucwords(strtolower(str_replace('_', ' ', '\$1')))", $tpl);
$tpl = preg_replace_callback('/{L_([A-Z0-9_]+)}/', function ($match) use ($user) {
return (!empty($user->lang[$match[1]])) ? $user->lang($match[1]) : ucwords(strtolower(str_replace('_', ' ', $match[1])));
}, $tpl);
if (!empty($replacements[$tpl_name]))
{

View file

@ -83,7 +83,14 @@ class bbcode_firstpass extends bbcode
// it should not demand recompilation
if (preg_match($regexp, $this->message))
{
$this->message = preg_replace($regexp, $replacement, $this->message);
if (is_callable($replacement))
{
$this->message = preg_replace_callback($regexp, $replacement, $this->message);
}
else
{
$this->message = preg_replace($regexp, $replacement, $this->message);
}
$bitfield->set($bbcode_data['bbcode_id']);
}
}
@ -123,6 +130,8 @@ class bbcode_firstpass extends bbcode
static $rowset;
$bbcode_class = $this;
// 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.
@ -132,19 +141,71 @@ class bbcode_firstpass extends bbcode
// To perform custom validation in extension, use $this->validate_bbcode_by_extension()
// method which accepts variable number of parameters
$this->bbcodes = array(
'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(?:=&quot;(.*?)&quot;)?\](.+)\[/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')"))
'code' => array('bbcode_id' => 8, 'regexp' => array('#\[code(?:=([a-z]+))?\](.+\[/code\])#uis' => function ($match) use($bbcode_class)
{
return $bbcode_class->bbcode_code($match[1], $match[2]);
}
)),
'quote' => array('bbcode_id' => 0, 'regexp' => array('#\[quote(?:=&quot;(.*?)&quot;)?\](.+)\[/quote\]#uis' => function ($match) use($bbcode_class)
{
return $bbcode_class->bbcode_quote($match[0]);
}
)),
'attachment' => array('bbcode_id' => 12, 'regexp' => array('#\[attachment=([0-9]+)\](.*?)\[/attachment\]#uis' => function ($match) use($bbcode_class)
{
return $bbcode_class->bbcode_attachment($match[1], $match[2]);
}
)),
'b' => array('bbcode_id' => 1, 'regexp' => array('#\[b\](.*?)\[/b\]#uis' => function ($match) use($bbcode_class)
{
return $bbcode_class->bbcode_strong($match[1]);
}
)),
'i' => array('bbcode_id' => 2, 'regexp' => array('#\[i\](.*?)\[/i\]#uis' => function ($match) use($bbcode_class)
{
return $bbcode_class->bbcode_italic($match[1]);
}
)),
'url' => array('bbcode_id' => 3, 'regexp' => array('#\[url(=(.*))?\](?(1)((?s).*(?-s))|(.*))\[/url\]#uiU' => function ($match) use($bbcode_class)
{
return $bbcode_class->validate_url($match[2], ($match[3]) ? $match[3] : $match[4]);
}
)),
'img' => array('bbcode_id' => 4, 'regexp' => array('#\[img\](.*)\[/img\]#uiU' => function ($match) use($bbcode_class)
{
return $bbcode_class->bbcode_img($match[1]);
}
)),
'size' => array('bbcode_id' => 5, 'regexp' => array('#\[size=([\-\+]?\d+)\](.*?)\[/size\]#uis' => function ($match) use($bbcode_class)
{
return $bbcode_class->bbcode_size($match[1], $match[2]);
}
)),
'color' => array('bbcode_id' => 6, 'regexp' => array('!\[color=(#[0-9a-f]{3}|#[0-9a-f]{6}|[a-z\-]+)\](.*?)\[/color\]!uis' => function ($match) use($bbcode_class)
{
return $bbcode_class->bbcode_color($match[1], $match[2]);
}
)),
'u' => array('bbcode_id' => 7, 'regexp' => array('#\[u\](.*?)\[/u\]#uis' => function ($match) use($bbcode_class)
{
return $bbcode_class->bbcode_underline($match[1]);
}
)),
'list' => array('bbcode_id' => 9, 'regexp' => array('#\[list(?:=(?:[a-z0-9]|disc|circle|square))?].*\[/list]#uis' => function ($match) use($bbcode_class)
{
return $bbcode_class->bbcode_parse_list($match[0]);
}
)),
'email' => array('bbcode_id' => 10, 'regexp' => array('#\[email=?(.*?)?\](.*?)\[/email\]#uis' => function ($match) use($bbcode_class)
{
return $bbcode_class->validate_email($match[1], $match[2]);
}
)),
'flash' => array('bbcode_id' => 11, 'regexp' => array('#\[flash=([0-9]+),([0-9]+)\](.*?)\[/flash\]#ui' => function ($match) use($bbcode_class)
{
return $bbcode_class->bbcode_flash($match[1], $match[2], $match[3]);
}
))
);
// Zero the parsed items array
@ -747,7 +808,9 @@ class bbcode_firstpass extends bbcode
}
// 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_callback('#quote=&quot;(.*?)&quot;\]#i', function ($match) {
return 'quote=&quot;' . str_replace(array('[', ']', '\\\"'), array('&#91;', '&#93;', '\"'), $match[1]) . '&quot;]';
}, $in);
$tok = ']';
$out = '[';
@ -1536,7 +1599,9 @@ class parse_message extends bbcode_firstpass
);
$this->attachment_data = array_merge(array(0 => $new_entry), $this->attachment_data);
$this->message = preg_replace('#\[attachment=([0-9]+)\](.*?)\[\/attachment\]#e', "'[attachment='.(\\1 + 1).']\\2[/attachment]'", $this->message);
$this->message = preg_replace_callback('#\[attachment=([0-9]+)\](.*?)\[\/attachment\]#', function ($match) {
return '[attachment='.($match[1] + 1).']' . $match[2] . '[/attachment]';
}, $this->message);
$this->filename_data['filecomment'] = '';
@ -1604,7 +1669,9 @@ class parse_message extends bbcode_firstpass
}
unset($this->attachment_data[$index]);
$this->message = preg_replace('#\[attachment=([0-9]+)\](.*?)\[\/attachment\]#e', "(\\1 == \$index) ? '' : ((\\1 > \$index) ? '[attachment=' . (\\1 - 1) . ']\\2[/attachment]' : '\\0')", $this->message);
$this->message = preg_replace_callback('#\[attachment=([0-9]+)\](.*?)\[\/attachment\]#', function ($match) use($index) {
return ($match[1] == $index) ? '' : (($match[1] > $index) ? '[attachment=' . ($match[1] - 1) . ']' . $match[2] . '[/attachment]' : $match[0]);
}, $this->message);
// Reindex Array
$this->attachment_data = array_values($this->attachment_data);
@ -1648,7 +1715,9 @@ class parse_message extends bbcode_firstpass
);
$this->attachment_data = array_merge(array(0 => $new_entry), $this->attachment_data);
$this->message = preg_replace('#\[attachment=([0-9]+)\](.*?)\[\/attachment\]#e', "'[attachment='.(\\1 + 1).']\\2[/attachment]'", $this->message);
$this->message = preg_replace_callback('#\[attachment=([0-9]+)\](.*?)\[\/attachment\]#', function ($match) {
return '[attachment=' . ($match[1] + 1) . ']' . $match[2] . '[/attachment]';
}, $this->message);
$this->filename_data['filecomment'] = '';
if (isset($this->plupload) && $this->plupload->is_active())

View file

@ -507,7 +507,9 @@ function message_options($id, $mode, $global_privmsgs_rules, $global_rule_condit
$rule_lang = $action_lang = $check_lang = array();
// Build all three language arrays
preg_replace('#^((RULE|ACTION|CHECK)_([A-Z0-9_]+))$#e', "\${strtolower('\\2') . '_lang'}[constant('\\1')] = \$user->lang['PM_\\2']['\\3']", array_keys(get_defined_constants()));
preg_replace_callback('#^((RULE|ACTION|CHECK)_([A-Z0-9_]+))$#', function ($match) use(&$rule_lang, &$action_lang, &$check_lang, $user) {
${strtolower($match[2]) . '_lang'}[constant($match[1])] = $user->lang['PM_' . $match[2]][$match[3]];
}, array_keys(get_defined_constants()));
/*
Rule Ordering: