forked from GithubBackups/vichan
Merge pull request #658 from Zankaria/post-initial-refactor
Initial post refactor
This commit is contained in:
commit
4bd3fdb8a9
295
post.php
295
post.php
@ -5,6 +5,148 @@
|
||||
|
||||
require_once 'inc/bootstrap.php';
|
||||
|
||||
/**
|
||||
* Utility functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the md5 hash of the file.
|
||||
*
|
||||
* @param array $config instance configuration.
|
||||
* @param string $file file to the the md5 of.
|
||||
* @return string|false
|
||||
*/
|
||||
function md5_hash_of_file($config, $path) {
|
||||
$cmd = false;
|
||||
if ($config['bsd_md5']) {
|
||||
$cmd = '/sbin/md5 -r';
|
||||
}
|
||||
if ($config['gnu_md5']) {
|
||||
$cmd = 'md5sum';
|
||||
}
|
||||
|
||||
if ($cmd) {
|
||||
$output = shell_exec_error($cmd . " " . escapeshellarg($path));
|
||||
$output = explode(' ', $output);
|
||||
return $output[0];
|
||||
} else {
|
||||
return md5_file($path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip the symbols incompatible with the current database version.
|
||||
*
|
||||
* @param string @input The input string.
|
||||
* @return string The value stripped of incompatible symbols.
|
||||
*/
|
||||
function strip_symbols($input) {
|
||||
if (mysql_version() >= 50503) {
|
||||
return $input; // Assume we're using the utf8mb4 charset
|
||||
} else {
|
||||
// MySQL's `utf8` charset only supports up to 3-byte symbols
|
||||
// Remove anything >= 0x010000
|
||||
|
||||
$chars = preg_split('//u', $input, -1, PREG_SPLIT_NO_EMPTY);
|
||||
$ret = '';
|
||||
foreach ($chars as $char) {
|
||||
$o = 0;
|
||||
$ord = ordutf8($char, $o);
|
||||
if ($ord >= 0x010000) {
|
||||
continue;
|
||||
}
|
||||
$ret .= $char;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Download the url's target with curl.
|
||||
*
|
||||
* @param string $url Url to the file to download.
|
||||
* @param int $timeout Request timeout in seconds.
|
||||
* @param File $fd File descriptor to save the content to.
|
||||
* @return null|string Returns a string on error.
|
||||
*/
|
||||
function download_file_into($url, $timeout, $fd) {
|
||||
$err = null;
|
||||
$curl = curl_init();
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
curl_setopt($curl, CURLOPT_FAILONERROR, true);
|
||||
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false);
|
||||
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);
|
||||
curl_setopt($curl, CURLOPT_TIMEOUT, $timeout);
|
||||
curl_setopt($curl, CURLOPT_USERAGENT, 'Tinyboard');
|
||||
curl_setopt($curl, CURLOPT_FILE, $fd);
|
||||
curl_setopt($curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
|
||||
curl_setopt($curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
|
||||
|
||||
if (curl_exec($curl) === false) {
|
||||
$err = curl_error($curl);
|
||||
}
|
||||
|
||||
curl_close($curl);
|
||||
return $err;
|
||||
}
|
||||
|
||||
/**
|
||||
* Download a remote file from the given url.
|
||||
* The file is deleted at shutdown.
|
||||
*
|
||||
* @param string $file_url The url to download the file from.
|
||||
* @param int $request_timeout Timeout to retrieve the file.
|
||||
* @param array $extra_extensions Allowed file extensions.
|
||||
* @param string $tmp_dir Temporary directory to save the file into.
|
||||
* @param array $error_array An array with error codes, used to create exceptions on failure.
|
||||
* @return array Returns an array describing the file on success.
|
||||
* @throws Exception on error.
|
||||
*/
|
||||
function download_file_from_url($file_url, $request_timeout, $allowed_extensions, $tmp_dir, &$error_array) {
|
||||
if (!preg_match('@^https?://@', $file_url)) {
|
||||
throw new InvalidArgumentException($error_array['invalidimg']);
|
||||
}
|
||||
|
||||
if (mb_strpos($file_url, '?') !== false) {
|
||||
$url_without_params = mb_substr($file_url, 0, mb_strpos($file_url, '?'));
|
||||
} else {
|
||||
$url_without_params = $file_url;
|
||||
}
|
||||
|
||||
$extension = strtolower(mb_substr($url_without_params, mb_strrpos($url_without_params, '.') + 1));
|
||||
|
||||
if (!in_array($extension, $allowed_extensions)) {
|
||||
throw new InvalidArgumentException($error_array['unknownext']);
|
||||
}
|
||||
|
||||
$tmp_file = tempnam($tmp_dir, 'url');
|
||||
function unlink_tmp_file($file) {
|
||||
@unlink($file);
|
||||
fatal_error_handler();
|
||||
}
|
||||
register_shutdown_function('unlink_tmp_file', $tmp_file);
|
||||
|
||||
$fd = fopen($tmp_file, 'w');
|
||||
|
||||
$dl_err = download_file_into($tmp_file, $request_timeout, $fd);
|
||||
fclose($fd);
|
||||
if ($dl_err !== null) {
|
||||
throw new Exception($error_array['nomove'] . '<br/>Curl says: ' . $dl_err);
|
||||
}
|
||||
|
||||
return array(
|
||||
'name' => basename($url_without_params),
|
||||
'tmp_name' => $tmp_file,
|
||||
'file_tmp' => true,
|
||||
'error' => 0,
|
||||
'size' => filesize($tmp_file)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method handling functions
|
||||
*/
|
||||
|
||||
$dropped_post = false;
|
||||
|
||||
// Is it a post coming from NNTP? Let's extract it and pretend it's a normal post.
|
||||
@ -48,8 +190,8 @@ if (isset($_GET['Newsgroups']) && $config['nntpchan']['enabled']) {
|
||||
$ref = $refs[0];
|
||||
|
||||
$query = prepare("SELECT `board`,`id` FROM ``nntp_references`` WHERE `message_id` = :ref");
|
||||
$query->bindValue(':ref', $ref);
|
||||
$query->execute() or error(db_error($query));
|
||||
$query->bindValue(':ref', $ref);
|
||||
$query->execute() or error(db_error($query));
|
||||
|
||||
$ary = $query->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
@ -134,8 +276,8 @@ if (isset($_GET['Newsgroups']) && $config['nntpchan']['enabled']) {
|
||||
|
||||
$query = prepare("SELECT `board`,`id` FROM ``nntp_references`` WHERE `message_id_digest` LIKE :rule");
|
||||
$idx = $id . "%";
|
||||
$query->bindValue(':rule', $idx);
|
||||
$query->execute() or error(db_error($query));
|
||||
$query->bindValue(':rule', $idx);
|
||||
$query->execute() or error(db_error($query));
|
||||
|
||||
$ary = $query->fetchAll(PDO::FETCH_ASSOC);
|
||||
if (count($ary) == 0) {
|
||||
@ -199,7 +341,7 @@ if (isset($_POST['delete'])) {
|
||||
error($config['error']['noboard']);
|
||||
|
||||
if ((!isset($_POST['mod']) || !$_POST['mod']) && $config['board_locked']) {
|
||||
error("Board is locked");
|
||||
error("Board is locked");
|
||||
}
|
||||
|
||||
// Check if banned
|
||||
@ -266,9 +408,9 @@ if (isset($_POST['delete'])) {
|
||||
echo json_encode(array('success' => true));
|
||||
}
|
||||
|
||||
// We are already done, let's continue our heavy-lifting work in the background (if we run off FastCGI)
|
||||
if (function_exists('fastcgi_finish_request'))
|
||||
@fastcgi_finish_request();
|
||||
// We are already done, let's continue our heavy-lifting work in the background (if we run off FastCGI)
|
||||
if (function_exists('fastcgi_finish_request'))
|
||||
@fastcgi_finish_request();
|
||||
|
||||
rebuildThemes('post-delete', $board['uri']);
|
||||
|
||||
@ -290,7 +432,7 @@ if (isset($_POST['delete'])) {
|
||||
error($config['error']['noboard']);
|
||||
|
||||
if ((!isset($_POST['mod']) || !$_POST['mod']) && $config['board_locked']) {
|
||||
error("Board is locked");
|
||||
error("Board is locked");
|
||||
}
|
||||
|
||||
// Check if banned
|
||||
@ -317,7 +459,7 @@ if (isset($_POST['delete'])) {
|
||||
$resp = curl_exec($ch);
|
||||
|
||||
if ($resp !== '1') {
|
||||
error($config['error']['captcha']);
|
||||
error($config['error']['captcha']);
|
||||
}
|
||||
}
|
||||
|
||||
@ -331,11 +473,10 @@ if (isset($_POST['delete'])) {
|
||||
|
||||
$post = $query->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
$error = event('report', array('ip' => $_SERVER['REMOTE_ADDR'], 'board' => $board['uri'], 'post' => $post, 'reason' => $reason, 'link' => link_for($post)));
|
||||
|
||||
if ($error) {
|
||||
error($error);
|
||||
}
|
||||
$error = event('report', array('ip' => $_SERVER['REMOTE_ADDR'], 'board' => $board['uri'], 'post' => $post, 'reason' => $reason, 'link' => link_for($post)));
|
||||
if ($error) {
|
||||
error($error);
|
||||
}
|
||||
|
||||
if ($config['syslog'])
|
||||
_syslog(LOG_INFO, 'Reported post: ' .
|
||||
@ -372,7 +513,7 @@ if (isset($_POST['delete'])) {
|
||||
error($config['error']['noboard']);
|
||||
|
||||
if ((!isset($_POST['mod']) || !$_POST['mod']) && $config['board_locked']) {
|
||||
error("Board is locked");
|
||||
error("Board is locked");
|
||||
}
|
||||
|
||||
if (!isset($_POST['name']))
|
||||
@ -451,8 +592,8 @@ if (isset($_POST['delete'])) {
|
||||
$resp = curl_exec($ch);
|
||||
|
||||
if ($resp !== '1') {
|
||||
error($config['error']['captcha'] .
|
||||
'<script>if (actually_load_captcha !== undefined) actually_load_captcha("'.$config['captcha']['provider_get'].'", "'.$config['captcha']['extra'].'");</script>');
|
||||
error($config['error']['captcha'] .
|
||||
'<script>if (actually_load_captcha !== undefined) actually_load_captcha("'.$config['captcha']['provider_get'].'", "'.$config['captcha']['extra'].'");</script>');
|
||||
}
|
||||
}
|
||||
|
||||
@ -550,58 +691,18 @@ if (isset($_POST['delete'])) {
|
||||
}
|
||||
|
||||
if ($config['allow_upload_by_url'] && isset($_POST['file_url']) && !empty($_POST['file_url'])) {
|
||||
$post['file_url'] = $_POST['file_url'];
|
||||
if (!preg_match('@^https?://@', $post['file_url']))
|
||||
error($config['error']['invalidimg']);
|
||||
|
||||
if (mb_strpos($post['file_url'], '?') !== false)
|
||||
$url_without_params = mb_substr($post['file_url'], 0, mb_strpos($post['file_url'], '?'));
|
||||
else
|
||||
$url_without_params = $post['file_url'];
|
||||
|
||||
$post['extension'] = strtolower(mb_substr($url_without_params, mb_strrpos($url_without_params, '.') + 1));
|
||||
$allowed_extensions = $config['allowed_ext_files'];
|
||||
|
||||
// Add allowed extensions for OP, if enabled.
|
||||
if ($post['op'] && $config['allowed_ext_op']) {
|
||||
if (!in_array($post['extension'], $config['allowed_ext_op']))
|
||||
error($config['error']['unknownext']);
|
||||
array_merge($allowed_extensions, $config['allowed_ext_op']);
|
||||
}
|
||||
else if (!in_array($post['extension'], $config['allowed_ext']) && !in_array($post['extension'], $config['allowed_ext_files']))
|
||||
error($config['error']['unknownext']);
|
||||
|
||||
$post['file_tmp'] = tempnam($config['tmp'], 'url');
|
||||
function unlink_tmp_file($file) {
|
||||
@unlink($file);
|
||||
fatal_error_handler();
|
||||
try {
|
||||
$_FILES['file'] = download_file_from_url($_POST['file_url'], $config['upload_by_url_timeout'], $allowed_extensions, $config['tmp'], $config['error']);
|
||||
} catch (Exception $e) {
|
||||
error($e->getMessage());
|
||||
}
|
||||
register_shutdown_function('unlink_tmp_file', $post['file_tmp']);
|
||||
|
||||
$fp = fopen($post['file_tmp'], 'w');
|
||||
|
||||
$curl = curl_init();
|
||||
curl_setopt($curl, CURLOPT_URL, $post['file_url']);
|
||||
curl_setopt($curl, CURLOPT_FAILONERROR, true);
|
||||
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false);
|
||||
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);
|
||||
curl_setopt($curl, CURLOPT_TIMEOUT, $config['upload_by_url_timeout']);
|
||||
curl_setopt($curl, CURLOPT_USERAGENT, 'Tinyboard');
|
||||
curl_setopt($curl, CURLOPT_BINARYTRANSFER, true);
|
||||
curl_setopt($curl, CURLOPT_FILE, $fp);
|
||||
curl_setopt($curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
|
||||
|
||||
if (curl_exec($curl) === false)
|
||||
error($config['error']['nomove'] . '<br/>Curl says: ' . curl_error($curl));
|
||||
|
||||
curl_close($curl);
|
||||
|
||||
fclose($fp);
|
||||
|
||||
$_FILES['file'] = array(
|
||||
'name' => basename($url_without_params),
|
||||
'tmp_name' => $post['file_tmp'],
|
||||
'file_tmp' => true,
|
||||
'error' => 0,
|
||||
'size' => filesize($post['file_tmp'])
|
||||
);
|
||||
}
|
||||
|
||||
$post['name'] = $_POST['name'] != '' ? $_POST['name'] : $config['anonymous'];
|
||||
@ -637,7 +738,7 @@ if (isset($_POST['delete'])) {
|
||||
}
|
||||
else {
|
||||
if (!$post['op']) {
|
||||
$numposts = numPosts($post['thread']);
|
||||
$numposts = numPosts($post['thread']);
|
||||
}
|
||||
}
|
||||
|
||||
@ -795,18 +896,17 @@ if (isset($_POST['delete'])) {
|
||||
}
|
||||
}
|
||||
|
||||
if ($config['user_flag'] && isset($_POST['user_flag']))
|
||||
if (!empty($_POST['user_flag']) ){
|
||||
|
||||
if ($config['user_flag'] && isset($_POST['user_flag']) && !empty($_POST['user_flag'])) {
|
||||
$user_flag = $_POST['user_flag'];
|
||||
|
||||
if (!isset($config['user_flags'][$user_flag]))
|
||||
if (!isset($config['user_flags'][$user_flag])) {
|
||||
error(_('Invalid flag selection!'));
|
||||
}
|
||||
|
||||
$flag_alt = isset($user_flag_alt) ? $user_flag_alt : $config['user_flags'][$user_flag];
|
||||
|
||||
$post['body'] .= "\n<tinyboard flag>" . strtolower($user_flag) . "</tinyboard>" .
|
||||
"\n<tinyboard flag alt>" . $flag_alt . "</tinyboard>";
|
||||
"\n<tinyboard flag alt>" . $flag_alt . "</tinyboard>";
|
||||
}
|
||||
|
||||
if ($config['allowed_tags'] && $post['op'] && isset($_POST['tag']) && isset($config['allowed_tags'][$_POST['tag']])) {
|
||||
@ -814,37 +914,17 @@ if (isset($_POST['delete'])) {
|
||||
}
|
||||
|
||||
if (!$dropped_post)
|
||||
if ($config['proxy_save'] && isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
|
||||
if ($config['proxy_save'] && isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
|
||||
$proxy = preg_replace("/[^0-9a-fA-F.,: ]/", '', $_SERVER['HTTP_X_FORWARDED_FOR']);
|
||||
$post['body'] .= "\n<tinyboard proxy>".$proxy."</tinyboard>";
|
||||
}
|
||||
|
||||
if (mysql_version() >= 50503) {
|
||||
$post['body_nomarkup'] = $post['body']; // Assume we're using the utf8mb4 charset
|
||||
} else {
|
||||
// MySQL's `utf8` charset only supports up to 3-byte symbols
|
||||
// Remove anything >= 0x010000
|
||||
|
||||
$chars = preg_split('//u', $post['body'], -1, PREG_SPLIT_NO_EMPTY);
|
||||
$post['body_nomarkup'] = '';
|
||||
foreach ($chars as $char) {
|
||||
$o = 0;
|
||||
$ord = ordutf8($char, $o);
|
||||
if ($ord >= 0x010000)
|
||||
continue;
|
||||
$post['body_nomarkup'] .= $char;
|
||||
}
|
||||
}
|
||||
$post['body_nomarkup'] = strip_symbols($post['body']);
|
||||
|
||||
$post['tracked_cites'] = markup($post['body'], true);
|
||||
|
||||
|
||||
|
||||
if ($post['has_file']) {
|
||||
$md5cmd = false;
|
||||
if ($config['bsd_md5']) $md5cmd = '/sbin/md5 -r';
|
||||
if ($config['gnu_md5']) $md5cmd = 'md5sum';
|
||||
|
||||
$allhashes = '';
|
||||
|
||||
foreach ($post['files'] as $key => &$file) {
|
||||
@ -865,14 +945,7 @@ if (isset($_POST['delete'])) {
|
||||
if (!is_readable($upload))
|
||||
error($config['error']['nomove']);
|
||||
|
||||
if ($md5cmd) {
|
||||
$output = shell_exec_error($md5cmd . " " . escapeshellarg($upload));
|
||||
$output = explode(' ', $output);
|
||||
$hash = $output[0];
|
||||
}
|
||||
else {
|
||||
$hash = md5_file($upload);
|
||||
}
|
||||
$hash = md5_hash_of_file($config, $upload);
|
||||
|
||||
$file['hash'] = $hash;
|
||||
$allhashes .= $hash;
|
||||
@ -1038,7 +1111,7 @@ if (isset($_POST['delete'])) {
|
||||
|
||||
// Preprocess command is an ImageMagick b/w quantization
|
||||
$error = shell_exec_error(sprintf($config['tesseract_preprocess_command'], escapeshellarg($fname)) . " | " .
|
||||
'tesseract stdin '.escapeshellarg($tmpname).' '.$config['tesseract_params']);
|
||||
'tesseract stdin '.escapeshellarg($tmpname).' '.$config['tesseract_params']);
|
||||
$tmpname .= ".txt";
|
||||
|
||||
$value = @file_get_contents($tmpname);
|
||||
@ -1137,8 +1210,8 @@ if (isset($_POST['delete'])) {
|
||||
|
||||
|
||||
if ($dropped_post && $dropped_post['from_nntp']) {
|
||||
$query = prepare("INSERT INTO ``nntp_references`` (`board`, `id`, `message_id`, `message_id_digest`, `own`, `headers`) VALUES ".
|
||||
"(:board , :id , :message_id , :message_id_digest , false, :headers)");
|
||||
$query = prepare("INSERT INTO ``nntp_references`` (`board`, `id`, `message_id`, `message_id_digest`, `own`, `headers`) VALUES ".
|
||||
"(:board , :id , :message_id , :message_id_digest , false, :headers)");
|
||||
|
||||
$query->bindValue(':board', $dropped_post['board']);
|
||||
$query->bindValue(':id', $id);
|
||||
@ -1157,15 +1230,15 @@ if (isset($_POST['delete'])) {
|
||||
|
||||
$message = gen_nntp($headers, $files);
|
||||
|
||||
$query = prepare("INSERT INTO ``nntp_references`` (`board`, `id`, `message_id`, `message_id_digest`, `own`, `headers`) VALUES ".
|
||||
"(:board , :id , :message_id , :message_id_digest , true , :headers)");
|
||||
$query = prepare("INSERT INTO ``nntp_references`` (`board`, `id`, `message_id`, `message_id_digest`, `own`, `headers`) VALUES ".
|
||||
"(:board , :id , :message_id , :message_id_digest , true , :headers)");
|
||||
|
||||
$query->bindValue(':board', $post['board']);
|
||||
$query->bindValue(':id', $post['id']);
|
||||
$query->bindValue(':message_id', $msgid);
|
||||
$query->bindValue(':message_id_digest', sha1($msgid));
|
||||
$query->bindValue(':headers', json_encode($headers));
|
||||
$query->execute() or error(db_error($query));
|
||||
$query->bindValue(':id', $post['id']);
|
||||
$query->bindValue(':message_id', $msgid);
|
||||
$query->bindValue(':message_id_digest', sha1($msgid));
|
||||
$query->bindValue(':headers', json_encode($headers));
|
||||
$query->execute() or error(db_error($query));
|
||||
|
||||
// Let's broadcast it!
|
||||
nntp_publish($message, $msgid);
|
||||
|
Loading…
x
Reference in New Issue
Block a user