Browse Source

Merge branch 'master' of https://github.com/savetheinternet/Tinyboard

Conflicts:
	inc/functions.php
	inc/mod/pages.php
	install.php
	js/expand.js
	mod.php
pull/40/head
czaks 11 years ago
parent
commit
96bcf5dd1e
  1. 17
      README.md
  2. 5
      inc/config.php
  3. 21
      inc/database.php
  4. 6
      inc/display.php
  5. 16
      inc/functions.php
  6. 13
      inc/mod/pages.php
  7. 115
      install.php
  8. 93
      install.sql
  9. 6
      js/expand.js
  10. 2
      js/inline-expanding.js
  11. 33
      mod.php
  12. 11
      post.php
  13. 6
      templates/mod/log.html
  14. 2
      templates/post_form.html
  15. 63
      templates/posts.sql

17
README.md

@ -17,16 +17,21 @@ license. It is written in PHP and has few dependencies.
Requirements Requirements
------------ ------------
1. PHP >= 5.2.5 1. PHP >= 5.2.5
2. [mbstring](http://www.php.net/manual/en/mbstring.installation.php) 2. MySQL server
(--enable-mbstring) 3. [mbstring](http://www.php.net/manual/en/mbstring.installation.php)
3. [PHP-GD](http://php.net/manual/en/book.image.php) 4. [PHP GD](http://www.php.net/manual/en/intro.image.php)
4. [PHP-PDO](http://php.net/manual/en/book.pdo.php) 5. [PHP PDO](http://www.php.net/manual/en/intro.pdo.php)
(only MySQL is supported at the moment)
We try to make sure Tinyboard is compatible with all major web servers and We try to make sure Tinyboard is compatible with all major web servers and
operating systems. Tinyboard does not include an Apache ```.htaccess``` file nor does operating systems. Tinyboard does not include an Apache ```.htaccess``` file nor does
it need one. it need one.
### Recommended
1. PHP >= 5.3
2. MySQL server >= 5.5.3
3. ImageMagick or command-line version (```convert``` and ```identify```)
4. [APC (Alternative PHP Cache)](http://php.net/manual/en/book.apc.php), [XCache](http://xcache.lighttpd.net/) or [Memcached](http://www.php.net/manual/en/intro.memcached.php)
Contributing Contributing
------------ ------------
You can contribute to Tinyboard by: You can contribute to Tinyboard by:
@ -65,7 +70,7 @@ find support from a variety of sources:
* Documentation can be found [here](http://tinyboard.org/docs/). * Documentation can be found [here](http://tinyboard.org/docs/).
* You can join Tinyboard's IRC channel for support and general queries: * You can join Tinyboard's IRC channel for support and general queries:
[irc.datnode.net #tinyboard](irc://irc.datnode.net/tinyboard). [irc.datnode.net #tinyboard](irc://irc.datnode.net/tinyboard).
* You can find enterprise-grade support at [tinyboard.org](http://tinyboard.org/#support). * You may find help at [tinyboard.org](http://tinyboard.org/#help).
License License
-------- --------

5
inc/config.php

@ -1051,6 +1051,8 @@
$config['mod']['createusers'] = ADMIN; $config['mod']['createusers'] = ADMIN;
// View the moderation log // View the moderation log
$config['mod']['modlog'] = ADMIN; $config['mod']['modlog'] = ADMIN;
// View IP addresses of other mods in ?/log
$config['mod']['show_ip_modlog'] = ADMIN;
// View relevant moderation log entries on IP address pages (ie. ban history, etc.) // View relevant moderation log entries on IP address pages (ie. ban history, etc.)
// Warning: Can be pretty resource exhaustive if your mod logs are huge. // Warning: Can be pretty resource exhaustive if your mod logs are huge.
$config['mod']['modlog_ip'] = MOD; $config['mod']['modlog_ip'] = MOD;
@ -1177,6 +1179,9 @@
// 'type' => 'scp' // 'type' => 'scp'
//); //);
// Regex for board URIs
$config['board_regex'] = '[0-9a-zA-Z$_\x{0080}-\x{FFFF}]{1,58}';
// Complex regular expression to catch URLs // Complex regular expression to catch URLs
$config['url_regex'] = '/' . '(https?|ftp):\/\/' . '(([\w\-]+\.)+[a-zA-Z]{2,6}|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' . '(:\d+)?' . '(\/([\w\-~.#\/?=&;:+%!*\[\]@$\'()+,|\^]+)?)?' . '/'; $config['url_regex'] = '/' . '(https?|ftp):\/\/' . '(([\w\-]+\.)+[a-zA-Z]{2,6}|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' . '(:\d+)?' . '(\/([\w\-~.#\/?=&;:+%!*\[\]@$\'()+,|\^]+)?)?' . '/';

21
inc/database.php

@ -51,12 +51,16 @@ function sql_open() {
try { try {
$options = array( $options = array(
PDO::ATTR_TIMEOUT => $config['db']['timeout'], PDO::ATTR_TIMEOUT => $config['db']['timeout'],
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true
); );
if ($config['db']['persistent']) if ($config['db']['persistent'])
$options[PDO::ATTR_PERSISTENT] = true; $options[PDO::ATTR_PERSISTENT] = true;
return $pdo = new PDO($dsn, $config['db']['user'], $config['db']['password'], $options); $pdo = new PDO($dsn, $config['db']['user'], $config['db']['password'], $options);
if (mysql_version() >= 50503)
query('SET NAMES utf8mb4') or error(db_error());
else
query('SET NAMES utf8') or error(db_error());
return $pdo;
} catch(PDOException $e) { } catch(PDOException $e) {
$message = $e->getMessage(); $message = $e->getMessage();
@ -65,10 +69,21 @@ function sql_open() {
$message = str_replace($config['db']['password'], '<em>hidden</em>', $message); $message = str_replace($config['db']['password'], '<em>hidden</em>', $message);
// Print error // Print error
error('Database error: ' . $message); error(_('Database error: ') . $message);
} }
} }
// 5.6.10 becomes 50610
function mysql_version() {
global $pdo;
$version = $pdo->getAttribute(PDO::ATTR_SERVER_VERSION);
$v = explode('.', $version);
if (count($v) != 3)
return false;
return (int) sprintf("%02d%02d%02d", $v[0], $v[1], $v[2]);
}
function prepare($query) { function prepare($query) {
global $pdo, $debug, $config; global $pdo, $debug, $config;

6
inc/display.php

@ -235,7 +235,7 @@ function bidi_cleanup($str){
function secure_link_confirm($text, $title, $confirm_message, $href) { function secure_link_confirm($text, $title, $confirm_message, $href) {
global $config; global $config;
return '<a onclick="if (event.which==2) return true;if (confirm(\'' . htmlentities(addslashes($confirm_message)) . '\')) document.location=\'?/' . htmlentities(addslashes($href . '/' . make_secure_link_token($href))) . '\';return false;" title="' . htmlentities($title) . '" href="?/' . $href . '">' . $text . '</a>'; return '<a onclick="if (event.which==2) return true;if (confirm(\'' . htmlentities(addslashes($confirm_message)) . '\')) document.location=\'?/' . htmlspecialchars(addslashes($href . '/' . make_secure_link_token($href))) . '\';return false;" title="' . htmlentities($title) . '" href="?/' . $href . '">' . $text . '</a>';
} }
function secure_link($href) { function secure_link($href) {
return $href . '/' . make_secure_link_token($href); return $href . '/' . make_secure_link_token($href);
@ -299,7 +299,7 @@ class Post {
// Fix internal links // Fix internal links
// Very complicated regex // Very complicated regex
$this->body = preg_replace( $this->body = preg_replace(
'/<a((([a-zA-Z]+="[^"]+")|[a-zA-Z]+=[a-zA-Z]+|\s)*)href="' . preg_quote($config['root'], '/') . '(' . sprintf(preg_quote($config['board_path'], '/'), '\w+') . ')/', '/<a((([a-zA-Z]+="[^"]+")|[a-zA-Z]+=[a-zA-Z]+|\s)*)href="' . preg_quote($config['root'], '/') . '(' . sprintf(preg_quote($config['board_path'], '/'), $config['board_regex']) . ')/u',
'<a $1href="?/$4', '<a $1href="?/$4',
$this->body $this->body
); );
@ -398,7 +398,7 @@ class Thread {
// Fix internal links // Fix internal links
// Very complicated regex // Very complicated regex
$this->body = preg_replace( $this->body = preg_replace(
'/<a((([a-zA-Z]+="[^"]+")|[a-zA-Z]+=[a-zA-Z]+|\s)*)href="' . preg_quote($config['root'], '/') . '(' . sprintf(preg_quote($config['board_path'], '/'), '\w+') . ')/', '/<a((([a-zA-Z]+="[^"]+")|[a-zA-Z]+=[a-zA-Z]+|\s)*)href="' . preg_quote($config['root'], '/') . '(' . sprintf(preg_quote($config['board_path'], '/'), $config['board_regex']) . ')/u',
'<a $1href="?/$4', '<a $1href="?/$4',
$this->body $this->body
); );

16
inc/functions.php

@ -99,18 +99,18 @@ function loadConfig() {
'https?:\/\/' . $_SERVER['HTTP_HOST']) . 'https?:\/\/' . $_SERVER['HTTP_HOST']) .
preg_quote($config['root'], '/') . preg_quote($config['root'], '/') .
'(' . '(' .
str_replace('%s', '\w+', preg_quote($config['board_path'], '/')) . str_replace('%s', $config['board_regex'], preg_quote($config['board_path'], '/')) .
'(' . '(' .
preg_quote($config['file_index'], '/') . '|' . preg_quote($config['file_index'], '/') . '|' .
str_replace('%d', '\d+', preg_quote($config['file_page'])) . str_replace('%d', '\d+', preg_quote($config['file_page'])) .
')?' . ')?' .
'|' . '|' .
str_replace('%s', '\w+', preg_quote($config['board_path'], '/')) . str_replace('%s', $config['board_regex'], preg_quote($config['board_path'], '/')) .
preg_quote($config['dir']['res'], '/') . preg_quote($config['dir']['res'], '/') .
str_replace('%d', '\d+', preg_quote($config['file_page'], '/')) . str_replace('%d', '\d+', preg_quote($config['file_page'], '/')) .
'|' . '|' .
preg_quote($config['file_mod'], '/') . '\?\/.+' . preg_quote($config['file_mod'], '/') . '\?\/.+' .
')([#?](.+)?)?$/i'; ')([#?](.+)?)?$/ui';
} else { } else {
// CLI mode // CLI mode
$config['referer_match'] = '//'; $config['referer_match'] = '//';
@ -367,6 +367,11 @@ function boardTitle($uri) {
function purge($uri) { function purge($uri) {
global $config, $debug; global $config, $debug;
// Fix for Unicode
$uri = urlencode($uri);
$uri = str_replace("%2F", "/", $uri);
$uri = str_replace("%3A", ":", $uri);
if (preg_match($config['referer_match'], $config['root']) && isset($_SERVER['REQUEST_URI'])) { if (preg_match($config['referer_match'], $config['root']) && isset($_SERVER['REQUEST_URI'])) {
$uri = (str_replace('\\', '/', dirname($_SERVER['REQUEST_URI'])) == '/' ? '/' : str_replace('\\', '/', dirname($_SERVER['REQUEST_URI'])) . '/') . $uri; $uri = (str_replace('\\', '/', dirname($_SERVER['REQUEST_URI'])) == '/' ? '/' : str_replace('\\', '/', dirname($_SERVER['REQUEST_URI'])) . '/') . $uri;
} else { } else {
@ -1429,6 +1434,9 @@ function markup(&$body, $track_cites = false) {
$body = str_replace("\r", '', $body); $body = str_replace("\r", '', $body);
$body = utf8tohtml($body); $body = utf8tohtml($body);
if (mysql_version() < 50503)
$body = mb_encode_numericentity($body, array(0x010000, 0xffffff, 0, 0xffffff), 'UTF-8');
foreach ($config['markup'] as $markup) { foreach ($config['markup'] as $markup) {
if (is_string($markup[1])) { if (is_string($markup[1])) {
$body = preg_replace($markup[0], $markup[1], $body); $body = preg_replace($markup[0], $markup[1], $body);
@ -1495,7 +1503,7 @@ function markup(&$body, $track_cites = false) {
} }
// Cross-board linking // Cross-board linking
if (preg_match_all('/(^|\s)&gt;&gt;&gt;\/([\w.+]+?)\/(\d+)?([\s,.)?]|$)/m', $body, $cites, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { if (preg_match_all('/(^|\s)&gt;&gt;&gt;\/(' . $config['board_regex'] . 'f?)\/(\d+)?([\s,.)?]|$)/um', $body, $cites, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) {
if (count($cites[0]) > $config['max_cites']) { if (count($cites[0]) > $config['max_cites']) {
error($config['error']['toomanycross']); error($config['error']['toomanycross']);
} }

13
inc/mod/pages.php

@ -443,8 +443,8 @@ function mod_new_board() {
if ($_POST['title'] == '') if ($_POST['title'] == '')
error(sprintf($config['error']['required'], 'title')); error(sprintf($config['error']['required'], 'title'));
#if (!preg_match('/^\w+$/', $_POST['uri'])) if (!preg_match('/^' . $config['board_regex'] . '$/u', $_POST['uri']))
# error(sprintf($config['error']['invalidfield'], 'URI')); error(sprintf($config['error']['invalidfield'], 'URI'));
if (openBoard($_POST['uri'])) { if (openBoard($_POST['uri'])) {
error(sprintf($config['error']['boardexists'], $board['url'])); error(sprintf($config['error']['boardexists'], $board['url']));
@ -744,7 +744,8 @@ function mod_page_ip($ip) {
$boards = listBoards(); $boards = listBoards();
foreach ($boards as $board) { foreach ($boards as $board) {
openBoard($board['uri']); openBoard($board['uri']);
if (!hasPermission($config['mod']['show_ip'], $board['uri']))
continue;
$query = prepare(sprintf('SELECT * FROM `posts_%s` WHERE `ip` = :ip ORDER BY `sticky` DESC, `id` DESC LIMIT :limit', $board['uri'])); $query = prepare(sprintf('SELECT * FROM `posts_%s` WHERE `ip` = :ip ORDER BY `sticky` DESC, `id` DESC LIMIT :limit', $board['uri']));
$query->bindValue(':ip', $ip); $query->bindValue(':ip', $ip);
$query->bindValue(':limit', $config['mod']['ip_recentposts'], PDO::PARAM_INT); $query->bindValue(':limit', $config['mod']['ip_recentposts'], PDO::PARAM_INT);
@ -1418,7 +1419,7 @@ function mod_user($uid) {
$boards = array(); $boards = array();
foreach ($_POST as $name => $value) { foreach ($_POST as $name => $value) {
if (preg_match('/^board_(\w+)$/', $name, $matches) && in_array($matches[1], $_boards)) if (preg_match('/^board_(' . $config['board_regex'] . ')$/u', $name, $matches) && in_array($matches[1], $_boards))
$boards[] = $matches[1]; $boards[] = $matches[1];
} }
} }
@ -1539,7 +1540,7 @@ function mod_user_new() {
$boards = array(); $boards = array();
foreach ($_POST as $name => $value) { foreach ($_POST as $name => $value) {
if (preg_match('/^board_(\w+)$/', $name, $matches) && in_array($matches[1], $_boards)) if (preg_match('/^board_(' . $config['board_regex'] . ')$/u', $name, $matches) && in_array($matches[1], $_boards))
$boards[] = $matches[1]; $boards[] = $matches[1];
} }
} }
@ -2133,7 +2134,7 @@ function mod_debug_antispam() {
$where .= ' AND `thread` = ' . $pdo->quote($_POST['thread']); $where .= ' AND `thread` = ' . $pdo->quote($_POST['thread']);
if (isset($_POST['purge'])) { if (isset($_POST['purge'])) {
$query = prepare('UPDATE `antispam` SET `expires` = UNIX_TIMESTAMP() + :expires WHERE' . $where); $query = prepare(', DATE `antispam` SET `expires` = UNIX_TIMESTAMP() + :expires WHERE' . $where);
$query->bindValue(':expires', $config['spam']['hidden_inputs_expire']); $query->bindValue(':expires', $config['spam']['hidden_inputs_expire']);
$query->execute() or error(db_error()); $query->execute() or error(db_error());
} }

115
install.php

@ -1,7 +1,7 @@
<?php <?php
// Installation/upgrade file // Installation/upgrade file
define('VERSION', 'v0.9.6-dev-9 + <a href="https://github.com/vichan-devel/Tinyboard/">vichan-devel-4.0.5-gold</a>'); define('VERSION', 'v0.9.6-dev-11 + <a href="https://int.vichan.net/devel/">vichan-devel-4.0.6</a>');
require 'inc/functions.php'; require 'inc/functions.php';
@ -255,6 +255,115 @@ if (file_exists($config['has_installed'])) {
case 'v0.9.6-dev-9': case 'v0.9.6-dev-9':
case 'v0.9.6-dev-9 + <a href="https://github.com/vichan-devel/Tinyboard/">vichan-devel-4.0.3</a>': case 'v0.9.6-dev-9 + <a href="https://github.com/vichan-devel/Tinyboard/">vichan-devel-4.0.3</a>':
case 'v0.9.6-dev-9 + <a href="https://github.com/vichan-devel/Tinyboard/">vichan-devel-4.0.4-gold</a>': case 'v0.9.6-dev-9 + <a href="https://github.com/vichan-devel/Tinyboard/">vichan-devel-4.0.4-gold</a>':
case 'v0.9.6-dev-9 + <a href="https://github.com/vichan-devel/Tinyboard/">vichan-devel-4.0.5-gold</a>':
sql_open();
function __query($sql) {
if (mysql_version() >= 50503)
return query($sql);
else
return query(str_replace('utf8mb4', 'utf8', $sql));
}
foreach ($boards as &$board) {
__query(sprintf("ALTER TABLE `posts_%s`
CHANGE `subject` `subject` VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE `email` `email` VARCHAR(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE `name` `name` VARCHAR(35) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE `trip` `trip` VARCHAR(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE `capcode` `capcode` VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE `body` `body` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
CHANGE `body_nomarkup` `body_nomarkup` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE `thumb` `thumb` VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE `thumbwidth` `thumbwidth` INT(11) NULL DEFAULT NULL,
CHANGE `thumbheight` `thumbheight` INT(11) NULL DEFAULT NULL,
CHANGE `file` `file` VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE `filename` `filename` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE `filehash` `filehash` TEXT CHARACTER SET ascii COLLATE ascii_general_ci NULL DEFAULT NULL,
CHANGE `password` `password` VARCHAR(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
CHANGE `ip` `ip` VARCHAR(39) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL,
CHANGE `embed` `embed` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;", $board['uri'])) or error(db_error());
}
__query("ALTER TABLE `antispam`
CHANGE `board` `board` VARCHAR( 120 ) CHARACTER SET ASCII COLLATE ascii_general_ci NOT NULL ,
CHANGE `hash` `hash` CHAR( 40 ) CHARACTER SET ASCII COLLATE ascii_bin NOT NULL ,
DEFAULT CHARACTER SET ASCII COLLATE ascii_bin;") or error(db_error());
__query("ALTER TABLE `bans`
CHANGE `ip` `ip` VARCHAR( 39 ) CHARACTER SET ASCII COLLATE ascii_general_ci NOT NULL ,
CHANGE `reason` `reason` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL ,
CHANGE `board` `board` VARCHAR( 120 ) CHARACTER SET ASCII COLLATE ascii_general_ci NULL DEFAULT NULL,
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;") or error(db_error());
__query("ALTER TABLE `boards`
CHANGE `uri` `uri` VARCHAR( 120 ) CHARACTER SET ASCII COLLATE ascii_general_ci NOT NULL ,
CHANGE `title` `title` TINYTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
CHANGE `subtitle` `subtitle` TINYTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;") or error(db_error());
__query("ALTER TABLE `cites`
CHANGE `board` `board` VARCHAR( 120 ) CHARACTER SET ASCII COLLATE ascii_general_ci NOT NULL ,
CHANGE `target_board` `target_board` VARCHAR( 120 ) CHARACTER SET ASCII COLLATE ascii_general_ci NOT NULL ,
DEFAULT CHARACTER SET ASCII COLLATE ascii_general_ci;") or error(db_error());
__query("ALTER TABLE `ip_notes`
CHANGE `ip` `ip` VARCHAR( 39 ) CHARACTER SET ASCII COLLATE ascii_general_ci NOT NULL ,
CHANGE `body` `body` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;") or error(db_error());
__query("ALTER TABLE `modlogs`
CHANGE `ip` `ip` VARCHAR( 39 ) CHARACTER SET ASCII COLLATE ascii_general_ci NOT NULL ,
CHANGE `board` `board` VARCHAR( 120 ) CHARACTER SET ASCII COLLATE ascii_general_ci NULL DEFAULT NULL ,
CHANGE `text` `text` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;") or error(db_error());
__query("ALTER TABLE `mods`
CHANGE `username` `username` VARCHAR( 30 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
CHANGE `password` `password` CHAR( 64 ) CHARACTER SET ASCII COLLATE ascii_general_ci NOT NULL COMMENT 'SHA256',
CHANGE `salt` `salt` CHAR( 32 ) CHARACTER SET ASCII COLLATE ascii_general_ci NOT NULL ,
CHANGE `boards` `boards` TEXT CHARACTER SET ASCII COLLATE ascii_general_ci NOT NULL ,
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;") or error(db_error());
__query("ALTER TABLE `mutes`
CHANGE `ip` `ip` VARCHAR( 39 ) CHARACTER SET ASCII COLLATE ascii_general_ci NOT NULL ,
DEFAULT CHARACTER SET ASCII COLLATE ascii_general_ci;") or error(db_error());
__query("ALTER TABLE `news`
CHANGE `name` `name` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
CHANGE `subject` `subject` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
CHANGE `body` `body` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;") or error(db_error());
__query("ALTER TABLE `noticeboard`
CHANGE `subject` `subject` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
CHANGE `body` `body` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;") or error(db_error());
__query("ALTER TABLE `pms`
CHANGE `message` `message` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;") or error(db_error());
__query("ALTER TABLE `reports`
CHANGE `ip` `ip` VARCHAR( 39 ) CHARACTER SET ASCII COLLATE ascii_general_ci NOT NULL ,
CHANGE `board` `board` VARCHAR( 120 ) CHARACTER SET ASCII COLLATE ascii_general_ci NULL DEFAULT NULL ,
CHANGE `reason` `reason` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;") or error(db_error());
__query("ALTER TABLE `robot`
CHANGE `hash` `hash` VARCHAR( 40 ) CHARACTER SET ASCII COLLATE ascii_bin NOT NULL COMMENT 'SHA1',
DEFAULT CHARACTER SET ASCII COLLATE ascii_bin;") or error(db_error());
__query("ALTER TABLE `theme_settings`
CHANGE `theme` `theme` VARCHAR( 40 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL ,
CHANGE `name` `name` VARCHAR( 40 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL ,
CHANGE `value` `value` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL ,
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;") or eror(db_error());
case 'v0.9.6-dev-10':
query("ALTER TABLE `antispam`
CHANGE `board` `board` VARCHAR( 58 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;") or error(db_error());
query("ALTER TABLE `bans`
CHANGE `board` `board` VARCHAR( 58 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL;") or error(db_error());
query("ALTER TABLE `boards`
CHANGE `uri` `uri` VARCHAR( 58 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;") or error(db_error());
query("ALTER TABLE `cites`
CHANGE `board` `board` VARCHAR( 58 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
CHANGE `target_board` `target_board` VARCHAR( 58 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;") or error(db_error());
query("ALTER TABLE `modlogs`
CHANGE `board` `board` VARCHAR( 58 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL;") or error(db_error());
query("ALTER TABLE `mods`
CHANGE `boards` `boards` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;") or error(db_error());
query("ALTER TABLE `reports`
CHANGE `board` `board` VARCHAR( 58 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL;") or error(db_error());
case 'v0.9.6-dev-11':
case false: case false:
// Update version number // Update version number
file_write($config['has_installed'], VERSION); file_write($config['has_installed'], VERSION);
@ -554,6 +663,10 @@ if ($step == 0) {
$sql = @file_get_contents('install.sql') or error("Couldn't load install.sql."); $sql = @file_get_contents('install.sql') or error("Couldn't load install.sql.");
sql_open();
if (mysql_version() < 50503)
$sql = str_replace('utf8', 'utf8mb4', $sql);
// This code is probably horrible, but what I'm trying // This code is probably horrible, but what I'm trying
// to do is find all of the SQL queires and put them // to do is find all of the SQL queires and put them
// in an array. // in an array.

93
install.sql

@ -1,25 +1,20 @@
-- phpMyAdmin SQL Dump -- phpMyAdmin SQL Dump
-- version 3.4.2 -- version 4.0.4.1
-- http://www.phpmyadmin.net -- http://www.phpmyadmin.net
-- --
-- Host: localhost -- Host: localhost
-- Generation Time: Apr 12, 2012 at 11:22 PM -- Generation Time: Jul 30, 2013 at 09:45 PM
-- Server version: 5.1.61 -- Server version: 5.6.10
-- PHP Version: 5.3.3-7+squeeze8 -- PHP Version: 5.3.15
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00"; SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */; /*!40101 SET NAMES utf8 */;
--
-- Database: `tinyboard`
--
-- -------------------------------------------------------- -- --------------------------------------------------------
-- --
@ -27,15 +22,15 @@ SET time_zone = "+00:00";
-- --
CREATE TABLE IF NOT EXISTS `antispam` ( CREATE TABLE IF NOT EXISTS `antispam` (
`board` varchar(255) NOT NULL, `board` varchar(58) CHARACTER SET utf8 NOT NULL,
`thread` int(11) DEFAULT NULL, `thread` int(11) DEFAULT NULL,
`hash` char(40) NOT NULL, `hash` char(40) COLLATE ascii_bin NOT NULL,
`created` int(11) NOT NULL, `created` int(11) NOT NULL,
`expires` int(11) DEFAULT NULL, `expires` int(11) DEFAULT NULL,
`passed` smallint(6) NOT NULL, `passed` smallint(6) NOT NULL,
PRIMARY KEY (`hash`), PRIMARY KEY (`hash`),
KEY `board` (`board`,`thread`) KEY `board` (`board`,`thread`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8; ) ENGINE=MyISAM DEFAULT CHARSET=ascii COLLATE=ascii_bin;
-- -------------------------------------------------------- -- --------------------------------------------------------
@ -44,17 +39,17 @@ CREATE TABLE IF NOT EXISTS `antispam` (
-- --
CREATE TABLE IF NOT EXISTS `bans` ( CREATE TABLE IF NOT EXISTS `bans` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`ip` varchar(45) NOT NULL, `ip` varchar(39) CHARACTER SET ascii NOT NULL,
`mod` int(11) NOT NULL COMMENT 'which mod made the ban', `mod` int(11) NOT NULL COMMENT 'which mod made the ban',
`set` int(11) NOT NULL, `set` int(11) NOT NULL,
`expires` int(11) DEFAULT NULL, `expires` int(11) DEFAULT NULL,
`reason` text, `reason` text,
`board` varchar(120) DEFAULT NULL, `board` varchar(58) CHARACTER SET utf8 DEFAULT NULL,
`seen` tinyint(1) NOT NULL, `seen` tinyint(1) NOT NULL,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
FULLTEXT KEY `ip` (`ip`) FULLTEXT KEY `ip` (`ip`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ;
-- -------------------------------------------------------- -- --------------------------------------------------------
@ -63,18 +58,18 @@ CREATE TABLE IF NOT EXISTS `bans` (
-- --
CREATE TABLE IF NOT EXISTS `boards` ( CREATE TABLE IF NOT EXISTS `boards` (
`uri` varchar(120) NOT NULL, `uri` varchar(58) CHARACTER SET utf8 NOT NULL,
`title` tinytext NOT NULL, `title` tinytext NOT NULL,
`subtitle` tinytext, `subtitle` tinytext,
PRIMARY KEY (`uri`) PRIMARY KEY (`uri`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8; ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
-- --
-- Dumping data for table `boards` -- Dumping data for table `boards`
-- --
INSERT INTO `boards` (`uri`, `title`, `subtitle`) VALUES INSERT INTO `boards` VALUES
('b', 'Beta', 'In development.'); ('b', 'Random', NULL);
-- -------------------------------------------------------- -- --------------------------------------------------------
@ -83,9 +78,9 @@ INSERT INTO `boards` (`uri`, `title`, `subtitle`) VALUES
-- --
CREATE TABLE IF NOT EXISTS `cites` ( CREATE TABLE IF NOT EXISTS `cites` (
`board` varchar(8) NOT NULL, `board` varchar(58) NOT NULL,
`post` int(11) NOT NULL, `post` int(11) NOT NULL,
`target_board` varchar(8) NOT NULL, `target_board` varchar(58) NOT NULL,
`target` int(11) NOT NULL, `target` int(11) NOT NULL,
KEY `target` (`target_board`,`target`), KEY `target` (`target_board`,`target`),
KEY `post` (`board`,`post`) KEY `post` (`board`,`post`)
@ -98,14 +93,14 @@ CREATE TABLE IF NOT EXISTS `cites` (
-- --
CREATE TABLE IF NOT EXISTS `ip_notes` ( CREATE TABLE IF NOT EXISTS `ip_notes` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`ip` varchar(45) NOT NULL, `ip` varchar(39) CHARACTER SET ascii NOT NULL,
`mod` int(11) DEFAULT NULL, `mod` int(11) DEFAULT NULL,
`time` int(11) NOT NULL, `time` int(11) NOT NULL,
`body` text NOT NULL, `body` text NOT NULL,
UNIQUE KEY `id` (`id`), UNIQUE KEY `id` (`id`),
KEY `ip` (`ip`) KEY `ip` (`ip`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ;
-- -------------------------------------------------------- -- --------------------------------------------------------
@ -115,12 +110,12 @@ CREATE TABLE IF NOT EXISTS `ip_notes` (
CREATE TABLE IF NOT EXISTS `modlogs` ( CREATE TABLE IF NOT EXISTS `modlogs` (
`mod` int(11) NOT NULL, `mod` int(11) NOT NULL,
`ip` varchar(45) NOT NULL, `ip` varchar(39) CHARACTER SET ascii NOT NULL,
`board` varchar(120) DEFAULT NULL, `board` varchar(58) CHARACTER SET utf8 DEFAULT NULL,
`time` int(11) NOT NULL, `time` int(11) NOT NULL,
`text` text NOT NULL, `text` text NOT NULL,
KEY `time` (`time`) KEY `time` (`time`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8; ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
-- -------------------------------------------------------- -- --------------------------------------------------------
@ -131,19 +126,19 @@ CREATE TABLE IF NOT EXISTS `modlogs` (
CREATE TABLE IF NOT EXISTS `mods` ( CREATE TABLE IF NOT EXISTS `mods` (
`id` smallint(6) unsigned NOT NULL AUTO_INCREMENT, `id` smallint(6) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(30) NOT NULL, `username` varchar(30) NOT NULL,
`password` char(64) NOT NULL COMMENT 'SHA256', `password` char(64) CHARACTER SET ascii NOT NULL COMMENT 'SHA256',
`salt` char(32) NOT NULL, `salt` char(32) CHARACTER SET ascii NOT NULL,
`type` smallint(1) NOT NULL COMMENT '0: janitor, 1: mod, 2: admin', `type` smallint(1) NOT NULL COMMENT '0: janitor, 1: mod, 2: admin',
`boards` text NOT NULL, `boards` text CHARACTER SET utf8 NOT NULL,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`,`username`) UNIQUE KEY `id` (`id`,`username`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ; ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=5 ;
-- --
-- Dumping data for table `mods` -- Dumping data for table `mods`
-- --
INSERT INTO `mods` (`id`, `username`, `password`, `salt`, `type`, `boards`) VALUES INSERT INTO `mods` VALUES
(1, 'admin', 'cedad442efeef7112fed0f50b011b2b9bf83f6898082f995f69dd7865ca19fb7', '4a44c6c55df862ae901b413feecb0d49', 2, '*'); (1, 'admin', 'cedad442efeef7112fed0f50b011b2b9bf83f6898082f995f69dd7865ca19fb7', '4a44c6c55df862ae901b413feecb0d49', 2, '*');
-- -------------------------------------------------------- -- --------------------------------------------------------
@ -153,10 +148,10 @@ INSERT INTO `mods` (`id`, `username`, `password`, `salt`, `type`, `boards`) VALU
-- --
CREATE TABLE IF NOT EXISTS `mutes` ( CREATE TABLE IF NOT EXISTS `mutes` (
`ip` varchar(45) NOT NULL, `ip` varchar(39) NOT NULL,
`time` int(11) NOT NULL, `time` int(11) NOT NULL,
KEY `ip` (`ip`) KEY `ip` (`ip`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8; ) ENGINE=MyISAM DEFAULT CHARSET=ascii;
-- -------------------------------------------------------- -- --------------------------------------------------------
@ -165,14 +160,14 @@ CREATE TABLE IF NOT EXISTS `mutes` (
-- --
CREATE TABLE IF NOT EXISTS `news` ( CREATE TABLE IF NOT EXISTS `news` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` text NOT NULL, `name` text NOT NULL,
`time` int(11) NOT NULL, `time` int(11) NOT NULL,
`subject` text NOT NULL, `subject` text NOT NULL,
`body` text NOT NULL, `body` text NOT NULL,
UNIQUE KEY `id` (`id`), UNIQUE KEY `id` (`id`),
KEY `time` (`time`) KEY `time` (`time`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ;
-- -------------------------------------------------------- -- --------------------------------------------------------
@ -181,13 +176,13 @@ CREATE TABLE IF NOT EXISTS `news` (
-- --
CREATE TABLE IF NOT EXISTS `noticeboard` ( CREATE TABLE IF NOT EXISTS `noticeboard` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`mod` int(11) NOT NULL, `mod` int(11) NOT NULL,
`time` int(11) NOT NULL, `time` int(11) NOT NULL,
`subject` text NOT NULL, `subject` text NOT NULL,
`body` text NOT NULL, `body` text NOT NULL,
UNIQUE KEY `id` (`id`) UNIQUE KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ;
-- -------------------------------------------------------- -- --------------------------------------------------------
@ -196,14 +191,14 @@ CREATE TABLE IF NOT EXISTS `noticeboard` (
-- --
CREATE TABLE IF NOT EXISTS `pms` ( CREATE TABLE IF NOT EXISTS `pms` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`sender` int(11) NOT NULL, `sender` int(11) NOT NULL,
`to` int(11) NOT NULL, `to` int(11) NOT NULL,
`message` text NOT NULL, `message` text NOT NULL,
`time` int(11) NOT NULL, `time` int(11) NOT NULL,
`unread` tinyint(1) NOT NULL, `unread` tinyint(1) NOT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ;
-- -------------------------------------------------------- -- --------------------------------------------------------
@ -212,14 +207,14 @@ CREATE TABLE IF NOT EXISTS `pms` (
-- --
CREATE TABLE IF NOT EXISTS `reports` ( CREATE TABLE IF NOT EXISTS `reports` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`time` int(11) NOT NULL, `time` int(11) NOT NULL,
`ip` varchar(45) NOT NULL, `ip` varchar(39) CHARACTER SET ascii NOT NULL,
`board` varchar(120) DEFAULT NULL, `board` varchar(58) CHARACTER SET utf8 DEFAULT NULL,
`post` int(11) NOT NULL, `post` int(11) NOT NULL,
`reason` text NOT NULL, `reason` text NOT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ;
-- -------------------------------------------------------- -- --------------------------------------------------------
@ -228,9 +223,9 @@ CREATE TABLE IF NOT EXISTS `reports` (
-- --
CREATE TABLE IF NOT EXISTS `robot` ( CREATE TABLE IF NOT EXISTS `robot` (
`hash` varchar(40) NOT NULL COMMENT 'SHA1', `hash` varchar(40) COLLATE ascii_bin NOT NULL COMMENT 'SHA1',
PRIMARY KEY (`hash`) PRIMARY KEY (`hash`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8; ) ENGINE=MyISAM DEFAULT CHARSET=ascii COLLATE=ascii_bin;
-- -------------------------------------------------------- -- --------------------------------------------------------
@ -255,7 +250,7 @@ CREATE TABLE IF NOT EXISTS `theme_settings` (
`name` varchar(40) DEFAULT NULL, `name` varchar(40) DEFAULT NULL,
`value` text, `value` text,
KEY `theme` (`theme`) KEY `theme` (`theme`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8; ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;

6
js/expand.js

@ -3,7 +3,7 @@
* https://github.com/savetheinternet/Tinyboard/blob/master/js/expand.js * https://github.com/savetheinternet/Tinyboard/blob/master/js/expand.js
* *
* Released under the MIT license * Released under the MIT license
* Copyright (c) 2012 Michael Save <savetheinternet@tinyboard.org> * Copyright (c) 2012-2013 Michael Save <savetheinternet@tinyboard.org>
* *
* Usage: * Usage:
* $config['additional_javascript'][] = 'js/jquery.min.js'; * $config['additional_javascript'][] = 'js/jquery.min.js';
@ -35,10 +35,8 @@ $(document).ready(function(){
$(this).addClass('expanded').insertAfter(thread.find('div.post:first')).after('<br class="expanded">'); $(this).addClass('expanded').insertAfter(thread.find('div.post:first')).after('<br class="expanded">');
} }
last_expanded = $(this); last_expanded = $(this);
$(document).trigger('new_post', this); $(document).trigger('new_post', this);
} } else {
else {
last_expanded = post_in_doc; last_expanded = post_in_doc;
} }
}); });

2
js/inline-expanding.js

@ -21,7 +21,7 @@ onready(function(){
link[i].onclick = function(e) { link[i].onclick = function(e) {
if (this.childNodes[0].className == 'hidden') if (this.childNodes[0].className == 'hidden')
return false; return false;
if (e.which == 2) if (e.which == 2 || e.metaKey)
return true; return true;
if (!this.dataset.src) { if (!this.dataset.src) {
this.dataset.expanded = 'true'; this.dataset.expanded = 'true';

33
mod.php

@ -18,7 +18,7 @@ if (get_magic_quotes_gpc()) {
$_POST = strip_array($_POST); $_POST = strip_array($_POST);
} }
$query = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : ''; $query = isset($_SERVER['QUERY_STRING']) ? urldecode($_SERVER['QUERY_STRING']) : '';
$pages = array( $pages = array(
'' => ':?/', // redirect to dashboard '' => ':?/', // redirect to dashboard
@ -45,7 +45,7 @@ $pages = array(
'/news/(\d+)' => 'news', // view news '/news/(\d+)' => 'news', // view news
'/news/delete/(\d+)' => 'news_delete', // delete from news '/news/delete/(\d+)' => 'news_delete', // delete from news
'/edit/([\w+.]+)' => 'edit_board', // edit board details '/edit/(\%b)' => 'edit_board', // edit board details
'/new-board' => 'new_board', // create a new board '/new-board' => 'new_board', // create a new board
'/rebuild' => 'rebuild', // rebuild static files '/rebuild' => 'rebuild', // rebuild static files
@ -63,15 +63,15 @@ $pages = array(
// CSRF-protected moderator actions // CSRF-protected moderator actions
'/ban' => 'secure_POST ban', // new ban '/ban' => 'secure_POST ban', // new ban
'/([\w+.]+)/ban(&delete)?/(\d+)' => 'secure_POST ban_post', // ban poster '/(\%b)/ban(&delete)?/(\d+)' => 'secure_POST ban_post', // ban poster
'/([\w+.]+)/move/(\d+)' => 'secure_POST move', // move thread '/(\%b)/move/(\d+)' => 'secure_POST move', // move thread
'/([\w+.]+)/edit(_raw)?/(\d+)' => 'secure_POST edit_post', // edit post '/(\%b)/edit(_raw)?/(\d+)' => 'secure_POST edit_post', // edit post
'/([\w+.]+)/delete/(\d+)' => 'secure delete', // delete post '/(\%b)/delete/(\d+)' => 'secure delete', // delete post
'/([\w+.]+)/deletefile/(\d+)' => 'secure deletefile', // delete file from post '/(\%b)/deletefile/(\d+)' => 'secure deletefile', // delete file from post
'/([\w+.]+)/deletebyip/(\d+)(/global)?' => 'secure deletebyip', // delete all posts by IP address '/(\%b)/deletebyip/(\d+)(/global)?' => 'secure deletebyip', // delete all posts by IP address
'/([\w+.]+)/(un)?lock/(\d+)' => 'secure lock', // lock thread '/(\%b)/(un)?lock/(\d+)' => 'secure lock', // lock thread
'/([\w+.]+)/(un)?sticky/(\d+)' => 'secure sticky', // sticky thread '/(\%b)/(un)?sticky/(\d+)' => 'secure sticky', // sticky thread
'/([\w+.]+)/bump(un)?lock/(\d+)' => 'secure bumplock', // "bumplock" thread '/(\%b)/bump(un)?lock/(\d+)' => 'secure bumplock', // "bumplock" thread
'/themes' => 'themes_list', // manage themes '/themes' => 'themes_list', // manage themes
'/themes/(\w+)' => 'theme_configure', // configure/reconfigure theme '/themes/(\w+)' => 'theme_configure', // configure/reconfigure theme
@ -86,10 +86,10 @@ $pages = array(
'/debug/sql' => 'secure_POST debug_sql', '/debug/sql' => 'secure_POST debug_sql',
// This should always be at the end: // This should always be at the end:
'/([\w+.]+)/' => 'view_board', '/(\%b)/' => 'view_board',
'/([\w+.]+)/' . preg_quote($config['file_index'], '!') => 'view_board', '/(\%b)/' . preg_quote($config['file_index'], '!') => 'view_board',
'/([\w+.]+)/' . str_replace('%d', '(\d+)', preg_quote($config['file_page'], '!')) => 'view_board', '/(\%b)/' . str_replace('%d', '(\d+)', preg_quote($config['file_page'], '!')) => 'view_board',
'/([\w+.]+)/' . preg_quote($config['dir']['res'], '!') . '/(\%b)/' . preg_quote($config['dir']['res'], '!') .
str_replace('%d', '(\d+)', preg_quote($config['file_page'], '!')) => 'view_thread', str_replace('%d', '(\d+)', preg_quote($config['file_page'], '!')) => 'view_thread',
); );
@ -109,7 +109,8 @@ $new_pages = array();
foreach ($pages as $key => $callback) { foreach ($pages as $key => $callback) {
if (is_string($callback) && preg_match('/^secure /', $callback)) if (is_string($callback) && preg_match('/^secure /', $callback))
$key .= '(/(?P<token>[a-f0-9]{8}))?'; $key .= '(/(?P<token>[a-f0-9]{8}))?';
$new_pages[@$key[0] == '!' ? $key : '!^' . $key . '(?:&[^&=]+=[^&]*)*$!'] = $callback; $key = str_replace('\%b', $config['board_regex'], $key);
$new_pages[@$key[0] == '!' ? $key : '!^' . $key . '(?:&[^&=]+=[^&]*)*$!u'] = $callback;
} }
$pages = $new_pages; $pages = $new_pages;

11
post.php

@ -172,7 +172,7 @@ if (isset($_POST['delete'])) {
error($config['error']['bot']); error($config['error']['bot']);
// Check the referrer // Check the referrer
if (!isset($_SERVER['HTTP_REFERER']) || !preg_match($config['referer_match'], $_SERVER['HTTP_REFERER'])) if (!isset($_SERVER['HTTP_REFERER']) || !preg_match($config['referer_match'], urldecode($_SERVER['HTTP_REFERER'])))
error($config['error']['referer']); error($config['error']['referer']);
checkDNSBL(); checkDNSBL();
@ -380,7 +380,10 @@ if (isset($_POST['delete'])) {
wordfilters($post['body']); wordfilters($post['body']);
$post['body_nomarkup'] = $post['body']; if (mysql_version() >= 50503)
$post['body_nomarkup'] = $post['body']; // Assume we're using the utf8mb4 charset
else
$post['body_nomarkup'] = preg_replace('/[\x{010000}-\x{ffffff}]/u', '', $post['body']); // MySQL's `utf8` charset only supports up to 3-byte symbols
if (!($mod && isset($post['raw']) && $post['raw'])) if (!($mod && isset($post['raw']) && $post['raw']))
$post['tracked_cites'] = markup($post['body'], true); $post['tracked_cites'] = markup($post['body'], true);
@ -546,9 +549,9 @@ if (isset($_POST['delete'])) {
// Remove board directories before inserting them into the database. // Remove board directories before inserting them into the database.
if ($post['has_file']) { if ($post['has_file']) {
$post['file_path'] = $post['file']; $post['file_path'] = $post['file'];
$post['file'] = substr_replace($post['file'], '', 0, mb_strlen($board['dir'] . $config['dir']['img'])); $post['file'] = mb_substr($post['file'], mb_strlen($board['dir'] . $config['dir']['img']));
if ($is_an_image && $post['thumb'] != 'spoiler') if ($is_an_image && $post['thumb'] != 'spoiler')
$post['thumb'] = substr_replace($post['thumb'], '', 0, mb_strlen($board['dir'] . $config['dir']['thumb'])); $post['thumb'] = mb_substr($post['thumb'], mb_strlen($board['dir'] . $config['dir']['thumb']));
} }
$post = (object)$post; $post = (object)$post;

6
templates/mod/log.html

@ -18,7 +18,11 @@
{% endif %} {% endif %}
</td> </td>
<td class="minimal"> <td class="minimal">
<a href="?/IP/{{ log.ip }}">{{ log.ip }}</a> {% if mod|hasPermission(config.mod.show_ip_modlog) %}
<a href="?/IP/{{ log.ip }}">{{ log.ip }}</a>
{% else %}
<em>hidden</em>
{% endif %}
</td> </td>
<td class="minimal"> <td class="minimal">
<span title="{{ log.time|date(config.post_date) }}">{{ log.time|ago }}</span> <span title="{{ log.time|date(config.post_date) }}">{{ log.time|ago }}</span>

2
templates/post_form.html

@ -88,7 +88,7 @@
</td> </td>
</tr> </tr>
{% endif %} {% endif %}
{% if mod %} {% if mod and ((not id and post.mod|hasPermission(config.mod.sticky, board.uri)) or (not id and post.mod|hasPermission(config.mod.lock, board.uri)) or post.mod|hasPermission(config.mod.rawhtml, board.uri)) %}
<tr> <tr>
<th> <th>
{% trans %}Flags{% endtrans %} {% trans %}Flags{% endtrans %}

63
templates/posts.sql

@ -1,32 +1,33 @@
CREATE TABLE IF NOT EXISTS `posts_{{ board }}` ( CREATE TABLE IF NOT EXISTS `posts_{{ board }}` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`thread` int(11) DEFAULT NULL, `thread` int(11) DEFAULT NULL,
`subject` varchar(100) DEFAULT NULL, `subject` varchar(100) DEFAULT NULL,
`email` varchar(30) DEFAULT NULL, `email` varchar(30) DEFAULT NULL,
`name` varchar(35) DEFAULT NULL, `name` varchar(35) DEFAULT NULL,
`trip` varchar(15) DEFAULT NULL, `trip` varchar(15) DEFAULT NULL,
`capcode` varchar(50) DEFAULT NULL, `capcode` varchar(50) DEFAULT NULL,
`body` text NOT NULL, `body` text NOT NULL,
`body_nomarkup` text DEFAULT NULL, `body_nomarkup` text,
`time` int(11) NOT NULL, `time` int(11) NOT NULL,
`bump` int(11) DEFAULT NULL, `bump` int(11) DEFAULT NULL,
`thumb` varchar(50) DEFAULT NULL, `thumb` varchar(50) DEFAULT NULL,
`thumbwidth` int(11) DEFAULT NULL, `thumbwidth` int(11) DEFAULT NULL,
`thumbheight` int(11) DEFAULT NULL, `thumbheight` int(11) DEFAULT NULL,
`file` varchar(50) DEFAULT NULL, `file` varchar(50) DEFAULT NULL,
`filewidth` int(11) DEFAULT NULL, `filewidth` int(11) DEFAULT NULL,
`fileheight` int(11) DEFAULT NULL, `fileheight` int(11) DEFAULT NULL,
`filesize` int(11) DEFAULT NULL, `filesize` int(11) DEFAULT NULL,
`filename` text DEFAULT NULL, `filename` text,
`filehash` text DEFAULT NULL, `filehash` text CHARACTER SET ascii,
`password` varchar(20) DEFAULT NULL, `password` varchar(20) DEFAULT NULL,
`ip` varchar(45) NOT NULL, `ip` varchar(39) CHARACTER SET ascii NOT NULL,
`sticky` int(1) NOT NULL, `sticky` int(1) NOT NULL,
`locked` int(1) NOT NULL, `locked` int(1) NOT NULL,
`sage` int(1) NOT NULL, `sage` int(1) NOT NULL,
`embed` text, `embed` text,
UNIQUE KEY `id` (`id`), UNIQUE KEY `id` (`id`),
KEY `thread_id` (`thread`, `id`), KEY `thread_id` (`thread`,`id`),
KEY `time` (`time`), KEY `time` (`time`),
FULLTEXT KEY `body` (`body`) FULLTEXT KEY `body` (`body`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ;
Loading…
Cancel
Save