From 82e3592703f50869d589839f7d4d1bf763852b51 Mon Sep 17 00:00:00 2001 From: Macil Tech Date: Tue, 25 Jun 2013 12:13:17 -0500 Subject: [PATCH 01/11] Argh, just remove all RTL and LTR control codes in bidi_cleanup. If the name and subject fields both start with RLO characters, then the subject would be after the name with the old bidi_cleanup. --- inc/display.php | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/inc/display.php b/inc/display.php index 5395edcc..2021dc8f 100644 --- a/inc/display.php +++ b/inc/display.php @@ -214,7 +214,7 @@ function truncate($body, $url, $max_lines = false, $max_chars = false) { } function bidi_cleanup($str){ - # Closes all embedded RTL and LTR unicode formatting blocks in a string so that + # Removes all embedded RTL and LTR unicode formatting blocks in a string so that # it can be used inside another without controlling its direction. # More info: http://www.iamcal.com/understanding-bidirectional-text/ # @@ -228,21 +228,7 @@ function bidi_cleanup($str){ $explicits = '\xE2\x80\xAA|\xE2\x80\xAB|\xE2\x80\xAD|\xE2\x80\xAE'; $pdf = '\xE2\x80\xAC'; - $stack = 0; - $str = preg_replace_callback("!(?$explicits)|(?$pdf)!", function($match) use (&$stack) { - if (isset($match['explicits']) && $match['explicits']) { - $stack++; - } else { - if ($stack) - $stack--; - else - return ''; - } - return $match[0]; - }, $str); - for ($i=0; $i<$stack; $i++){ - $str .= "\xE2\x80\xAC"; - } + $str = preg_replace("!(?$explicits)|(?$pdf)!", '', $str); return $str; } From 230b5de16ed0e50843136efffdef85e7df8c91b1 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Mon, 15 Jul 2013 08:17:49 -0400 Subject: [PATCH 02/11] Bug fix: Error when using anonymous functions for mod pages --- mod.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mod.php b/mod.php index eb99c0fb..42196ef2 100644 --- a/mod.php +++ b/mod.php @@ -103,7 +103,7 @@ if (isset($config['mod']['custom_pages'])) { $new_pages = array(); foreach ($pages as $key => $callback) { - if (preg_match('/^secure /', $callback)) + if (is_string($callback) && preg_match('/^secure /', $callback)) $key .= '(/(?P[a-f0-9]{8}))?'; $new_pages[@$key[0] == '!' ? $key : '!^' . $key . '(?:&[^&=]+=[^&]*)*$!'] = $callback; } @@ -113,7 +113,7 @@ foreach ($pages as $uri => $handler) { if (preg_match($uri, $query, $matches)) { $matches = array_slice($matches, 1); - if (preg_match('/^secure(_POST)? /', $handler, $m)) { + if (is_string($handler) && preg_match('/^secure(_POST)? /', $handler, $m)) { $secure_post_only = isset($m[1]); if (!$secure_post_only || $_SERVER['REQUEST_METHOD'] == 'POST') { $token = isset($matches['token']) ? $matches['token'] : (isset($_POST['token']) ? $_POST['token'] : false); From 34dc31c50e89b38e9489826661edb3f0fffd23ea Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Tue, 16 Jul 2013 01:14:42 -0400 Subject: [PATCH 03/11] Remove search section from dashboard as it is currently nonexistent in the latest version. --- templates/mod/dashboard.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/templates/mod/dashboard.html b/templates/mod/dashboard.html index 2f0b03ad..e54b3cd3 100644 --- a/templates/mod/dashboard.html +++ b/templates/mod/dashboard.html @@ -101,6 +101,7 @@ +{#
{% trans 'Search' %} @@ -115,6 +116,7 @@
+#} {% if config.debug %}
From 77e4d926d9992dd56e1ab3c3af29ffd4bea92b59 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Tue, 16 Jul 2013 01:21:06 -0400 Subject: [PATCH 04/11] Add "write" (files written to) to debug section --- inc/functions.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/inc/functions.php b/inc/functions.php index 70848468..67019e0a 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -78,7 +78,7 @@ function loadConfig() { if ($config['debug']) { if (!isset($debug)) { - $debug = array('sql' => array(), 'purge' => array(), 'cached' => array()); + $debug = array('sql' => array(), 'purge' => array(), 'cached' => array(), 'write' => array()); $debug['start'] = microtime(true); } } @@ -392,7 +392,7 @@ function purge($uri) { } function file_write($path, $data, $simple = false, $skip_purge = false) { - global $config; + global $config, $debug; if (preg_match('/^remote:\/\/(.+)\:(.+)$/', $path, $m)) { if (isset($config['remote'][$m[1]])) { @@ -419,7 +419,7 @@ function file_write($path, $data, $simple = false, $skip_purge = false) { error('Unable to truncate file: ' . $path); // Write data - if (fwrite($fp, $data) === false) + if (($bytes = fwrite($fp, $data)) === false) error('Unable to write to file: ' . $path); // Unlock @@ -445,6 +445,10 @@ function file_write($path, $data, $simple = false, $skip_purge = false) { purge($path); } + if ($config['debug']) { + $debug['write'][] = $path . ': ' . $bytes . ' bytes'; + } + event('write', $path); } From c2dc25ac51d76c104e8a0cd3b8540886218f13ab Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Tue, 16 Jul 2013 01:34:36 -0400 Subject: [PATCH 05/11] incrementSpamHash() was duplicated for some reason --- post.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/post.php b/post.php index f236e929..3d718786 100644 --- a/post.php +++ b/post.php @@ -627,10 +627,6 @@ if (isset($_POST['delete'])) { incrementSpamHash($post['antispam_hash']); } - if (isset($post['antispam_hash'])) { - incrementSpamHash($post['antispam_hash']); - } - if (isset($post['tracked_cites'])) { foreach ($post['tracked_cites'] as $cite) { $query = prepare('INSERT INTO `cites` VALUES (:board, :post, :target_board, :target)'); From 23b27d805740599b968d41e08d726f2a0dc5bdde Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Tue, 16 Jul 2013 01:38:24 -0400 Subject: [PATCH 06/11] Add clean() to mod_move function --- inc/mod/pages.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 86f5ee52..fddf63c7 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -906,8 +906,10 @@ function mod_move($originBoard, $postID) { modLog("Moved thread #${postID} to " . sprintf($config['board_abbreviation'], $targetBoard) . " (#${newID})", $originBoard); - // build new hread + // build new thread buildThread($newID); + + clean(); buildIndex(); // trigger themes From 2144d43f2b114ac697d57d23300f51bf7d078b3b Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Tue, 16 Jul 2013 02:27:20 -0400 Subject: [PATCH 07/11] Fix issue #24 --- inc/mod/pages.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/inc/mod/pages.php b/inc/mod/pages.php index fddf63c7..899f2611 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -217,6 +217,19 @@ function mod_edit_board($boardName) { $query = prepare('DELETE FROM `antispam` WHERE `board` = :board'); $query->bindValue(':board', $board['uri']); $query->execute() or error(db_error($query)); + + // Remove board from users/permissions table + $query = query('SELECT `id`,`boards` FROM `mods`') or error(db_error()); + while ($user = $query->fetch(PDO::FETCH_ASSOC)) { + $user_boards = explode(',', $user['boards']); + if (in_array($board['uri'], $user_boards)) { + unset($user_boards[array_search($board['uri'], $user_boards)]); + $_query = prepare('UPDATE `mods` SET `boards` = :boards WHERE `id` = :id'); + $_query->bindValue(':boards', implode(',', $user_boards)); + $_query->bindValue(':id', $user['id']); + $_query->execute() or error(db_error($_query)); + } + } } else { $query = prepare('UPDATE `boards` SET `title` = :title, `subtitle` = :subtitle WHERE `uri` = :uri'); $query->bindValue(':uri', $board['uri']); From 7302fc57a8f83c6fe40f9c751259d9c616ebdaec Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Tue, 16 Jul 2013 02:32:44 -0400 Subject: [PATCH 08/11] Automatically dismiss all reports regarding a thread after it is locked. --- inc/config.php | 3 +++ inc/mod/pages.php | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/inc/config.php b/inc/config.php index da9309e8..83b98c2b 100644 --- a/inc/config.php +++ b/inc/config.php @@ -881,6 +881,9 @@ // Edit raw HTML in posts by default $config['mod']['raw_html_default'] = false; + // Automatically dismiss all reports regarding a thread when it is locked + $config['mod']['dismiss_reports_on_lock'] = true; + // Probably best not to change these: if (!defined('JANITOR')) { define('JANITOR', 0, true); diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 899f2611..3f823d3d 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -738,6 +738,13 @@ function mod_lock($board, $unlock, $post) { buildIndex(); } + if ($config['mod']['dismiss_reports_on_lock']) { + $query = prepare('DELETE FROM `reports` WHERE `board` = :board AND `post` = :id'); + $query->bindValue(':board', $board); + $query->bindValue(':id', $post); + $query->execute() or error(db_error($query)); + } + header('Location: ?/' . sprintf($config['board_path'], $board) . $config['file_index'], true, $config['redirect_http']); if ($unlock) From 29b10c88db1ba16210e753e1fcf08d702455a674 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Tue, 16 Jul 2013 02:48:20 -0400 Subject: [PATCH 09/11] Outputting thread subject in header/title (issue #122) --- inc/config.php | 3 +++ inc/functions.php | 5 +++-- templates/index.html | 2 +- templates/thread.html | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/inc/config.php b/inc/config.php index 83b98c2b..ed4a31f1 100644 --- a/inc/config.php +++ b/inc/config.php @@ -527,6 +527,9 @@ // Number of characters in the poster ID (maximum is 40) $config['poster_id_length'] = 5; + // Show thread subject in page title? + $config['thread_subject_in_title'] = false; + // Page footer $config['footer'][] = 'All trademarks, copyrights, comments, and images on this page are owned by and are the responsibility of their respective parties.'; diff --git a/inc/functions.php b/inc/functions.php index 67019e0a..4b0e56d8 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1537,8 +1537,9 @@ function buildThread($id, $return=false, $mod=false) { error($config['error']['nonexistant']); $body = Element('thread.html', array( - 'board'=>$board, - 'body'=>$thread->build(), + 'board' => $board, + 'thread' => $thread, + 'body' => $thread->build(), 'config' => $config, 'id' => $id, 'mod' => $mod, diff --git a/templates/index.html b/templates/index.html index 112756d1..9b25e1be 100644 --- a/templates/index.html +++ b/templates/index.html @@ -4,7 +4,7 @@ {% if config.url_favicon %}{% endif %} - {{ board.url }} - {{ board.name }} + {{ board.url }} - {{ board.title|e }} {% if config.meta_keywords %}{% endif %} {% if config.default_stylesheet.1 != '' %}{% endif %} diff --git a/templates/thread.html b/templates/thread.html index 5442166f..aea8abb5 100644 --- a/templates/thread.html +++ b/templates/thread.html @@ -4,7 +4,7 @@ {% if config.url_favicon %}{% endif %} - {{ board.url }} - {{ board.name }} + {{ 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 %} From c8f30550af861b95a1f475069ad8d10960a613b2 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Tue, 16 Jul 2013 06:33:37 -0400 Subject: [PATCH 10/11] $config['require_ban_view']: Force users to view the "You are banned" page at least once before letting a ban disappear naturally. --- inc/config.php | 3 +++ inc/functions.php | 18 ++++++++++++++---- inc/mod/ban.php | 2 +- install.php | 4 +++- install.sql | 1 + templates/banned.html | 16 +++++++++++++--- 6 files changed, 35 insertions(+), 9 deletions(-) diff --git a/inc/config.php b/inc/config.php index ed4a31f1..b7f6d220 100644 --- a/inc/config.php +++ b/inc/config.php @@ -366,6 +366,9 @@ // When true, a blank password will be used for files (not usable for deletion). $config['field_disable_password'] = false; + // Require users to see the ban page at least once for a ban even if it has since expired? + $config['require_ban_view'] = false; + /* * ==================== * Markup settings diff --git a/inc/functions.php b/inc/functions.php index 4b0e56d8..8d6e0a2d 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -579,6 +579,12 @@ function ago($timestamp) { function displayBan($ban) { global $config; + if (!$ban['seen']) { + $query = prepare("UPDATE `bans` SET `seen` = 1 WHERE `id` = :id"); + $query->bindValue(':id', $ban['id'], PDO::PARAM_INT); + $query->execute() or error(db_error($query)); + } + $ban['ip'] = $_SERVER['REMOTE_ADDR']; // Show banned page and exit @@ -605,12 +611,12 @@ function checkBan($board = 0) { if (event('check-ban', $board)) return true; - $query = prepare("SELECT `set`, `expires`, `reason`, `board`, `bans`.`id` FROM `bans` WHERE (`board` IS NULL OR `board` = :board) AND `ip` = :ip ORDER BY `expires` IS NULL DESC, `expires` DESC, `expires` DESC LIMIT 1"); + $query = prepare("SELECT `set`, `expires`, `reason`, `board`, `seen`, `bans`.`id` FROM `bans` WHERE (`board` IS NULL OR `board` = :board) AND `ip` = :ip ORDER BY `expires` IS NULL DESC, `expires` DESC, `expires` DESC LIMIT 1"); $query->bindValue(':ip', $_SERVER['REMOTE_ADDR']); $query->bindValue(':board', $board); $query->execute() or error(db_error($query)); if ($query->rowCount() < 1 && $config['ban_range']) { - $query = prepare("SELECT `set`, `expires`, `reason`, `board`, `bans`.`id` FROM `bans` WHERE (`board` IS NULL OR `board` = :board) AND :ip LIKE REPLACE(REPLACE(`ip`, '%', '!%'), '*', '%') ESCAPE '!' ORDER BY `expires` IS NULL DESC, `expires` DESC LIMIT 1"); + $query = prepare("SELECT `set`, `expires`, `reason`, `board`, `seen`, `bans`.`id` FROM `bans` WHERE (`board` IS NULL OR `board` = :board) AND :ip LIKE REPLACE(REPLACE(`ip`, '%', '!%'), '*', '%') ESCAPE '!' ORDER BY `expires` IS NULL DESC, `expires` DESC LIMIT 1"); $query->bindValue(':ip', $_SERVER['REMOTE_ADDR']); $query->bindValue(':board', $board); $query->execute() or error(db_error($query)); @@ -618,7 +624,7 @@ function checkBan($board = 0) { if ($query->rowCount() < 1 && $config['ban_cidr'] && !isIPv6()) { // my most insane SQL query yet - $query = prepare("SELECT `set`, `expires`, `reason`, `board`, `bans`.`id` FROM `bans` WHERE (`board` IS NULL OR `board` = :board) + $query = prepare("SELECT `set`, `expires`, `reason`, `board`, `seen`, `bans`.`id` FROM `bans` WHERE (`board` IS NULL OR `board` = :board) AND ( `ip` REGEXP '^(\[0-9]+\.\[0-9]+\.\[0-9]+\.\[0-9]+\)\/(\[0-9]+)$' AND @@ -635,10 +641,14 @@ function checkBan($board = 0) { if ($ban = $query->fetch()) { if ($ban['expires'] && $ban['expires'] < time()) { // Ban expired - $query = prepare("DELETE FROM `bans` WHERE `id` = :id LIMIT 1"); + $query = prepare("DELETE FROM `bans` WHERE `id` = :id"); $query->bindValue(':id', $ban['id'], PDO::PARAM_INT); $query->execute() or error(db_error($query)); + if ($config['require_ban_view'] && !$ban['seen']) { + displayBan($ban); + } + return; } diff --git a/inc/mod/ban.php b/inc/mod/ban.php index 30234157..cfc2636f 100644 --- a/inc/mod/ban.php +++ b/inc/mod/ban.php @@ -56,7 +56,7 @@ function parse_time($str) { function ban($mask, $reason, $length, $board) { global $mod, $pdo; - $query = prepare("INSERT INTO `bans` VALUES (NULL, :ip, :mod, :time, :expires, :reason, :board)"); + $query = prepare("INSERT INTO `bans` VALUES (NULL, :ip, :mod, :time, :expires, :reason, :board, 0)"); $query->bindValue(':ip', $mask); $query->bindValue(':mod', $mod['id']); $query->bindValue(':time', time()); diff --git a/install.php b/install.php index 1447c723..71d1c910 100644 --- a/install.php +++ b/install.php @@ -1,7 +1,7 @@ -

{% trans %}You are banned! ;_;{% endtrans %}

+ {% if ban.expires and time() >= ban.expires %} +

{% trans %}You were banned! ;_;{% endtrans %}

+ {% else %} +

{% trans %}You are banned! ;_;{% endtrans %}

+ {% endif %}

- {% trans %}You have been banned from{% endtrans %} + {% if ban.expires and time() >= ban.expires %} + {% trans %}You were banned from{% endtrans %} + {% else %} + {% trans %}You have been banned from{% endtrans %} + {% endif %} {% if ban.board %} {{ config.board_abbreviation|sprintf(ban.board) }} {% else %} @@ -23,7 +31,9 @@

{% trans %}Your ban was filed on{% endtrans %} {{ ban.set|date(config.ban_date) }} {% trans %}and{% endtrans %} - {% if ban.expires %} + {% if ban.expires and time() >= ban.expires %} + {% trans %} has since expired. Refresh the page to continue.{% endtrans %} + {% elseif ban.expires %} {% trans %}expires{% endtrans %} {{ ban.expires|until }} {% trans %}from now, which is on{% endtrans %} {{ ban.expires|date(config.ban_date) }} From aadb57f2a2db9210468f25d7dcd45d561ef6ad54 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Tue, 16 Jul 2013 08:50:39 -0400 Subject: [PATCH 11/11] More ban stuff: Show whether or not user has "seen" a ban yet in the ban list and on IP address pages. Purge useless expired ban records. --- inc/functions.php | 10 ++++++++++ templates/mod/ban_list.html | 8 ++++++++ templates/mod/view_ip.html | 10 ++++++++++ 3 files changed, 28 insertions(+) diff --git a/inc/functions.php b/inc/functions.php index 8d6e0a2d..40a2c1fe 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -654,6 +654,16 @@ function checkBan($board = 0) { displayBan($ban); } + + // I'm not sure where else to put this. It doesn't really matter where; it just needs to be called every now and then to keep the ban list tidy. + purge_bans(); +} + +// No reason to keep expired bans in the database (except those that haven't been viewed yet) +function purge_bans() { + $query = prepare("DELETE FROM `bans` WHERE `expires` IS NOT NULL AND `expires` < :time AND `seen` = 1"); + $query->bindValue(':time', time()); + $query->execute() or error(db_error($query)); } function threadLocked($id) { diff --git a/templates/mod/ban_list.html b/templates/mod/ban_list.html index 2edb9cdf..f8826ade 100644 --- a/templates/mod/ban_list.html +++ b/templates/mod/ban_list.html @@ -10,6 +10,7 @@ {% trans 'Set' %} {% trans 'Duration' %} {% trans 'Expires' %} + {% trans 'Seen' %} {% trans 'Staff' %} {% for ban in bans %} @@ -58,6 +59,13 @@ {% endif %} {% endif %} + + {% if ban.seen %} + {% trans 'Yes' %} + {% else %} + {% trans 'No' %} + {% endif %} + {% if ban.username %} {% if mod|hasPermission(config.mod.view_banstaff) %} diff --git a/templates/mod/view_ip.html b/templates/mod/view_ip.html index 562a0140..e2dad7af 100644 --- a/templates/mod/view_ip.html +++ b/templates/mod/view_ip.html @@ -136,6 +136,16 @@ {% endif %} + + {% trans 'Seen' %} + + {% if ban.seen %} + {% trans 'Yes' %} + {% else %} + {% trans 'No' %} + {% endif %} + + {% trans 'Staff' %}