From fb3b9ea868b7c65e18f8cde5d4d66388d78e5da8 Mon Sep 17 00:00:00 2001 From: czaks Date: Sun, 4 Aug 2013 01:53:37 -0400 Subject: [PATCH 01/13] quick-post-controls.js: fix javascript interactions --- js/quick-post-controls.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/js/quick-post-controls.js b/js/quick-post-controls.js index c28f874f..1cbc0711 100644 --- a/js/quick-post-controls.js +++ b/js/quick-post-controls.js @@ -71,10 +71,16 @@ $(document).ready(function(){ } }; - $('div.post input[type=checkbox].delete').each(function() { + var init_qpc = function() { $(this).change(open_form); if(this.checked) $(this).trigger('change'); + }; + + $('div.post input[type=checkbox].delete').each(init_qpc); + + $(document).bind('new_post', function(e, post) { + $(post).find('input[type=checkbox].delete').each(init_qpc); }); }); From 0890557ebb666dacf3356aae262ec79f486fa25d Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sun, 4 Aug 2013 04:48:13 -0400 Subject: [PATCH 02/13] Don't purge the ban list of expires bans every time somebody posts. Add a timer option. Less SQL queries when posting. --- inc/config.php | 4 ++++ inc/functions.php | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/inc/config.php b/inc/config.php index 06c6c243..bc7711e6 100644 --- a/inc/config.php +++ b/inc/config.php @@ -983,6 +983,10 @@ // persistent spammers and ban evaders. Again, a little more database load. $config['ban_cidr'] = true; + // How often (minimum) to purge the ban list of expired bans (which have been seen). Only works when + // $config['cache'] is enabled and working. + $config['purge_bans'] = 60 * 60 * 12; // 12 hours + // Do DNS lookups on IP addresses to get their hostname for the moderator IP pages (?/IP/x.x.x.x). $config['mod']['dns_lookup'] = true; // How many recent posts, per board, to show in ?/IP/x.x.x.x. diff --git a/inc/functions.php b/inc/functions.php index 8b2c4c7b..0c9b9983 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -687,9 +687,19 @@ function checkBan($board = 0) { // No reason to keep expired bans in the database (except those that haven't been viewed yet) function purge_bans() { + global $config; + + if ($config['cache']['enabled'] && $last_time_purged = cache::get('purged_bans_last')) { + if (time() - $last_time_purged < 60 * 30) + return; + } + $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)); + + if ($config['cache']['enabled']) + cache::set('purged_bans_last', time()); } function threadLocked($id) { From 6409ac61639e588f62904d54a4fb37158d31a5f4 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sun, 4 Aug 2013 04:49:21 -0400 Subject: [PATCH 03/13] fix last commit --- inc/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/functions.php b/inc/functions.php index 0c9b9983..fe27a568 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -690,7 +690,7 @@ function purge_bans() { global $config; if ($config['cache']['enabled'] && $last_time_purged = cache::get('purged_bans_last')) { - if (time() - $last_time_purged < 60 * 30) + if (time() - $last_time_purged < $config['purge_bans'] ) return; } From 76101cad516915c008ee5ca5b6d6c45dc54a7e03 Mon Sep 17 00:00:00 2001 From: czaks Date: Sun, 4 Aug 2013 04:46:30 -0400 Subject: [PATCH 04/13] fix gifsicle issue connected with frame limit --- inc/image.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/image.php b/inc/image.php index 193e588e..1c865218 100644 --- a/inc/image.php +++ b/inc/image.php @@ -320,7 +320,7 @@ class ImageConvert extends ImageBase { if ($this->format == 'gif' && ($config['thumb_ext'] == 'gif' || $config['thumb_ext'] == '') && $config['thumb_keep_animation_frames'] > 1) { if ($this->gifsicle) { - if (($error = shell_exec_error("gifsicle --unoptimize -O2 --resize {$this->width}x{$this->height} < " . + if (($error = shell_exec_error("gifsicle -w --unoptimize -O2 --resize {$this->width}x{$this->height} < " . escapeshellarg($this->src . '') . " \"#0-{$config['thumb_keep_animation_frames']}\" > " . escapeshellarg($this->temp))) || !file_exists($this->temp)) error('Failed to resize image!', null, $error); From 0f00f800b9735fe8b2c5c366a9b3972039c317e0 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sun, 4 Aug 2013 05:03:21 -0400 Subject: [PATCH 05/13] Use new shell_exec function for $config['dns_system'] `host` queries too --- inc/functions.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inc/functions.php b/inc/functions.php index fe27a568..82f047b5 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1901,7 +1901,7 @@ function rDNS($ip_addr) { if (!$config['dns_system']) { $host = gethostbyaddr($ip_addr); } else { - $resp = shell_exec('host -W 1 ' . $ip_addr); + $resp = shell_exec_error('host -W 1 ' . $ip_addr); if (preg_match('/domain name pointer ([^\s]+)$/', $resp, $m)) $host = $m[1]; else @@ -1926,7 +1926,7 @@ function DNS($host) { if ($ip_addr == $host) $ip_addr = false; } else { - $resp = shell_exec('host -W 1 ' . $host); + $resp = shell_exec_error('host -W 1 ' . $host); if (preg_match('/has address ([^\s]+)$/', $resp, $m)) $ip_addr = $m[1]; else From 33a07e9ee0103f51991020721eb4e059e0990942 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sun, 4 Aug 2013 05:11:46 -0400 Subject: [PATCH 06/13] bug fix, wrong index --- inc/image.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inc/image.php b/inc/image.php index 1c865218..23558386 100644 --- a/inc/image.php +++ b/inc/image.php @@ -265,8 +265,8 @@ class ImageConvert extends ImageBase { } $size = $this->get_size($this->src, false); if ($size) { - $this->width = $size[1]; - $this->height = $size[2]; + $this->width = $size[0]; + $this->height = $size[1]; $this->image = true; } else { From b7070aeac68c18e96c29babbb8d60c8e8ff1c659 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sun, 4 Aug 2013 15:23:26 -0400 Subject: [PATCH 07/13] Fix issue with installing and creating boards with MySQL < 5.5.3. Issue #129 --- inc/mod/pages.php | 7 ++++++- install.php | 5 +++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 0a9f825b..706d747d 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -480,7 +480,12 @@ function mod_new_board() { if (!openBoard($_POST['uri'])) error(_("Couldn't open board after creation.")); - query(Element('posts.sql', array('board' => $board['uri']))) or error(db_error()); + $query = Element('posts.sql', array('board' => $board['uri'])); + + if (mysql_version() < 50503) + $query = preg_replace('/(CHARSET=|CHARACTER SET )utf8mb4/', '$1utf8', $query); + + query($query) or error(db_error()); if ($config['cache']['enabled']) cache::delete('all_boards'); diff --git a/install.php b/install.php index 81b2e136..6971437a 100644 --- a/install.php +++ b/install.php @@ -618,8 +618,7 @@ if ($step == 0) { $sql = @file_get_contents('install.sql') or error("Couldn't load install.sql."); sql_open(); - if (mysql_version() < 50503) - $sql = preg_replace('/(CHARSET=|CHARACTER SET )utf8mb4/', '$1utf8', $sql); + $mysql_version = mysql_version(); // This code is probably horrible, but what I'm trying // to do is find all of the SQL queires and put them @@ -631,6 +630,8 @@ if ($step == 0) { $sql_errors = ''; foreach ($queries as $query) { + if ($mysql_version < 50503) + $query = preg_replace('/(CHARSET=|CHARACTER SET )utf8mb4/', '$1utf8', $query); $query = preg_replace('/^([\w\s]*)`([0-9a-zA-Z$_\x{0080}-\x{FFFF}]+)`/u', '$1``$2``', $query); if (!query($query)) $sql_errors .= '
  • ' . db_error() . '
  • '; From a3cf56a7688d9f5063ac06e5bf8afac0a693f2f0 Mon Sep 17 00:00:00 2001 From: czaks Date: Sun, 4 Aug 2013 15:29:18 -0400 Subject: [PATCH 08/13] gifsicle: make it finally work --- inc/image.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/image.php b/inc/image.php index 23558386..b3c0e6b5 100644 --- a/inc/image.php +++ b/inc/image.php @@ -321,7 +321,7 @@ class ImageConvert extends ImageBase { if ($this->format == 'gif' && ($config['thumb_ext'] == 'gif' || $config['thumb_ext'] == '') && $config['thumb_keep_animation_frames'] > 1) { if ($this->gifsicle) { if (($error = shell_exec_error("gifsicle -w --unoptimize -O2 --resize {$this->width}x{$this->height} < " . - escapeshellarg($this->src . '') . " \"#0-{$config['thumb_keep_animation_frames']}\" > " . + escapeshellarg($this->src . '') . " \"#0-{$config['thumb_keep_animation_frames']}\" >/dev/null -o " . escapeshellarg($this->temp))) || !file_exists($this->temp)) error('Failed to resize image!', null, $error); } else { From acfda35648b5a3eac5607084b781c0ced8e0bc53 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sun, 4 Aug 2013 16:32:36 -0400 Subject: [PATCH 09/13] gifsicle: redirect stdout to /dev/null but keep stderr going to stdout --- inc/functions.php | 5 +++-- inc/image.php | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/inc/functions.php b/inc/functions.php index 82f047b5..01fdb18e 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -1939,13 +1939,14 @@ function DNS($host) { return $ip_addr; } -function shell_exec_error($command) { +function shell_exec_error($command, $suppress_stdout = false) { global $config, $debug; if ($config['debug']) $start = microtime(true); - $return = trim(shell_exec('PATH="' . escapeshellcmd($config['shell_path']) . ':$PATH";' . $command . ' 2>&1 && echo "TB_SUCCESS"')); + $return = trim(shell_exec('PATH="' . escapeshellcmd($config['shell_path']) . ':$PATH";' . + $command . ' 2>&1 ' . ($suppress_stdout ? '> /dev/null ' : '') . '&& echo "TB_SUCCESS"')); $return = preg_replace('/TB_SUCCESS$/', '', $return); if ($config['debug']) { diff --git a/inc/image.php b/inc/image.php index b3c0e6b5..920cf8f9 100644 --- a/inc/image.php +++ b/inc/image.php @@ -321,8 +321,8 @@ class ImageConvert extends ImageBase { if ($this->format == 'gif' && ($config['thumb_ext'] == 'gif' || $config['thumb_ext'] == '') && $config['thumb_keep_animation_frames'] > 1) { if ($this->gifsicle) { if (($error = shell_exec_error("gifsicle -w --unoptimize -O2 --resize {$this->width}x{$this->height} < " . - escapeshellarg($this->src . '') . " \"#0-{$config['thumb_keep_animation_frames']}\" >/dev/null -o " . - escapeshellarg($this->temp))) || !file_exists($this->temp)) + escapeshellarg($this->src . '') . " \"#0-{$config['thumb_keep_animation_frames']}\" -o " . + escapeshellarg($this->temp), true)) || !file_exists($this->temp)) error('Failed to resize image!', null, $error); } else { if ($config['convert_manual_orient'] && ($this->format == 'jpg' || $this->format == 'jpeg')) From 6e0e5b1e8a4e5bc5ec5dd13ed2361f37abd6d965 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sun, 4 Aug 2013 16:46:08 -0400 Subject: [PATCH 10/13] Not the nicest-looking fix, but comments (actual comments, not code examples) beginning with "$" are ignored by ?/config. --- inc/config.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/inc/config.php b/inc/config.php index bc7711e6..410078d3 100644 --- a/inc/config.php +++ b/inc/config.php @@ -475,8 +475,8 @@ // Maximum amount of animated GIF frames to resize (more frames can mean more processing power). A value // of "1" means thumbnails will not be animated. Requires $config['thumb_ext'] to be 'gif' (or blank) and - // $config['thumb_method'] to be 'imagick', 'convert', or 'convert+gifsicle'. This value is not respected - // by 'convert'; will just resize all frames if this is > 1. + // $config['thumb_method'] to be 'imagick', 'convert', or 'convert+gifsicle'. This value is not + // respected by 'convert'; will just resize all frames if this is > 1. $config['thumb_keep_animation_frames'] = 1; /* @@ -510,7 +510,7 @@ $config['strip_exif'] = false; // Use the command-line `exiftool` tool to strip EXIF metadata without decompressing/recompressing JPEGs. // Ignored when $config['redraw_image'] is true. This is also used to adjust the Orientation tag when - // $config['strip_exif'] is false and $config['convert_manual_orient'] is true. + // $config['strip_exif'] is false and $config['convert_manual_orient'] is true. $config['use_exiftool'] = false; // Redraw the image to strip any excess data (commonly ZIP archives) WARNING: This might strip the @@ -579,7 +579,7 @@ // Reject duplicate image uploads. $config['image_reject_repost'] = true; // Reject duplicate image uploads within the same thread. Doesn't change anything if - // $config['image_reject_repost'] is true. + // $config['image_reject_repost'] is true. $config['image_reject_repost_in_thread'] = false; // Display the aspect ratio of uploaded files. @@ -606,7 +606,7 @@ $config['threads_preview_sticky'] = 1; // How to display the URI of boards. Usually '/%s/' (/b/, /mu/, etc). This doesn't change the URL. Find - // $config['board_path'] if you wish to change the URL. + // $config['board_path'] if you wish to change the URL. $config['board_abbreviation'] = '/%s/'; // The default name (ie. Anonymous). @@ -909,7 +909,7 @@ // If you want to put images and other dynamic-static stuff on another (preferably cookieless) domain. // This will override $config['root'] and $config['dir']['...'] directives. "%s" will get replaced with - // $board['dir'], which includes a trailing slash. + // $board['dir'], which includes a trailing slash. // $config['uri_thumb'] = 'http://images.example.org/%sthumb/'; // $config['uri_img'] = 'http://images.example.org/%ssrc/'; @@ -984,7 +984,7 @@ $config['ban_cidr'] = true; // How often (minimum) to purge the ban list of expired bans (which have been seen). Only works when - // $config['cache'] is enabled and working. + // $config['cache'] is enabled and working. $config['purge_bans'] = 60 * 60 * 12; // 12 hours // Do DNS lookups on IP addresses to get their hostname for the moderator IP pages (?/IP/x.x.x.x). From c3da5ab4e1186d230c1c836a08f0cb68c55ce231 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sun, 4 Aug 2013 17:53:09 -0400 Subject: [PATCH 11/13] ?/config: Advanced permissions --- inc/config.php | 43 +++++++++++++++++++++++++++++++++++---- inc/mod/config-editor.php | 42 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 79 insertions(+), 6 deletions(-) diff --git a/inc/config.php b/inc/config.php index 410078d3..1437aa58 100644 --- a/inc/config.php +++ b/inc/config.php @@ -1187,12 +1187,47 @@ $config['mod']['news_custom'] = ADMIN; // Delete news entries $config['mod']['news_delete'] = ADMIN; - - // Edit the current configuration (via web interface) - $config['mod']['edit_config'] = ADMIN; - // Execute un-filtered SQL queries on the database (?/debug/sql) $config['mod']['debug_sql'] = DISABLED; + // Edit the current configuration (via web interface) + $config['mod']['edit_config'] = MOD; + + // Config editor permissions + $config['mod']['config'] = array( + JANITOR => false, + MOD => false, + ADMIN => false, + DISABLED => false, + ); + + // Disable the following configuration variables from being changed via ?/config. The following default + // banned variables are considered somewhat dangerous. + $config['mod']['config'][DISABLED] = array( + 'mod>config', + 'mod>config_editor_php', + 'convert_args', + 'db>password', + ); + + $config['mod']['config'][JANITOR] = array( + '!', // Allow editing ONLY the variables listed (in this case, nothing). + ); + + $config['mod']['config'][MOD] = array( + '!', // Allow editing ONLY the variables listed (plus that in $config['mod']['config'][JANITOR]). + 'global_message', + ); + + // Example: Disallow ADMIN from editing (and viewing) $config['db']['password']. + // $config['mod']['config'][ADMIN] = array( + // 'db>password', + // ); + + // Example: Allow ADMIN to edit anything other than $config['db'] + // (and $config['mod']['config'][DISABLED]). + // $config['mod']['config'][ADMIN] = array( + // 'db', + // ); /* * ==================== diff --git a/inc/mod/config-editor.php b/inc/mod/config-editor.php index caca5a0e..27740378 100644 --- a/inc/mod/config-editor.php +++ b/inc/mod/config-editor.php @@ -1,5 +1,43 @@ ', $disabled_var_name); + if (count($disabled_var_name) == 1) + $disabled_var_name = $disabled_var_name[0]; + if ($varname == $disabled_var_name) + return false; + } + } + + $allow_only = false; + // for ($perm = (int)$mod['type']; $perm >= JANITOR; $perm --) { + for ($perm = JANITOR; $perm <= (int)$mod['type']; $perm ++) { + $allow_only = false; + if (is_array($config['mod']['config'][$perm])) { + foreach ($config['mod']['config'][$perm] as $perm_var_name) { + if ($perm_var_name == '!') { + $allow_only = true; + continue; + } + $perm_var_name = explode('>', $perm_var_name); + if ((count($perm_var_name) == 1 && $varname == $perm_var_name[0]) || + (is_array($varname) && array_slice($varname, 0, count($perm_var_name)) == $perm_var_name)) { + if ($allow_only) + return true; + else + return false; + } + } + } + } + + return !$allow_only; +} + function config_vars() { global $config; @@ -77,8 +115,8 @@ function config_vars() { $already_exists = true; } - if (!$already_exists) - $conf[] = $var; + if (!$already_exists && permission_to_edit_config_var($var['name'])) + $conf[] = $var; } } From 7a51444110c7fa539a630214b54ba1b7a9e4c6ad Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sun, 4 Aug 2013 17:53:55 -0400 Subject: [PATCH 12/13] This should probably still be ADMIN. By default, don't let mods or janitors edit any of the config. --- inc/config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/config.php b/inc/config.php index 1437aa58..61a36cad 100644 --- a/inc/config.php +++ b/inc/config.php @@ -1190,7 +1190,7 @@ // Execute un-filtered SQL queries on the database (?/debug/sql) $config['mod']['debug_sql'] = DISABLED; // Edit the current configuration (via web interface) - $config['mod']['edit_config'] = MOD; + $config['mod']['edit_config'] = ADMIN; // Config editor permissions $config['mod']['config'] = array( From 0c829aa8f6fb592c15086e8b2b0276fd862e89f1 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sun, 4 Aug 2013 18:48:32 -0400 Subject: [PATCH 13/13] bugfix --- inc/config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/config.php b/inc/config.php index 61a36cad..ef2ba4ac 100644 --- a/inc/config.php +++ b/inc/config.php @@ -561,7 +561,7 @@ // Location of thumbnail to use for spoiler images. $config['spoiler_image'] = 'static/spoiler.png'; // Location of thumbnail to use for deleted images. - $config['image_deleted'] = 'static/deleted.png'; + // $config['image_deleted'] = 'static/deleted.png'; // When a thumbnailed image is going to be the same (in dimension), just copy the entire file and use // that as a thumbnail instead of resizing/redrawing.