diff options
Diffstat (limited to 'phpBB/includes/acp/acp_bbcodes.php')
-rw-r--r-- | phpBB/includes/acp/acp_bbcodes.php | 183 |
1 files changed, 24 insertions, 159 deletions
diff --git a/phpBB/includes/acp/acp_bbcodes.php b/phpBB/includes/acp/acp_bbcodes.php index bd8df6a63b..5e39055f50 100644 --- a/phpBB/includes/acp/acp_bbcodes.php +++ b/phpBB/includes/acp/acp_bbcodes.php @@ -157,7 +157,7 @@ class acp_bbcodes * @var string bbcode_tpl The bbcode HTML replacement string * @var string bbcode_helpline The bbcode help line string * @var array hidden_fields Array of hidden fields for use when - * submitting form when $warn_text is true + * submitting form when $warn_unsafe is true * @since 3.1.0-a3 */ $vars = array( @@ -172,14 +172,25 @@ class acp_bbcodes ); extract($phpbb_dispatcher->trigger_event('core.acp_bbcodes_modify_create', compact($vars))); - $warn_text = preg_match('%<[^>]*\{text[\d]*\}[^>]*>%i', $bbcode_tpl); + $acp_utils = $phpbb_container->get('text_formatter.acp_utils'); + $bbcode_info = $acp_utils->analyse_bbcode($bbcode_match, $bbcode_tpl); + $warn_unsafe = ($bbcode_info['status'] === $acp_utils::BBCODE_STATUS_UNSAFE); - if (!$warn_text && !check_form_key($form_key)) + if ($bbcode_info['status'] === $acp_utils::BBCODE_STATUS_INVALID_TEMPLATE) + { + trigger_error($user->lang['BBCODE_INVALID_TEMPLATE'] . adm_back_link($this->u_action), E_USER_WARNING); + } + if ($bbcode_info['status'] === $acp_utils::BBCODE_STATUS_INVALID_DEFINITION) + { + trigger_error($user->lang['BBCODE_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); + } + + if (!$warn_unsafe && !check_form_key($form_key)) { trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); } - if (!$warn_text || confirm_box(true)) + if (!$warn_unsafe || confirm_box(true)) { $data = $this->build_regexp($bbcode_match, $bbcode_tpl); @@ -196,7 +207,10 @@ class acp_bbcodes $db->sql_freeresult($result); // Grab the end, interrogate the last closing tag - if ($info['test'] === '1' || in_array(strtolower($data['bbcode_tag']), $hard_coded) || (preg_match('#\[/([^[]*)]$#', $bbcode_match, $regs) && in_array(strtolower($regs[1]), $hard_coded))) + if (isset($info['test']) && $info['test'] === '1' + || in_array(strtolower($data['bbcode_tag']), $hard_coded) + || (preg_match('#\[/([^[]*)]$#', $bbcode_match, $regs) && in_array(strtolower($regs[1]), $hard_coded)) + ) { trigger_error($user->lang['BBCODE_INVALID_TAG_NAME'] . adm_back_link($this->u_action), E_USER_WARNING); } @@ -446,144 +460,7 @@ class acp_bbcodes function build_regexp(&$bbcode_match, &$bbcode_tpl) { $bbcode_match = trim($bbcode_match); - $bbcode_tpl = trim($bbcode_tpl); - - // Allow unicode characters for URL|LOCAL_URL|RELATIVE_URL|INTTEXT tokens - $utf8 = preg_match('/(URL|LOCAL_URL|RELATIVE_URL|INTTEXT)/', $bbcode_match); - - $fp_match = preg_quote($bbcode_match, '!'); - $fp_replace = preg_replace('#^\[(.*?)\]#', '[$1:$uid]', $bbcode_match); - $fp_replace = preg_replace('#\[/(.*?)\]$#', '[/$1:$uid]', $fp_replace); - - $sp_match = preg_quote($bbcode_match, '!'); - $sp_match = preg_replace('#^\\\\\[(.*?)\\\\\]#', '\[$1:$uid\]', $sp_match); - $sp_match = preg_replace('#\\\\\[/(.*?)\\\\\]$#', '\[/$1:$uid\]', $sp_match); - $sp_replace = $bbcode_tpl; - - // @todo Make sure to change this too if something changed in message parsing - $tokens = array( - 'URL' => array( - '!(?:(' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('url')) . ')|(' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('www_url')) . '))!ie' => "\$this->bbcode_specialchars(('\$1') ? '\$1' : 'http://\$2')" - ), - 'LOCAL_URL' => array( - '!(' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('relative_url')) . ')!e' => "\$this->bbcode_specialchars('$1')" - ), - 'RELATIVE_URL' => array( - '!(' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('relative_url')) . ')!e' => "\$this->bbcode_specialchars('$1')" - ), - 'EMAIL' => array( - '!(' . get_preg_expression('email') . ')!ie' => "\$this->bbcode_specialchars('$1')" - ), - 'TEXT' => array( - '!(.*?)!es' => "str_replace(array(\"\\r\\n\", '\\\"', '\\'', '(', ')'), array(\"\\n\", '\"', ''', '(', ')'), trim('\$1'))" - ), - 'SIMPLETEXT' => array( - '!([a-zA-Z0-9-+.,_ ]+)!' => "$1" - ), - 'INTTEXT' => array( - '!([\p{L}\p{N}\-+,_. ]+)!u' => "$1" - ), - 'IDENTIFIER' => array( - '!([a-zA-Z0-9-_]+)!' => "$1" - ), - 'COLOR' => array( - '!([a-z]+|#[0-9abcdef]+)!i' => '$1' - ), - 'NUMBER' => array( - '!([0-9]+)!' => '$1' - ) - ); - - $sp_tokens = array( - 'URL' => '(?i)((?:' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('url')) . ')|(?:' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('www_url')) . '))(?-i)', - 'LOCAL_URL' => '(?i)(' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('relative_url')) . ')(?-i)', - 'RELATIVE_URL' => '(?i)(' . str_replace(array('!', '\#'), array('\!', '#'), get_preg_expression('relative_url')) . ')(?-i)', - 'EMAIL' => '(' . get_preg_expression('email') . ')', - 'TEXT' => '(.*?)', - 'SIMPLETEXT' => '([a-zA-Z0-9-+.,_ ]+)', - 'INTTEXT' => '([\p{L}\p{N}\-+,_. ]+)', - 'IDENTIFIER' => '([a-zA-Z0-9-_]+)', - 'COLOR' => '([a-zA-Z]+|#[0-9abcdefABCDEF]+)', - 'NUMBER' => '([0-9]+)', - ); - - $pad = 0; - $modifiers = 'i'; - $modifiers .= ($utf8) ? 'u' : ''; - - if (preg_match_all('/\{(' . implode('|', array_keys($tokens)) . ')[0-9]*\}/i', $bbcode_match, $m)) - { - foreach ($m[0] as $n => $token) - { - $token_type = $m[1][$n]; - - reset($tokens[strtoupper($token_type)]); - list($match, $replace) = each($tokens[strtoupper($token_type)]); - - // Pad backreference numbers from tokens - if (preg_match_all('/(?<!\\\\)\$([0-9]+)/', $replace, $repad)) - { - $repad = $pad + count(array_unique($repad[0])); - $replace = preg_replace_callback('/(?<!\\\\)\$([0-9]+)/', function ($match) use ($pad) { - return '${' . ($match[1] + $pad) . '}'; - }, $replace); - $pad = $repad; - } - - // Obtain pattern modifiers to use and alter the regex accordingly - $regex = preg_replace('/!(.*)!([a-z]*)/', '$1', $match); - $regex_modifiers = preg_replace('/!(.*)!([a-z]*)/', '$2', $match); - - for ($i = 0, $size = strlen($regex_modifiers); $i < $size; ++$i) - { - if (strpos($modifiers, $regex_modifiers[$i]) === false) - { - $modifiers .= $regex_modifiers[$i]; - - if ($regex_modifiers[$i] == 'e') - { - $fp_replace = "'" . str_replace("'", "\\'", $fp_replace) . "'"; - } - } - - if ($regex_modifiers[$i] == 'e') - { - $replace = "'.$replace.'"; - } - } - - $fp_match = str_replace(preg_quote($token, '!'), $regex, $fp_match); - $fp_replace = str_replace($token, $replace, $fp_replace); - - $sp_match = str_replace(preg_quote($token, '!'), $sp_tokens[$token_type], $sp_match); - - // Prepend the board url to local relative links - $replace_prepend = ($token_type === 'LOCAL_URL') ? generate_board_url() . '/' : ''; - - $sp_replace = str_replace($token, $replace_prepend . '${' . ($n + 1) . '}', $sp_replace); - } - - $fp_match = '!' . $fp_match . '!' . $modifiers; - $sp_match = '!' . $sp_match . '!s' . (($utf8) ? 'u' : ''); - - if (strpos($fp_match, 'e') !== false) - { - $fp_replace = str_replace("'.'", '', $fp_replace); - $fp_replace = str_replace(".''.", '.', $fp_replace); - } - } - else - { - // No replacement is present, no need for a second-pass pattern replacement - // A simple str_replace will suffice - $fp_match = '!' . $fp_match . '!' . $modifiers; - $sp_match = $fp_replace; - $sp_replace = ''; - } - - // Lowercase tags $bbcode_tag = preg_replace('/.*?\[([a-z0-9_-]+).*/i', '$1', $bbcode_match); - $bbcode_search = preg_replace('/.*?\[([a-z0-9_-]+).*/i', '$1', $bbcode_match); if (!preg_match('/^[a-zA-Z0-9_-]+$/', $bbcode_tag)) { @@ -591,25 +468,13 @@ class acp_bbcodes trigger_error($user->lang['BBCODE_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); } - $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, - 'first_pass_match' => $fp_match, - 'first_pass_replace' => $fp_replace, - 'second_pass_match' => $sp_match, - 'second_pass_replace' => $sp_replace + 'first_pass_match' => '/(?!)/', + 'first_pass_replace' => '', + // Use a non-matching, valid regexp to effectively disable this BBCode + 'second_pass_match' => '/(?!)/', + 'second_pass_replace' => '' ); } } |