From 6317a7015272d770770c000c69271ff73cf55007 Mon Sep 17 00:00:00 2001 From: czaks Date: Sat, 15 Jun 2013 00:22:13 -0400 Subject: [PATCH 1/4] header abstraction: abstracted also in thread.html Conflicts: templates/page.html templates/thread.html --- templates/page.html | 2 +- templates/thread.html | 36 +++++------------------------------- 2 files changed, 6 insertions(+), 32 deletions(-) diff --git a/templates/page.html b/templates/page.html index a7c6a300..0d33c16f 100644 --- a/templates/page.html +++ b/templates/page.html @@ -22,4 +22,4 @@

Powered by Tinyboard {{ config.version }} | Tinyboard Copyright © 2010-2013 Tinyboard Development Group

- + \ No newline at end of file diff --git a/templates/thread.html b/templates/thread.html index 5882d9b6..a6b8793f 100644 --- a/templates/thread.html +++ b/templates/thread.html @@ -2,34 +2,8 @@ - - {% if config.url_favicon %}{% endif %} + {% include 'header.html' %} {{ board.url }} - {% if config.thread_subject_in_title and thread.subject %}{{ thread.subject }}{% else %}{{ board.title|e }}{% endif %} - - {% if config.meta_keywords %}{% endif %} - {% if config.default_stylesheet.1 != '' %}{% endif %} - {% if config.font_awesome %}{% endif %} - {% if not nojavascript %} - - {% if not config.additional_javascript_compile %} - {% for javascript in config.additional_javascript %}{% endfor %} - {% endif %} - {% endif %} - {% if config.recaptcha %}{% endif %} {{ boardlist.top }} @@ -44,11 +18,11 @@ {% if mod %}

{% trans %}Return to dashboard{% endtrans %}

