diff options
| author | Nils Adermann <naderman@naderman.de> | 2010-03-02 01:05:34 +0100 |
|---|---|---|
| committer | Nils Adermann <naderman@naderman.de> | 2010-03-02 01:05:34 +0100 |
| commit | 07633a66e8c9bbb2b288a286bfbea6f562eeca4d (patch) | |
| tree | a255efa70ed6f202542649148c0445445504d181 /phpBB/includes/message_parser.php | |
| parent | ee82970d96e0a6772b24c48aab8ebd1888ec5216 (diff) | |
| parent | 5cfa0ec0c32ddc424f9651d8766db3e4ced59f96 (diff) | |
| download | forums-07633a66e8c9bbb2b288a286bfbea6f562eeca4d.tar forums-07633a66e8c9bbb2b288a286bfbea6f562eeca4d.tar.gz forums-07633a66e8c9bbb2b288a286bfbea6f562eeca4d.tar.bz2 forums-07633a66e8c9bbb2b288a286bfbea6f562eeca4d.tar.xz forums-07633a66e8c9bbb2b288a286bfbea6f562eeca4d.zip | |
Merge commit 'release-3.0-B3'
Diffstat (limited to 'phpBB/includes/message_parser.php')
| -rw-r--r-- | phpBB/includes/message_parser.php | 263 |
1 files changed, 145 insertions, 118 deletions
diff --git a/phpBB/includes/message_parser.php b/phpBB/includes/message_parser.php index 6aa78d091f..6538bd7721 100644 --- a/phpBB/includes/message_parser.php +++ b/phpBB/includes/message_parser.php @@ -47,7 +47,6 @@ class bbcode_firstpass extends bbcode $this->bbcode_bitfield = ''; $bitfield = new bitfield(); - $size = strlen($this->message); foreach ($this->bbcodes as $bbcode_name => $bbcode_data) { if (isset($bbcode_data['disabled']) && $bbcode_data['disabled']) @@ -65,18 +64,15 @@ class bbcode_firstpass extends bbcode { foreach ($bbcode_data['regexp'] as $regexp => $replacement) { - $this->message = preg_replace($regexp, $replacement, $this->message); + // The pattern gets compiled and cached by the PCRE extension, + // it should not demand recompilation + if (preg_match($regexp, $this->message)) + { + $this->message = preg_replace($regexp, $replacement, $this->message); + $bitfield->set($bbcode_data['bbcode_id']); + } } } - - // Because 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) - { - $bitfield->set($bbcode_data['bbcode_id']); - $size = $new_size; - } } $this->bbcode_bitfield = $bitfield->get_base64(); @@ -368,15 +364,11 @@ class bbcode_firstpass extends bbcode // We remove the hardcoded elements from the code block here because it is not used in code blocks // Having it here saves us one preg_replace per message containing [code] blocks // Additionally, magic url parsing should go after parsing bbcodes, but for safety those are stripped out too... - $htm_match = array( - '#<!\-\- e \-\-><a href="mailto:(.*?)">.*?</a><!\-\- e \-\->#', - '#<!\-\- m \-\-><a href="(.*?)" target="_blank">.*?</a><!\-\- m \-\->#', - '#<!\-\- w \-\-><a href="http:\/\/(.*?)" target="_blank">.*?</a><!\-\- w \-\->#', - '#<!\-\- l \-\-><a href="(.*?)">.*?</a><!\-\- l \-\->#', - '#<!\-\- s(.*?) \-\-><img src="\{SMILIES_PATH\}\/.*? \/><!\-\- s\1 \-\->#', - '#&\#([0-9]+);#', - ); - $htm_replace = array('\1', '\1', '\1', '\1', '\1', '&#\1;'); + $htm_match = get_preg_expression('bbcode_htm'); +// $htm_match[3] = '/&#([0-9]+);/'; + unset($htm_match[3], $htm_match[4]); + + $htm_replace = array('\1', '\2', '\1'); //, '&#\1;'); $out = ''; @@ -427,7 +419,7 @@ class bbcode_firstpass extends bbcode } // Because highlight_string is specialcharing the text (but we already did this before), we have to reverse this in order to get correct results - $code = html_entity_decode($code); + $code = htmlspecialchars_decode($code); $code = highlight_string($code, true); $str_from = array('<span style="color: ', '<font color="syntax', '</font>', '<code>', '</code>','[', ']', '.', ':'); @@ -507,13 +499,15 @@ class bbcode_firstpass extends bbcode $tok = ']'; $out = '['; + // First character is [ $in = substr($in, 1); $list_end_tags = array(); do { $pos = strlen($in); - for ($i = 0; $i < strlen($tok); ++$i) + + for ($i = 0, $tok_len = strlen($tok); $i < $tok_len; ++$i) { $tmp_pos = strpos($in, $tok{$i}); @@ -531,7 +525,7 @@ class bbcode_firstpass extends bbcode if ($tok == ']') { // if $tok is ']' the buffer holds a tag - if ($buffer == '/list' && sizeof($list_end_tags)) + if (strtolower($buffer) == '/list' && sizeof($list_end_tags)) { $out .= array_pop($list_end_tags) . ']'; $tok = '['; @@ -547,6 +541,12 @@ class bbcode_firstpass extends bbcode { array_push($list_end_tags, '/list:o:' . $this->bbcode_uid); } + + if (strtolower(substr($buffer, 0, 4)) == 'list') + { + $buffer = 'list' . substr($buffer, 4, $pos); + } + $out .= $buffer . ':' . $this->bbcode_uid . ']'; $tok = '['; } @@ -598,7 +598,7 @@ class bbcode_firstpass extends bbcode do { $pos = strlen($in); - for ($i = 0; $i < strlen($tok); ++$i) + for ($i = 0, $tok_len = strlen($tok); $i < $tok_len; ++$i) { $tmp_pos = strpos($in, $tok{$i}); if ($tmp_pos !== false && $tmp_pos < $pos) @@ -649,7 +649,7 @@ class bbcode_firstpass extends bbcode preg_match_all('#\[((?:/)?(?:[a-z]+))#i', $username, $tags); foreach ($tags[1] as $tag) { - if ($tag{0} != '/') + if ($tag[0] != '/') { $end_tags[] = '/' . $tag; } @@ -807,7 +807,7 @@ class bbcode_firstpass extends bbcode * @param string $url the url to check * @return true if the url is pointing to this domain/script_path/php-file, false if not * - * @access: private + * @access private */ function path_in_domain($url) { @@ -857,6 +857,7 @@ class parse_message extends bbcode_firstpass var $allow_img_bbcode = true; var $allow_flash_bbcode = true; var $allow_quote_bbcode = true; + var $allow_url_bbcode = true; var $mode; @@ -877,7 +878,7 @@ class parse_message extends bbcode_firstpass /** * Parse Message */ - function parse($allow_bbcode, $allow_magic_url, $allow_smilies, $allow_img_bbcode = true, $allow_flash_bbcode = true, $allow_quote_bbcode = true, $update_this_message = true, $mode = 'post') + function parse($allow_bbcode, $allow_magic_url, $allow_smilies, $allow_img_bbcode = true, $allow_flash_bbcode = true, $allow_quote_bbcode = true, $allow_url_bbcode = true, $update_this_message = true, $mode = 'post') { global $config, $db, $user; @@ -888,6 +889,7 @@ class parse_message extends bbcode_firstpass $this->allow_img_bbcode = $allow_img_bbcode; $this->allow_flash_bbcode = $allow_flash_bbcode; $this->allow_quote_bbcode = $allow_quote_bbcode; + $this->allow_url_bbcode = $allow_url_bbcode; // If false, then $this->message won't be altered, the text will be returned instead. if (!$update_this_message) @@ -911,7 +913,7 @@ class parse_message extends bbcode_firstpass // Message length check. -1 disables this check completely. if ($config['max_' . $mode . '_chars'] != -1) { - $msg_len = ($mode == 'post') ? strlen($this->message) : strlen(preg_replace('#\[\/?[a-z\*\+\-]+(=[\S]+)?\]#is', ' ', $this->message)); + $msg_len = ($mode == 'post') ? utf8_strlen($this->message) : utf8_strlen(preg_replace('#\[\/?[a-z\*\+\-]+(=[\S]+)?\]#is', ' ', $this->message)); if ((!$msg_len && $mode !== 'sig') || $config['max_' . $mode . '_chars'] && $msg_len > $config['max_' . $mode . '_chars']) { @@ -924,7 +926,7 @@ class parse_message extends bbcode_firstpass if ($allow_bbcode && strpos($this->message, '[') !== false) { $this->bbcode_init(); - $disallow = array('img', 'flash', 'quote'); + $disallow = array('img', 'flash', 'quote', 'url'); foreach ($disallow as $bool) { if (!${'allow_' . $bool . '_bbcode'}) @@ -995,7 +997,7 @@ class parse_message extends bbcode_firstpass if ($this->message_status == 'plain') { // Force updating message - of course. - $this->parse($allow_bbcode, $allow_magic_url, $allow_smilies, $this->allow_img_bbcode, $this->allow_flash_bbcode, $this->allow_quote_bbcode, true); + $this->parse($allow_bbcode, $allow_magic_url, $allow_smilies, $this->allow_img_bbcode, $this->allow_flash_bbcode, $this->allow_quote_bbcode, $this->allow_url_bbcode, true); } // Parse BBcode @@ -1076,7 +1078,7 @@ class parse_message extends bbcode_firstpass // NOTE: obtain_* function? chaching the table contents? // For now setting the ttl to 10 minutes - switch (SQL_LAYER) + switch ($db->sql_layer) { case 'mssql': case 'mssql_odbc': @@ -1088,7 +1090,7 @@ class parse_message extends bbcode_firstpass case 'firebird': $sql = 'SELECT * FROM ' . SMILIES_TABLE . ' - ORDER BY STRLEN(code) DESC'; + ORDER BY CHAR_LENGTH(code) DESC'; break; // LENGTH supported by MySQL, IBM DB2, Oracle and Access for sure... @@ -1104,7 +1106,7 @@ class parse_message extends bbcode_firstpass { // (assertion) $match[] = '#(?<=^|[\n ]|\.)' . preg_quote($row['code'], '#') . '#'; - $replace[] = '<!-- s' . $row['code'] . ' --><img src="{SMILIES_PATH}/' . $row['smiley_url'] . '" border="0" alt="' . $row['emotion'] . '" title="' . $row['emotion'] . '" /><!-- s' . $row['code'] . ' -->'; + $replace[] = '<!-- s' . $row['code'] . ' --><img src="{SMILIES_PATH}/' . $row['smiley_url'] . '" alt="' . $row['emotion'] . '" title="' . $row['emotion'] . '" /><!-- s' . $row['code'] . ' -->'; } $db->sql_freeresult($result); } @@ -1131,12 +1133,13 @@ class parse_message extends bbcode_firstpass */ function parse_attachments($form_name, $mode, $forum_id, $submit, $preview, $refresh, $is_message = false) { - global $config, $auth, $user, $phpbb_root_path, $phpEx; + global $config, $auth, $user, $phpbb_root_path, $phpEx, $db; $error = array(); $num_attachments = sizeof($this->attachment_data); $this->filename_data['filecomment'] = request_var('filecomment', '', true); + utf8_normalize_nfc(&$this->filename_data['filecomment']); $upload_file = (isset($_FILES[$form_name]) && $_FILES[$form_name]['name'] != 'none' && trim($_FILES[$form_name]['name'])) ? true : false; $add_file = (isset($_POST['add_file'])) ? true : false; @@ -1156,7 +1159,7 @@ class parse_message extends bbcode_firstpass if ($filedata['post_attach'] && !sizeof($error)) { - $new_entry = array( + $sql_ary = array( 'physical_filename' => $filedata['physical_filename'], 'attach_comment' => $this->filename_data['filecomment'], 'real_filename' => $filedata['real_filename'], @@ -1164,8 +1167,19 @@ class parse_message extends bbcode_firstpass 'mimetype' => $filedata['mimetype'], 'filesize' => $filedata['filesize'], 'filetime' => $filedata['filetime'], - 'attach_id' => 0, - 'thumbnail' => $filedata['thumbnail'] + 'thumbnail' => $filedata['thumbnail'], + 'is_orphan' => 1, + 'in_message' => ($is_message) ? 1 : 0, + 'poster_id' => $user->data['user_id'], + ); + + $db->sql_query('INSERT INTO ' . ATTACHMENTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary)); + + $new_entry = array( + 'attach_id' => $db->sql_nextid(), + 'is_orphan' => 1, + 'real_filename' => $filedata['real_filename'], + 'attach_comment'=> $this->filename_data['filecomment'], ); $this->attachment_data = array_merge(array(0 => $new_entry), $this->attachment_data); @@ -1199,32 +1213,51 @@ class parse_message extends bbcode_firstpass $index = (int) key($_POST['delete_file']); - // delete selected attachment - if (!$this->attachment_data[$index]['attach_id']) + if (!empty($this->attachment_data[$index])) { - phpbb_unlink($this->attachment_data[$index]['physical_filename'], 'file'); - if ($this->attachment_data[$index]['thumbnail']) + // delete selected attachment + if ($this->attachment_data[$index]['is_orphan']) { - phpbb_unlink($this->attachment_data[$index]['physical_filename'], 'thumbnail'); + $sql = 'SELECT attach_id, physical_filename, thumbnail + FROM ' . ATTACHMENTS_TABLE . ' + WHERE attach_id = ' . (int) $this->attachment_data[$index]['attach_id'] . ' + AND is_orphan = 1 + AND poster_id = ' . $user->data['user_id']; + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + if ($row) + { + phpbb_unlink($row['physical_filename'], 'file'); + + if ($row['thumbnail']) + { + phpbb_unlink($row['physical_filename'], 'thumbnail'); + } + + $db->sql_query('DELETE FROM ' . ATTACHMENTS_TABLE . ' WHERE attach_id = ' . (int) $this->attachment_data[$index]['attach_id']); + } + } + else + { + delete_attachments('attach', array(intval($this->attachment_data[$index]['attach_id']))); } - } - else - { - delete_attachments('attach', array(intval($this->attachment_data[$index]['attach_id']))); - } - 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); + 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); - // Reindex Array - $this->attachment_data = array_values($this->attachment_data); + // Reindex Array + $this->attachment_data = array_values($this->attachment_data); + } } else if ($edit_comment || $add_file || $preview) { if ($edit_comment) { $actual_comment_list = request_var('comment_list', array(''), true); + utf8_normalize_nfc(&$actual_comment_list); $edit_comment = request_var('edit_comment', array(0 => '')); $edit_comment = key($edit_comment); @@ -1233,14 +1266,14 @@ class parse_message extends bbcode_firstpass if (($add_file || $preview) && $upload_file) { - if ($num_attachments < $cfg['max_attachments'] || $auth->acl_gets('m_', 'a_')) + if ($num_attachments < $cfg['max_attachments'] || $auth->acl_gets('m_', 'a_', $forum_id)) { $filedata = upload_attachment($form_name, $forum_id, false, '', $is_message); $error = array_merge($error, $filedata['error']); if (!sizeof($error)) { - $new_entry = array( + $sql_ary = array( 'physical_filename' => $filedata['physical_filename'], 'attach_comment' => $this->filename_data['filecomment'], 'real_filename' => $filedata['real_filename'], @@ -1248,8 +1281,19 @@ class parse_message extends bbcode_firstpass 'mimetype' => $filedata['mimetype'], 'filesize' => $filedata['filesize'], 'filetime' => $filedata['filetime'], - 'attach_id' => 0, - 'thumbnail' => $filedata['thumbnail'] + 'thumbnail' => $filedata['thumbnail'], + 'is_orphan' => 1, + 'in_message' => ($is_message) ? 1 : 0, + 'poster_id' => $user->data['user_id'], + ); + + $db->sql_query('INSERT INTO ' . ATTACHMENTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary)); + + $new_entry = array( + 'attach_id' => $db->sql_nextid(), + 'is_orphan' => 1, + 'real_filename' => $filedata['real_filename'], + 'attach_comment'=> $this->filename_data['filecomment'], ); $this->attachment_data = array_merge(array(0 => $new_entry), $this->attachment_data); @@ -1279,99 +1323,84 @@ class parse_message extends bbcode_firstpass global $user, $db, $phpbb_root_path, $phpEx, $config; $this->filename_data['filecomment'] = request_var('filecomment', '', true); - $this->attachment_data = (isset($_POST['attachment_data'])) ? $_POST['attachment_data'] : array(); + utf8_normalize_nfc(&$this->filename_data['filecomment']); + $attachment_data = (isset($_POST['attachment_data'])) ? $_POST['attachment_data'] : array(); + $this->attachment_data = array(); $check_user_id = ($check_user_id === false) ? $user->data['user_id'] : $check_user_id; - // Regenerate data array... - $attach_ids = $filenames = array(); + if (!sizeof($attachment_data)) + { + return; + } - foreach ($this->attachment_data as $pos => $var_ary) + $not_orphan = $orphan = array(); + + foreach ($attachment_data as $pos => $var_ary) { - if ($var_ary['attach_id']) + if ($var_ary['is_orphan']) { - $attach_ids[(int) $this->attachment_data[$pos]['attach_id']] = $pos; + $orphan[(int) $var_ary['attach_id']] = $pos; } else { - $filenames[$pos] = ''; - set_var($filenames[$pos], $this->attachment_data[$pos]['physical_filename'], 'string'); - $filenames[$pos] = basename($filenames[$pos]); + $not_orphan[(int) $var_ary['attach_id']] = $pos; } } - $this->attachment_data = array(); - - // Regenerate already posted attachments... - if (sizeof($attach_ids)) + // Regenerate already posted attachments + if (sizeof($not_orphan)) { - // Get the data from the attachments - $sql = 'SELECT attach_id, physical_filename, real_filename, extension, mimetype, filesize, filetime, thumbnail + // Get the attachment data, based on the poster id... + $sql = 'SELECT attach_id, is_orphan, real_filename, attach_comment FROM ' . ATTACHMENTS_TABLE . ' - WHERE ' . $db->sql_in_set('attach_id', array_keys($attach_ids)) . ' + WHERE ' . $db->sql_in_set('attach_id', array_keys($not_orphan)) . ' AND poster_id = ' . $check_user_id; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { - if (isset($attach_ids[$row['attach_id']])) - { - $pos = $attach_ids[$row['attach_id']]; - $this->attachment_data[$pos] = $row; - set_var($this->attachment_data[$pos]['attach_comment'], $_POST['attachment_data'][$pos]['attach_comment'], 'string', true); + $pos = $not_orphan[$row['attach_id']]; + $this->attachment_data[$pos] = $row; + set_var($this->attachment_data[$pos]['attach_comment'], $_POST['attachment_data'][$pos]['attach_comment'], 'string', true); - unset($attach_ids[$row['attach_id']]); - } + unset($not_orphan[$row['attach_id']]); } $db->sql_freeresult($result); + } - if (sizeof($attach_ids)) - { - trigger_error($user->lang['NO_ACCESS_ATTACHMENT'], E_USER_ERROR); - } + if (sizeof($not_orphan)) + { + trigger_error($user->lang['NO_ACCESS_ATTACHMENT'], E_USER_ERROR); } // Regenerate newly uploaded attachments - if (sizeof($filenames)) + if (sizeof($orphan)) { - include_once($phpbb_root_path . 'includes/functions_upload.' . $phpEx); - - $sql = 'SELECT attach_id + $sql = 'SELECT attach_id, is_orphan, real_filename, attach_comment FROM ' . ATTACHMENTS_TABLE . ' - WHERE ' . $db->sql_in_set('LOWER(physical_filename)', array_map('strtolower', $filenames)); - $result = $db->sql_query_limit($sql, 1); - $row = $db->sql_fetchrow($result); - $db->sql_freeresult($result); - - if ($row) - { - trigger_error($user->lang['NO_ACCESS_ATTACHMENT'], E_USER_ERROR); - } + WHERE ' . $db->sql_in_set('attach_id', array_keys($orphan)) . ' + AND poster_id = ' . $user->data['user_id'] . ' + AND is_orphan = 1'; + $result = $db->sql_query($sql); - foreach ($filenames as $pos => $physical_filename) + while ($row = $db->sql_fetchrow($result)) { - $this->attachment_data[$pos] = array( - 'physical_filename' => $physical_filename, - 'extension' => strtolower(filespec::get_extension($phpbb_root_path . $config['upload_path'] . '/' . $physical_filename)), - 'filesize' => filespec::get_filesize($phpbb_root_path . $config['upload_path'] . '/' . $physical_filename), - 'attach_id' => 0, - 'thumbnail' => (file_exists($phpbb_root_path . $config['upload_path'] . '/thumb_' . $physical_filename)) ? 1 : 0, - ); - + $pos = $orphan[$row['attach_id']]; + $this->attachment_data[$pos] = $row; set_var($this->attachment_data[$pos]['attach_comment'], $_POST['attachment_data'][$pos]['attach_comment'], 'string', true); - set_var($this->attachment_data[$pos]['real_filename'], $_POST['attachment_data'][$pos]['real_filename'], 'string', true); - set_var($this->attachment_data[$pos]['filetime'], $_POST['attachment_data'][$pos]['filetime'], 'int'); - if (strpos($_POST['attachment_data'][$pos]['mimetype'], 'image/') !== false) - { - set_var($this->attachment_data[$pos]['mimetype'], $_POST['attachment_data'][$pos]['mimetype'], 'string'); - } - else - { - $this->attachment_data[$pos]['mimetype'] = filespec::get_mimetype($phpbb_root_path . $config['upload_path'] . '/' . $physical_filename); - } + unset($orphan[$row['attach_id']]); } + $db->sql_freeresult($result); + } + + if (sizeof($orphan)) + { + trigger_error($user->lang['NO_ACCESS_ATTACHMENT'], E_USER_ERROR); } + + ksort($this->attachment_data); } /** @@ -1388,8 +1417,7 @@ class parse_message extends bbcode_firstpass $this->message = $poll['poll_option_text']; - $poll['poll_option_text'] = $this->parse($poll['enable_bbcode'], $poll['enable_urls'], $poll['enable_smilies'], $poll['img_status'], false, false, false); - + $poll['poll_option_text'] = $this->parse($poll['enable_bbcode'], ($config['allow_post_links']) ? $poll['enable_urls'] : false, $poll['enable_smilies'], $poll['img_status'], false, false, $config['allow_post_links'], false); $this->message = $tmp_message; @@ -1398,8 +1426,7 @@ class parse_message extends bbcode_firstpass $this->message = $poll['poll_title']; - $poll['poll_title'] = $this->parse($poll['enable_bbcode'], $poll['enable_urls'], $poll['enable_smilies'], $poll['img_status'], false, false, false); - + $poll['poll_title'] = $this->parse($poll['enable_bbcode'], ($config['allow_post_links']) ? $poll['enable_urls'] : false, $poll['enable_smilies'], $poll['img_status'], false, false, $config['allow_post_links'], false); $this->message = $tmp_message; |