{% endif %} - + - + {% include 'post_form.html' %} - + {% if config.blotter %}
{{ config.blotter }}
{% endif %}
@@ -68,4 +42,4 @@ ready(); {% endraw %} - + \ No newline at end of file From 4891735c49ee7879d0f299d03ebfbe361f3cc73d Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 18:29:09 -0400 Subject: [PATCH 2/4] Fix issue #72 --- inc/config.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/inc/config.php b/inc/config.php index 1fd00a3d..6f2371ec 100644 --- a/inc/config.php +++ b/inc/config.php @@ -381,10 +381,10 @@ */ // "Wiki" markup syntax ($config['wiki_markup'] in pervious versions): - $config['markup'][] = array("/'''(.+?)'''/", "\$1"); - $config['markup'][] = array("/''(.+?)''/", "\$1"); - $config['markup'][] = array("/\*\*(.+?)\*\*/", "\$1"); - $config['markup'][] = array("/^[ |\t]*==(.+?)==[ |\t]*$/m", "\$1"); + $config['markup'][] = array("/'''([^<]+?)'''/", "\$1"); + $config['markup'][] = array("/''([^<]+?)''/", "\$1"); + $config['markup'][] = array("/\*\*([^<]+?)\*\*/", "\$1"); + $config['markup'][] = array("/^[ |\t]*==([^<]+?)==[ |\t]*$/m", "\$1"); // Highlight PHP code wrapped in tags (PHP 5.3.0+) // $config['markup'][] = array( From 6d52c8b42813722c49890b6e4f776dc0dabf382c Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 18:59:54 -0400 Subject: [PATCH 3/4] Markup modifiers. Fix issue #66 (public ban message lost when rebuilding post body) --- inc/functions.php | 36 +++++++++++++++++++++++++++++++++++- inc/mod/pages.php | 10 ++++++++-- post.php | 3 ++- 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/inc/functions.php b/inc/functions.php index 7826d41b..e638f016 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1456,13 +1456,43 @@ function markup(&$body, $track_cites = false) { } } + if (preg_match_all('@<tinyboard ([\w\s]+)>(.+)</tinyboard>@', $body, $modifiers, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { + $skip_chars = 0; + $body_tmp = $body; + + foreach ($modifiers as $modifier) { + // preg_match_all is not multibyte-safe + foreach ($modifier as &$match) { + $match[1] = mb_strlen(substr($body_tmp, 0, $match[1])); + } + + $modifier['type'] = $modifier[1][0]; + $modifier['content'] = $modifier[2][0]; + + if ($modifier['type'] == 'ban message') { + // Public ban message + $replacement = sprintf($config['mod']['ban_message'], $modifier['content']); + } elseif (preg_match('/^escape /', $modifier['type'])) { + // Escaped (not a real modifier) + $replacement = '<tinyboard ' . substr($modifier['type'], strlen('escape ')) . '>' . $modifier['content'] . '</tinyboard>'; + } else { + // Unknown + $replacement = ''; + } + + $body = mb_substr_replace($body, $replacement, $modifier[0][1] + $skip_chars, mb_strlen($modifier[0][0])); + $skip_chars += mb_strlen($replacement) - mb_strlen($modifier[0][0]); + + } + } + // replace tabs with 8 spaces $body = str_replace("\t", ' ', $body); $tracked_cites = array(); // Cites - if (isset($board) && preg_match_all('/(^|\s)>>(\d+?)([\s,.)?]|$)/m', $body, $cites, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { + if (isset($board) && preg_match_all('/(^|\s)>>(\d+?)([\s,.)?]|$)/m', $body, $cites, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { if (count($cites[0]) > $config['max_cites']) { error($config['error']['toomanycites']); } @@ -1561,6 +1591,10 @@ function markup(&$body, $track_cites = false) { return $tracked_cites; } +function escape_markup_modifiers($string) { + return preg_replace('@(.+)@', '$2', $string); +} + function utf8tohtml($utf8) { return htmlspecialchars($utf8, ENT_NOQUOTES, 'UTF-8'); } diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 08604039..351d3203 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -507,6 +507,7 @@ function mod_noticeboard($page_no = 1) { if (!hasPermission($config['mod']['noticeboard_post'])) error($config['error']['noaccess']); + $_POST['body'] = escape_markup_modifiers($_POST['body']); markup($_POST['body']); $query = prepare('INSERT INTO `noticeboard` VALUES (NULL, :mod, :time, :subject, :body)'); @@ -568,6 +569,7 @@ function mod_news($page_no = 1) { if (!hasPermission($config['mod']['news'])) error($config['error']['noaccess']); + $_POST['body'] = escape_markup_modifiers($_POST['body']); markup($_POST['body']); $query = prepare('INSERT INTO `news` VALUES (NULL, :name, :time, :subject, :body)'); @@ -737,6 +739,7 @@ function mod_page_ip($ip) { if (!hasPermission($config['mod']['create_notes'])) error($config['error']['noaccess']); + $_POST['note'] = escape_markup_modifiers($_POST['note']); markup($_POST['note']); $query = prepare('INSERT INTO `ip_notes` VALUES (NULL, :ip, :mod, :time, :body)'); $query->bindValue(':ip', $ip); @@ -1214,12 +1217,14 @@ function mod_ban_post($board, $delete, $post, $token = false) { if (isset($_POST['public_message'], $_POST['message'])) { // public ban message $length_english = parse_time($_POST['length']) ? 'for ' . until(parse_time($_POST['length'])) : 'permanently'; + $_POST['message'] = preg_replace('/[\r\n]/', '', $_POST['message']); $_POST['message'] = str_replace('%length%', $length_english, $_POST['message']); $_POST['message'] = str_replace('%LENGTH%', strtoupper($length_english), $_POST['message']); - $query = prepare(sprintf('UPDATE `posts_%s` SET `body` = CONCAT(`body`, :body) WHERE `id` = :id', $board)); + $query = prepare(sprintf('UPDATE `posts_%s` SET `body_nomarkup` = CONCAT(`body_nomarkup`, :body_nomarkup) WHERE `id` = :id', $board)); $query->bindValue(':id', $post); - $query->bindValue(':body', sprintf($config['mod']['ban_message'], utf8tohtml($_POST['message']))); + $query->bindValue(':body_nomarkup', sprintf('%s', $_POST['message'])); $query->execute() or error(db_error($query)); + rebuildPost($post); modLog("Attached a public ban message to post #{$post}: " . utf8tohtml($_POST['message'])); buildThread($thread ? $thread : $post); @@ -1713,6 +1718,7 @@ function mod_new_pm($username) { } if (isset($_POST['message'])) { + $_POST['message'] = escape_markup_modifiers($_POST['message']); markup($_POST['message']); $query = prepare("INSERT INTO `pms` VALUES (NULL, :me, :id, :message, :time, 1)"); diff --git a/post.php b/post.php index 8820db2d..adb44b58 100644 --- a/post.php +++ b/post.php @@ -107,7 +107,7 @@ if (isset($_POST['delete'])) { if (count($report) > $config['report_limit']) error($config['error']['toomanyreports']); - $reason = &$_POST['reason']; + $reason = escape_markup_modifiers($_POST['reason']); markup($reason); foreach ($report as &$id) { @@ -377,6 +377,7 @@ if (isset($_POST['delete'])) { error(sprintf($config['error']['toolong'], 'password')); wordfilters($post['body']); + $post['body'] = escape_markup_modifiers($post['body']); if (mysql_version() >= 50503) { $post['body_nomarkup'] = $post['body']; // Assume we're using the utf8mb4 charset From 6bbe407e18681f2812db4345036bb5ae639f5973 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Wed, 31 Jul 2013 19:18:55 -0400 Subject: [PATCH 4/4] Markup modifiers: raw HTML --- inc/functions.php | 65 +++++++++++++++++++++++++---------------------- post.php | 7 +++-- 2 files changed, 39 insertions(+), 33 deletions(-) diff --git a/inc/functions.php b/inc/functions.php index e638f016..7cde156b 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1421,6 +1421,39 @@ function markup(&$body, $track_cites = false) { $body = str_replace("\r", '', $body); $body = utf8tohtml($body); + if (preg_match_all('@<tinyboard ([\w\s]+)>(.+)</tinyboard>@um', $body, $modifiers, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { + $skip_chars = 0; + $body_tmp = $body; + + foreach ($modifiers as $modifier) { + // preg_match_all is not multibyte-safe + foreach ($modifier as &$match) { + $match[1] = mb_strlen(substr($body_tmp, 0, $match[1])); + } + + $modifier['type'] = $modifier[1][0]; + $modifier['content'] = $modifier[2][0]; + + if ($modifier['type'] == 'ban message') { + // Public ban message + $replacement = sprintf($config['mod']['ban_message'], $modifier['content']); + } elseif ($modifier['type'] == 'raw html') { + $body = html_entity_decode($modifier['content']); + return array(); + } elseif (preg_match('/^escape /', $modifier['type'])) { + // Escaped (not a real modifier) + $replacement = '<tinyboard ' . substr($modifier['type'], strlen('escape ')) . '>' . $modifier['content'] . '</tinyboard>'; + } else { + // Unknown + $replacement = ''; + } + + $body = mb_substr_replace($body, $replacement, $modifier[0][1] + $skip_chars, mb_strlen($modifier[0][0])); + $skip_chars += mb_strlen($replacement) - mb_strlen($modifier[0][0]); + + } + } + if (mysql_version() < 50503) $body = mb_encode_numericentity($body, array(0x010000, 0xffffff, 0, 0xffffff), 'UTF-8'); @@ -1456,36 +1489,6 @@ function markup(&$body, $track_cites = false) { } } - if (preg_match_all('@<tinyboard ([\w\s]+)>(.+)</tinyboard>@', $body, $modifiers, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { - $skip_chars = 0; - $body_tmp = $body; - - foreach ($modifiers as $modifier) { - // preg_match_all is not multibyte-safe - foreach ($modifier as &$match) { - $match[1] = mb_strlen(substr($body_tmp, 0, $match[1])); - } - - $modifier['type'] = $modifier[1][0]; - $modifier['content'] = $modifier[2][0]; - - if ($modifier['type'] == 'ban message') { - // Public ban message - $replacement = sprintf($config['mod']['ban_message'], $modifier['content']); - } elseif (preg_match('/^escape /', $modifier['type'])) { - // Escaped (not a real modifier) - $replacement = '<tinyboard ' . substr($modifier['type'], strlen('escape ')) . '>' . $modifier['content'] . '</tinyboard>'; - } else { - // Unknown - $replacement = ''; - } - - $body = mb_substr_replace($body, $replacement, $modifier[0][1] + $skip_chars, mb_strlen($modifier[0][0])); - $skip_chars += mb_strlen($replacement) - mb_strlen($modifier[0][0]); - - } - } - // replace tabs with 8 spaces $body = str_replace("\t", ' ', $body); @@ -1592,7 +1595,7 @@ function markup(&$body, $track_cites = false) { } function escape_markup_modifiers($string) { - return preg_replace('@(.+)@', '$2', $string); + return preg_replace('@(.+)@m', '$2', $string); } function utf8tohtml($utf8) { diff --git a/post.php b/post.php index adb44b58..db077866 100644 --- a/post.php +++ b/post.php @@ -379,6 +379,10 @@ if (isset($_POST['delete'])) { wordfilters($post['body']); $post['body'] = escape_markup_modifiers($post['body']); + if ($mod && isset($post['raw']) && $post['raw']) { + $post['body'] = '' . $post['body'] . ''; + } + if (mysql_version() >= 50503) { $post['body_nomarkup'] = $post['body']; // Assume we're using the utf8mb4 charset } else { @@ -396,8 +400,7 @@ if (isset($_POST['delete'])) { } } - if (!($mod && isset($post['raw']) && $post['raw'])) - $post['tracked_cites'] = markup($post['body'], true); + $post['tracked_cites'] = markup($post['body'], true); // Check for a flood if (!hasPermission($config['mod']['flood'], $board['uri']) && checkFlood($post)) {