2011-06-15 13:11:52 -04:00
< ? php
2012-04-11 12:49:22 -04:00
/*
2014-04-12 14:12:42 -04:00
* Copyright ( c ) 2010 - 2014 Tinyboard Development Group
2012-04-11 12:49:22 -04:00
*/
2015-04-05 10:31:20 -04:00
require_once 'inc/functions.php' ;
require_once 'inc/anti-bot.php' ;
require_once 'inc/bans.php' ;
2012-04-11 12:49:22 -04:00
// Fix for magic quotes
if ( get_magic_quotes_gpc ()) {
function strip_array ( $var ) {
2012-04-12 07:56:01 -04:00
return is_array ( $var ) ? array_map ( 'strip_array' , $var ) : stripslashes ( $var );
2010-11-05 12:46:20 -04:00
}
2012-04-11 12:49:22 -04:00
$_GET = strip_array ( $_GET );
$_POST = strip_array ( $_POST );
}
2016-03-04 21:44:33 -05:00
if (( ! isset ( $_POST [ 'mod' ]) || ! $_POST [ 'mod' ])
&& ( $config [ 'board_locked' ] === true
|| ( is_array ( $config [ 'board_locked' ]) && in_array ( strtolower ( $_POST [ 'board' ]), $config [ 'board_locked' ])))){
2015-02-15 21:16:36 -05:00
error ( " Board is locked " );
}
2016-08-14 10:24:17 -04:00
$dropped_post = false ;
2016-08-14 18:56:06 -04:00
// Is it a post coming from NNTP? Let's extract it and pretend it's a normal post.
2016-08-14 10:24:17 -04:00
if ( isset ( $_GET [ 'Newsgroups' ]) && $config [ 'nntpchan' ][ 'enabled' ]) {
2016-08-14 18:56:06 -04:00
if ( $_SERVER [ 'REMOTE_ADDR' ] != $config [ 'nntpchan' ][ 'trusted_peer' ]) {
error ( " NNTPChan: Forbidden. $_SERVER[REMOTE_ADDR] is not a trusted peer " );
}
2016-08-14 10:24:17 -04:00
$_POST = array ();
$_POST [ 'json_response' ] = true ;
$headers = json_encode ( $_GET );
if ( ! isset ( $_GET [ 'Message-Id' ])) {
if ( ! isset ( $_GET [ 'Message-ID' ])) {
error ( " NNTPChan: No message ID " );
}
else $msgid = $_GET [ 'Message-ID' ];
}
else $msgid = $_GET [ 'Message-Id' ];
$groups = preg_split ( " /, \ s*/ " , $_GET [ 'Newsgroups' ]);
if ( count ( $groups ) != 1 ) {
error ( " NNTPChan: Messages can go to only one newsgroup " );
}
$group = $groups [ 0 ];
if ( ! isset ( $config [ 'nntpchan' ][ 'dispatch' ][ $group ])) {
error ( " NNTPChan: We don't synchronize $group " );
}
$xboard = $config [ 'nntpchan' ][ 'dispatch' ][ $group ];
$ref = null ;
if ( isset ( $_GET [ 'References' ])) {
$refs = preg_split ( " /, \ s*/ " , $_GET [ 'References' ]);
if ( count ( $refs ) > 1 ) {
error ( " NNTPChan: We don't support multiple references " );
}
$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 ));
$ary = $query -> fetchAll ( PDO :: FETCH_ASSOC );
if ( count ( $ary ) == 0 ) {
error ( " NNTPChan: We don't have $ref that $msgid references " );
}
$p_id = $ary [ 0 ][ 'id' ];
$p_board = $ary [ 0 ][ 'board' ];
if ( $p_board != $xboard ) {
error ( " NNTPChan: Cross board references not allowed. Tried to reference $p_board on $xboard " );
}
$_POST [ 'thread' ] = $p_id ;
}
$date = isset ( $_GET [ 'Date' ]) ? strtotime ( $_GET [ 'Date' ]) : time ();
list ( $ct ) = explode ( '; ' , $_GET [ 'Content-Type' ]);
$query = prepare ( " SELECT COUNT(*) AS `c` FROM ``nntp_references`` WHERE `message_id` = :msgid " );
$query -> bindValue ( " :msgid " , $msgid );
$query -> execute () or error ( db_error ( $query ));
$a = $query -> fetch ( PDO :: FETCH_ASSOC );
if ( $a [ 'c' ] > 0 ) {
error ( " NNTPChan: We already have this post. Post discarded. " );
}
if ( $ct == 'text/plain' ) {
$content = file_get_contents ( " php://input " );
}
elseif ( $ct == 'multipart/mixed' || $ct == 'multipart/form-data' ) {
2016-08-19 17:15:08 -04:00
_syslog ( LOG_INFO , " MM: Files: " . print_r ( $GLOBALS , true )); // Debug
2016-08-14 10:24:17 -04:00
$content = '' ;
2016-08-19 17:15:08 -04:00
$newfiles = array ();
foreach ( $_FILES [ 'attachment' ][ 'error' ] as $id => $error ) {
if ( $_FILES [ 'attachment' ][ 'type' ][ $id ] == 'text/plain' ) {
$content .= file_get_contents ( $_FILES [ 'attachment' ][ 'tmp_name' ][ $id ]);
2016-08-14 10:24:17 -04:00
}
2016-08-19 17:15:08 -04:00
elseif ( $_FILES [ 'attachment' ][ 'type' ][ $id ] == 'message/rfc822' ) { // Signed message, ignore for now
2016-08-14 10:24:17 -04:00
}
else { // A real attachment :^)
2016-08-19 17:15:08 -04:00
$file = array ();
$file [ 'name' ] = $_FILES [ 'attachment' ][ 'name' ][ $id ];
$file [ 'type' ] = $_FILES [ 'attachment' ][ 'type' ][ $id ];
$file [ 'size' ] = $_FILES [ 'attachment' ][ 'size' ][ $id ];
$file [ 'tmp_name' ] = $_FILES [ 'attachment' ][ 'tmp_name' ][ $id ];
$file [ 'error' ] = $_FILES [ 'attachment' ][ 'error' ][ $id ];
$newfiles [ " file $id " ] = $file ;
2016-08-14 10:24:17 -04:00
}
}
2016-08-19 17:15:08 -04:00
$_FILES = $newfiles ;
2016-08-14 10:24:17 -04:00
}
else {
error ( " NNTPChan: Wrong mime type: $ct " );
}
2016-08-19 17:15:08 -04:00
$_POST [ 'subject' ] = isset ( $_GET [ 'Subject' ]) ? ( $_GET [ 'Subject' ] == 'None' ? '' : $_GET [ 'Subject' ]) : '' ;
2016-08-14 10:24:17 -04:00
$_POST [ 'board' ] = $xboard ;
if ( isset ( $_GET [ 'From' ])) {
list ( $name , $mail ) = explode ( " < " , $_GET [ 'From' ], 2 );
$mail = preg_replace ( '/>\s+$/' , '' , $mail );
$_POST [ 'name' ] = $name ;
//$_POST['email'] = $mail;
$_POST [ 'email' ] = '' ;
}
if ( isset ( $_GET [ 'X_Sage' ])) {
$_POST [ 'email' ] = 'sage' ;
}
$content = preg_replace_callback ( '/>>([0-9a-fA-F]{6,})/' , function ( $id ) use ( $xboard ) {
$id = $id [ 1 ];
$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 ));
$ary = $query -> fetchAll ( PDO :: FETCH_ASSOC );
if ( count ( $ary ) == 0 ) {
return " >>>> $id " ;
}
else {
$ret = array ();
foreach ( $ary as $v ) {
if ( $v [ 'board' ] != $xboard ) {
$ret [] = " >>>/ " . $v [ 'board' ] . " / " . $v [ 'id' ];
}
else {
$ret [] = " >> " . $v [ 'id' ];
}
}
return implode ( $ret , " , " );
}
}, $content );
$_POST [ 'body' ] = $content ;
$dropped_post = array (
'date' => $date ,
'board' => $xboard ,
'msgid' => $msgid ,
'headers' => $headers ,
'from_nntp' => true ,
);
}
elseif ( isset ( $_GET [ 'Newsgroups' ])) {
error ( " NNTPChan: NNTPChan support is disabled " );
}
2012-04-12 10:18:19 -04:00
if ( isset ( $_POST [ 'delete' ])) {
2012-04-11 12:49:22 -04:00
// Delete
2012-04-12 10:18:19 -04:00
if ( ! isset ( $_POST [ 'board' ], $_POST [ 'password' ]))
2012-04-11 12:49:22 -04:00
error ( $config [ 'error' ][ 'bot' ]);
$password = & $_POST [ 'password' ];
2012-04-12 10:18:19 -04:00
if ( $password == '' )
2012-04-11 12:49:22 -04:00
error ( $config [ 'error' ][ 'invalidpassword' ]);
$delete = array ();
2012-04-12 10:18:19 -04:00
foreach ( $_POST as $post => $value ) {
if ( preg_match ( '/^delete_(\d+)$/' , $post , $m )) {
2012-04-11 12:49:22 -04:00
$delete [] = ( int ) $m [ 1 ];
2011-01-20 21:14:11 -05:00
}
2012-04-11 12:49:22 -04:00
}
checkDNSBL ();
2011-01-20 21:14:11 -05:00
2012-04-11 12:49:22 -04:00
// Check if board exists
2012-04-12 10:18:19 -04:00
if ( ! openBoard ( $_POST [ 'board' ]))
2012-04-11 12:49:22 -04:00
error ( $config [ 'error' ][ 'noboard' ]);
// Check if banned
checkBan ( $board [ 'uri' ]);
2014-05-05 18:03:51 -04:00
// Check if deletion enabled
if ( ! $config [ 'allow_delete' ])
error ( _ ( 'Post deletion is not allowed!' ));
2012-04-11 12:49:22 -04:00
2012-04-12 10:18:19 -04:00
if ( empty ( $delete ))
2012-04-11 12:49:22 -04:00
error ( $config [ 'error' ][ 'nodelete' ]);
2011-01-20 21:14:11 -05:00
2012-04-12 10:18:19 -04:00
foreach ( $delete as & $id ) {
2013-07-31 22:14:26 -04:00
$query = prepare ( sprintf ( " SELECT `thread`, `time`,`password` FROM ``posts_%s`` WHERE `id` = :id " , $board [ 'uri' ]));
2012-04-11 12:49:22 -04:00
$query -> bindValue ( ':id' , $id , PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
2011-07-26 23:40:27 -04:00
2013-07-31 20:51:43 -04:00
if ( $post = $query -> fetch ( PDO :: FETCH_ASSOC )) {
2014-05-06 15:53:05 -04:00
$thread = false ;
if ( $config [ 'user_moderation' ] && $post [ 'thread' ]) {
$thread_query = prepare ( sprintf ( " SELECT `time`,`password` FROM ``posts_%s`` WHERE `id` = :id " , $board [ 'uri' ]));
$thread_query -> bindValue ( ':id' , $post [ 'thread' ], PDO :: PARAM_INT );
$thread_query -> execute () or error ( db_error ( $query ));
$thread = $thread_query -> fetch ( PDO :: FETCH_ASSOC );
}
if ( $password != '' && $post [ 'password' ] != $password && ( ! $thread || $thread [ 'password' ] != $password ))
2012-04-11 12:49:22 -04:00
error ( $config [ 'error' ][ 'invalidpassword' ]);
2011-01-20 21:14:11 -05:00
2014-05-06 15:53:05 -04:00
if ( $post [ 'time' ] > time () - $config [ 'delete_time' ] && ( ! $thread || $thread [ 'password' ] != $password )) {
2012-04-11 12:49:22 -04:00
error ( sprintf ( $config [ 'error' ][ 'delete_too_soon' ], until ( $post [ 'time' ] + $config [ 'delete_time' ])));
}
2011-01-20 21:14:11 -05:00
2012-04-12 10:18:19 -04:00
if ( isset ( $_POST [ 'file' ])) {
2012-04-11 12:49:22 -04:00
// Delete just the file
deleteFile ( $id );
2015-02-25 20:21:49 -05:00
modLog ( " User deleted file from his own post # $id " );
2012-04-11 12:49:22 -04:00
} else {
// Delete entire post
deletePost ( $id );
2015-02-25 20:21:49 -05:00
modLog ( " User deleted his own post # $id " );
2011-01-20 21:14:11 -05:00
}
2012-04-11 12:49:22 -04:00
_syslog ( LOG_INFO , 'Deleted post: ' .
2015-03-10 07:48:59 -04:00
'/' . $board [ 'dir' ] . $config [ 'dir' ][ 'res' ] . link_for ( $post ) . ( $post [ 'thread' ] ? '#' . $id : '' )
2012-04-11 12:49:22 -04:00
);
2011-01-20 21:14:11 -05:00
}
2012-04-11 12:49:22 -04:00
}
2011-02-20 01:19:57 -05:00
2012-04-11 12:49:22 -04:00
buildIndex ();
2013-08-25 23:23:02 -04:00
2012-04-11 12:49:22 -04:00
$is_mod = isset ( $_POST [ 'mod' ]) && $_POST [ 'mod' ];
$root = $is_mod ? $config [ 'root' ] . $config [ 'file_mod' ] . '?/' : $config [ 'root' ];
2015-03-31 03:17:22 -04:00
2013-09-15 14:42:13 -04:00
if ( ! isset ( $_POST [ 'json_response' ])) {
header ( 'Location: ' . $root . $board [ 'dir' ] . $config [ 'file_index' ], true , $config [ 'redirect_http' ]);
} else {
header ( 'Content-Type: text/json' );
echo json_encode ( array ( 'success' => true ));
}
2015-03-31 03:17:22 -04:00
// 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' ]);
2012-04-12 10:18:19 -04:00
} elseif ( isset ( $_POST [ 'report' ])) {
2014-05-05 18:03:51 -04:00
if ( ! isset ( $_POST [ 'board' ], $_POST [ 'reason' ]))
2012-04-11 12:49:22 -04:00
error ( $config [ 'error' ][ 'bot' ]);
$report = array ();
2012-04-12 10:18:19 -04:00
foreach ( $_POST as $post => $value ) {
if ( preg_match ( '/^delete_(\d+)$/' , $post , $m )) {
2012-04-11 12:49:22 -04:00
$report [] = ( int ) $m [ 1 ];
2011-02-20 01:19:57 -05:00
}
2012-04-11 12:49:22 -04:00
}
checkDNSBL ();
2011-02-20 01:19:57 -05:00
2012-04-11 12:49:22 -04:00
// Check if board exists
2012-04-12 10:18:19 -04:00
if ( ! openBoard ( $_POST [ 'board' ]))
2012-04-11 12:49:22 -04:00
error ( $config [ 'error' ][ 'noboard' ]);
// Check if banned
checkBan ( $board [ 'uri' ]);
2012-04-12 10:18:19 -04:00
if ( empty ( $report ))
2012-04-11 12:49:22 -04:00
error ( $config [ 'error' ][ 'noreport' ]);
2012-04-12 10:18:19 -04:00
if ( count ( $report ) > $config [ 'report_limit' ])
2012-04-11 12:49:22 -04:00
error ( $config [ 'error' ][ 'toomanyreports' ]);
2015-03-13 00:45:57 -04:00
if ( $config [ 'report_captcha' ] && ! isset ( $_POST [ 'captcha_text' ], $_POST [ 'captcha_cookie' ])) {
error ( $config [ 'error' ][ 'bot' ]);
}
if ( $config [ 'report_captcha' ]) {
$resp = file_get_contents ( $config [ 'captcha' ][ 'provider_check' ] . " ? " . http_build_query ([
'mode' => 'check' ,
'text' => $_POST [ 'captcha_text' ],
'extra' => $config [ 'captcha' ][ 'extra' ],
'cookie' => $_POST [ 'captcha_cookie' ]
]));
if ( $resp !== '1' ) {
error ( $config [ 'error' ][ 'captcha' ]);
}
}
2012-04-11 12:49:22 -04:00
2013-07-31 18:59:54 -04:00
$reason = escape_markup_modifiers ( $_POST [ 'reason' ]);
2012-04-11 12:49:22 -04:00
markup ( $reason );
2012-04-12 10:18:19 -04:00
foreach ( $report as & $id ) {
2016-09-25 03:34:47 -04:00
$query = prepare ( sprintf ( " SELECT `id`,`thread` , `body_nomarkup` FROM ``posts_%s`` WHERE `id` = :id " , $board [ 'uri' ]));
2012-04-11 12:49:22 -04:00
$query -> bindValue ( ':id' , $id , PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
2016-09-23 09:44:48 -04:00
$thread = $query -> fetch ( PDO :: FETCH_ASSOC );
2012-04-11 12:49:22 -04:00
2013-08-11 07:22:25 -04:00
if ( $config [ 'syslog' ])
_syslog ( LOG_INFO , 'Reported post: ' .
2016-09-23 09:44:48 -04:00
'/' . $board [ 'dir' ] . $config [ 'dir' ][ 'res' ] . link_for ( $post ) . ( $thread [ 'thread' ] ? '#' . $id : '' ) .
2013-08-11 07:22:25 -04:00
' for "' . $reason . '"'
);
$query = prepare ( " INSERT INTO ``reports`` VALUES (NULL, :time, :ip, :board, :post, :reason) " );
$query -> bindValue ( ':time' , time (), PDO :: PARAM_INT );
$query -> bindValue ( ':ip' , $_SERVER [ 'REMOTE_ADDR' ], PDO :: PARAM_STR );
$query -> bindValue ( ':board' , $board [ 'uri' ], PDO :: PARAM_INT );
$query -> bindValue ( ':post' , $id , PDO :: PARAM_INT );
$query -> bindValue ( ':reason' , $reason , PDO :: PARAM_STR );
$query -> execute () or error ( db_error ( $query ));
2016-10-01 12:15:34 -04:00
if ( $config [ 'slack' ])
{
function slack ( $message , $room = " reports " , $icon = " :no_entry_sign: " )
{
$room = ( $room ) ? $room : " reports " ;
$data = " payload= " . json_encode ( array (
" channel " => " # { $room } " ,
" text " => urlencode ( $message ),
" icon_emoji " => $icon
));
// You can get your webhook endpoint from your Slack settings
// For some reason using the configuration key doesn't work
$ch = curl_init ( $config [ 'slack_incoming_webhook_endpoint' ]);
curl_setopt ( $ch , CURLOPT_SSL_VERIFYPEER , false );
curl_setopt ( $ch , CURLOPT_CUSTOMREQUEST , " POST " );
curl_setopt ( $ch , CURLOPT_POSTFIELDS , $data );
curl_setopt ( $ch , CURLOPT_RETURNTRANSFER , true );
$result = curl_exec ( $ch );
curl_close ( $ch );
return $result ;
}
2016-09-23 09:44:48 -04:00
$postcontent = mb_substr ( $thread [ 'body_nomarkup' ], 0 , 120 ) . '... _*(POST TRIMMED)*_' ;
2016-09-23 23:52:08 -04:00
$slackmessage = '<' . $config [ 'domain' ] . " /mod.php?/ " . $board [ 'dir' ] . $config [ 'dir' ][ 'res' ] . ( $thread [ 'thread' ] ? $thread [ 'thread' ] : $id ) . " .html " . ( $thread [ 'thread' ] ? '#' . $id : '' ) . '> \n ' . $reason . '\n ' . $postcontent . '\n' ;
2016-09-23 09:44:48 -04:00
$slackresult = slack ( $slackmessage , $config [ 'slack_channel' ]);
2016-10-01 12:15:34 -04:00
}
2016-09-23 09:44:48 -04:00
2012-04-11 12:49:22 -04:00
}
$is_mod = isset ( $_POST [ 'mod' ]) && $_POST [ 'mod' ];
$root = $is_mod ? $config [ 'root' ] . $config [ 'file_mod' ] . '?/' : $config [ 'root' ];
2013-09-15 14:42:13 -04:00
if ( ! isset ( $_POST [ 'json_response' ])) {
2015-03-13 00:45:57 -04:00
$index = $root . $board [ 'dir' ] . $config [ 'file_index' ];
2017-03-01 21:25:45 -05:00
$reported_post = $root . $board [ 'dir' ] . $config [ 'dir' ][ 'res' ] . ( $thread [ 'thread' ] ? $thread [ 'thread' ] : $id ) . " .html " . ( $thread [ 'thread' ] ? '#' . $id : '' ) ;
header ( 'Location: ' . $reported_post );
//echo Element('page.html', array('config' => $config, 'body' => '<div style="text-align:center"><a href="javascript:window.close()">[ ' . _('Close window') ." ]</a> <a href='$index'>[ " . _('Return') . ' ]</a></div>', 'title' => _('Report submitted!')));
2013-09-15 14:42:13 -04:00
} else {
header ( 'Content-Type: text/json' );
echo json_encode ( array ( 'success' => true ));
}
2016-08-14 10:24:17 -04:00
} elseif ( isset ( $_POST [ 'post' ]) || $dropped_post ) {
if ( ! isset ( $_POST [ 'body' ], $_POST [ 'board' ]) && ! $dropped_post )
2012-04-11 12:49:22 -04:00
error ( $config [ 'error' ][ 'bot' ]);
2014-04-18 08:32:05 -04:00
2014-04-27 09:48:47 -04:00
$post = array ( 'board' => $_POST [ 'board' ], 'files' => array ());
2014-04-18 08:33:50 -04:00
2014-04-18 08:32:05 -04:00
// Check if board exists
if ( ! openBoard ( $post [ 'board' ]))
error ( $config [ 'error' ][ 'noboard' ]);
2012-04-11 12:49:22 -04:00
2012-04-12 10:18:19 -04:00
if ( ! isset ( $_POST [ 'name' ]))
2012-04-11 12:49:22 -04:00
$_POST [ 'name' ] = $config [ 'anonymous' ];
2012-04-12 10:18:19 -04:00
if ( ! isset ( $_POST [ 'email' ]))
2012-04-11 12:49:22 -04:00
$_POST [ 'email' ] = '' ;
2012-08-30 06:07:23 -04:00
if ( ! isset ( $_POST [ 'subject' ]))
$_POST [ 'subject' ] = '' ;
2012-04-12 10:18:19 -04:00
if ( ! isset ( $_POST [ 'password' ]))
2014-04-18 08:33:50 -04:00
$_POST [ 'password' ] = '' ;
2012-04-11 12:49:22 -04:00
2012-04-12 10:18:19 -04:00
if ( isset ( $_POST [ 'thread' ])) {
2012-04-11 12:49:22 -04:00
$post [ 'op' ] = false ;
$post [ 'thread' ] = round ( $_POST [ 'thread' ]);
} else
$post [ 'op' ] = true ;
2014-04-18 08:32:05 -04:00
2016-08-14 10:24:17 -04:00
if ( ! $dropped_post ) {
// Check for CAPTCHA right after opening the board so the "return" link is in there
if ( $config [ 'recaptcha' ]) {
if ( ! isset ( $_POST [ 'recaptcha_challenge_field' ]) || ! isset ( $_POST [ 'recaptcha_response_field' ]))
error ( $config [ 'error' ][ 'bot' ]);
// Check what reCAPTCHA has to say...
$resp = recaptcha_check_answer ( $config [ 'recaptcha_private' ],
$_SERVER [ 'REMOTE_ADDR' ],
$_POST [ 'recaptcha_challenge_field' ],
$_POST [ 'recaptcha_response_field' ]);
if ( ! $resp -> is_valid ) {
error ( $config [ 'error' ][ 'captcha' ]);
}
2011-02-16 04:37:57 -05:00
}
2014-10-06 06:35:37 -04:00
2016-08-14 10:24:17 -04:00
if ( ! (( $post [ 'op' ] && $_POST [ 'post' ] == $config [ 'button_newtopic' ]) ||
( ! $post [ 'op' ] && $_POST [ 'post' ] == $config [ 'button_reply' ])))
error ( $config [ 'error' ][ 'bot' ]);
2014-10-06 06:35:37 -04:00
2016-08-14 10:24:17 -04:00
// Check the referrer
if ( $config [ 'referer_match' ] !== false &&
( ! isset ( $_SERVER [ 'HTTP_REFERER' ]) || ! preg_match ( $config [ 'referer_match' ], rawurldecode ( $_SERVER [ 'HTTP_REFERER' ]))))
error ( $config [ 'error' ][ 'referer' ]);
2013-07-20 22:47:26 -04:00
2016-08-14 10:24:17 -04:00
checkDNSBL ();
2014-10-06 06:35:37 -04:00
2016-08-14 10:24:17 -04:00
// Check if banned
checkBan ( $board [ 'uri' ]);
2014-10-06 06:35:37 -04:00
2016-08-14 10:24:17 -04:00
if ( $post [ 'mod' ] = isset ( $_POST [ 'mod' ]) && $_POST [ 'mod' ]) {
check_login ( false );
if ( ! $mod ) {
// Liar. You're not a mod.
error ( $config [ 'error' ][ 'notamod' ]);
}
2012-04-12 07:56:01 -04:00
2016-08-14 10:24:17 -04:00
$post [ 'sticky' ] = $post [ 'op' ] && isset ( $_POST [ 'sticky' ]);
$post [ 'locked' ] = $post [ 'op' ] && isset ( $_POST [ 'lock' ]);
$post [ 'raw' ] = isset ( $_POST [ 'raw' ]);
2012-04-12 07:56:01 -04:00
2016-08-14 10:24:17 -04:00
if ( $post [ 'sticky' ] && ! hasPermission ( $config [ 'mod' ][ 'sticky' ], $board [ 'uri' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
if ( $post [ 'locked' ] && ! hasPermission ( $config [ 'mod' ][ 'lock' ], $board [ 'uri' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
if ( $post [ 'raw' ] && ! hasPermission ( $config [ 'mod' ][ 'rawhtml' ], $board [ 'uri' ]))
error ( $config [ 'error' ][ 'noaccess' ]);
}
if ( ! $post [ 'mod' ]) {
$post [ 'antispam_hash' ] = checkSpam ( array ( $board [ 'uri' ], isset ( $post [ 'thread' ]) ? $post [ 'thread' ] : ( $config [ 'try_smarter' ] && isset ( $_POST [ 'page' ]) ? 0 - ( int ) $_POST [ 'page' ] : null )));
if ( $post [ 'antispam_hash' ] === true )
error ( $config [ 'error' ][ 'spam' ]);
}
2012-04-12 07:56:01 -04:00
2016-08-14 10:24:17 -04:00
if ( $config [ 'robot_enable' ] && $config [ 'robot_mute' ]) {
checkMute ();
}
2012-05-07 09:51:15 -04:00
}
2016-08-14 10:24:17 -04:00
else {
$mod = $post [ 'mod' ] = false ;
2012-04-11 12:49:22 -04:00
}
//Check if thread exists
2012-04-12 10:18:19 -04:00
if ( ! $post [ 'op' ]) {
2015-04-03 02:56:28 -04:00
$query = prepare ( sprintf ( " SELECT `sticky`,`locked`,`cycle`,`sage`,`slug` FROM ``posts_%s`` WHERE `id` = :id AND `thread` IS NULL LIMIT 1 " , $board [ 'uri' ]));
2012-04-11 12:49:22 -04:00
$query -> bindValue ( ':id' , $post [ 'thread' ], PDO :: PARAM_INT );
$query -> execute () or error ( db_error ());
2013-07-31 20:51:43 -04:00
if ( ! $thread = $query -> fetch ( PDO :: FETCH_ASSOC )) {
2012-04-11 12:49:22 -04:00
// Non-existant
error ( $config [ 'error' ][ 'nonexistant' ]);
2011-10-10 11:58:22 -04:00
}
2012-04-11 12:49:22 -04:00
}
2015-03-10 07:48:59 -04:00
else {
$thread = false ;
}
2011-05-18 03:05:48 -04:00
2012-04-11 12:49:22 -04:00
// Check for an embed field
2012-04-12 10:18:19 -04:00
if ( $config [ 'enable_embedding' ] && isset ( $_POST [ 'embed' ]) && ! empty ( $_POST [ 'embed' ])) {
2012-04-11 12:49:22 -04:00
// yep; validate it
$value = $_POST [ 'embed' ];
2012-04-12 10:18:19 -04:00
foreach ( $config [ 'embedding' ] as & $embed ) {
2013-07-19 18:36:12 -04:00
if ( preg_match ( $embed [ 0 ], $value )) {
// Valid link
$post [ 'embed' ] = $value ;
// This is bad, lol.
2012-04-11 12:49:22 -04:00
$post [ 'no_longer_require_an_image_for_op' ] = true ;
break ;
2011-05-18 03:05:48 -04:00
}
2010-11-05 12:46:20 -04:00
}
2012-04-12 10:18:19 -04:00
if ( ! isset ( $post [ 'embed' ])) {
2012-04-11 12:49:22 -04:00
error ( $config [ 'error' ][ 'invalid_embed' ]);
2011-02-21 19:09:43 -05:00
}
2012-04-11 12:49:22 -04:00
}
2012-04-12 10:18:19 -04:00
if ( ! hasPermission ( $config [ 'mod' ][ 'bypass_field_disable' ], $board [ 'uri' ])) {
if ( $config [ 'field_disable_name' ])
2012-04-11 12:49:22 -04:00
$_POST [ 'name' ] = $config [ 'anonymous' ]; // "forced anonymous"
2012-04-12 10:18:19 -04:00
if ( $config [ 'field_disable_email' ])
2012-04-11 12:49:22 -04:00
$_POST [ 'email' ] = '' ;
2012-04-12 10:18:19 -04:00
if ( $config [ 'field_disable_password' ])
2012-04-11 12:49:22 -04:00
$_POST [ 'password' ] = '' ;
2012-08-30 06:07:23 -04:00
if ( $config [ 'field_disable_subject' ] || ( ! $post [ 'op' ] && $config [ 'field_disable_reply_subject' ]))
$_POST [ 'subject' ] = '' ;
2012-04-11 12:49:22 -04:00
}
2013-08-12 08:51:46 -04:00
if ( $config [ 'allow_upload_by_url' ] && isset ( $_POST [ 'file_url' ]) && ! empty ( $_POST [ 'file_url' ])) {
$post [ 'file_url' ] = $_POST [ 'file_url' ];
2013-09-14 15:48:37 -04:00
if ( ! preg_match ( '@^https?://@' , $post [ 'file_url' ]))
2013-08-12 08:51:46 -04:00
error ( $config [ 'error' ][ 'invalidimg' ]);
2013-08-25 22:13:40 -04:00
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 ));
2015-04-21 23:54:48 -04:00
if ( $post [ 'op' ] && $config [ 'allowed_ext_op' ]) {
if ( ! in_array ( $post [ 'extension' ], $config [ 'allowed_ext_op' ]))
error ( $config [ 'error' ][ 'unknownext' ]);
}
else if ( ! in_array ( $post [ 'extension' ], $config [ 'allowed_ext' ]) && ! in_array ( $post [ 'extension' ], $config [ 'allowed_ext_files' ]))
2013-08-12 08:51:46 -04:00
error ( $config [ 'error' ][ 'unknownext' ]);
$post [ 'file_tmp' ] = tempnam ( $config [ 'tmp' ], 'url' );
2013-08-12 09:35:27 -04:00
function unlink_tmp_file ( $file ) {
@ unlink ( $file );
2013-08-26 18:13:23 -04:00
fatal_error_handler ();
2013-08-12 09:35:27 -04:00
}
register_shutdown_function ( 'unlink_tmp_file' , $post [ 'file_tmp' ]);
2013-08-12 08:51:46 -04:00
$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 );
2013-08-19 04:54:10 -04:00
curl_setopt ( $curl , CURLOPT_TIMEOUT , $config [ 'upload_by_url_timeout' ]);
2013-08-12 08:51:46 -04:00
curl_setopt ( $curl , CURLOPT_USERAGENT , 'Tinyboard' );
curl_setopt ( $curl , CURLOPT_BINARYTRANSFER , true );
curl_setopt ( $curl , CURLOPT_FILE , $fp );
2013-08-12 10:07:23 -04:00
curl_setopt ( $curl , CURLOPT_PROTOCOLS , CURLPROTO_HTTP | CURLPROTO_HTTPS );
2013-08-12 08:51:46 -04:00
if ( curl_exec ( $curl ) === false )
2014-05-27 19:45:05 -04:00
error ( $config [ 'error' ][ 'nomove' ] . '<br/>Curl says: ' . curl_error ( $curl ));
2013-08-12 08:51:46 -04:00
curl_close ( $curl );
fclose ( $fp );
$_FILES [ 'file' ] = array (
2013-08-25 22:13:40 -04:00
'name' => basename ( $url_without_params ),
2013-08-12 08:51:46 -04:00
'tmp_name' => $post [ 'file_tmp' ],
2014-04-29 14:50:28 -04:00
'file_tmp' => true ,
2013-08-12 08:51:46 -04:00
'error' => 0 ,
'size' => filesize ( $post [ 'file_tmp' ])
);
}
2012-04-11 12:49:22 -04:00
$post [ 'name' ] = $_POST [ 'name' ] != '' ? $_POST [ 'name' ] : $config [ 'anonymous' ];
$post [ 'subject' ] = $_POST [ 'subject' ];
2012-08-26 12:18:31 -04:00
$post [ 'email' ] = str_replace ( ' ' , '%20' , htmlspecialchars ( $_POST [ 'email' ]));
2012-04-11 12:49:22 -04:00
$post [ 'body' ] = $_POST [ 'body' ];
$post [ 'password' ] = $_POST [ 'password' ];
2016-08-14 10:24:17 -04:00
$post [ 'has_file' ] = ( ! isset ( $post [ 'embed' ]) && (( $post [ 'op' ] && ! isset ( $post [ 'no_longer_require_an_image_for_op' ]) && $config [ 'force_image_op' ]) || count ( $_FILES ) > 0 ));
2012-04-11 12:49:22 -04:00
2016-08-14 10:24:17 -04:00
if ( ! $dropped_post ) {
if ( ! ( $post [ 'has_file' ] || isset ( $post [ 'embed' ])) || (( $post [ 'op' ] && $config [ 'force_body_op' ]) || ( ! $post [ 'op' ] && $config [ 'force_body' ]))) {
$stripped_whitespace = preg_replace ( '/[\s]/u' , '' , $post [ 'body' ]);
if ( $stripped_whitespace == '' ) {
error ( $config [ 'error' ][ 'tooshort_body' ]);
}
2011-01-18 20:37:31 -05:00
}
2012-04-11 12:49:22 -04:00
2016-08-14 10:24:17 -04:00
if ( ! $post [ 'op' ]) {
// Check if thread is locked
// but allow mods to post
if ( $thread [ 'locked' ] && ! hasPermission ( $config [ 'mod' ][ 'postinlocked' ], $board [ 'uri' ]))
error ( $config [ 'error' ][ 'locked' ]);
2013-06-18 13:21:41 -04:00
2016-08-14 10:24:17 -04:00
$numposts = numPosts ( $post [ 'thread' ]);
2013-06-18 13:21:41 -04:00
2016-08-14 10:24:17 -04:00
if ( $config [ 'reply_hard_limit' ] != 0 && $config [ 'reply_hard_limit' ] <= $numposts [ 'replies' ])
error ( $config [ 'error' ][ 'reply_hard_limit' ]);
2013-06-18 13:21:41 -04:00
2016-08-14 10:24:17 -04:00
if ( $post [ 'has_file' ] && $config [ 'image_hard_limit' ] != 0 && $config [ 'image_hard_limit' ] <= $numposts [ 'images' ])
error ( $config [ 'error' ][ 'image_hard_limit' ]);
}
}
else {
if ( ! $post [ 'op' ]) {
$numposts = numPosts ( $post [ 'thread' ]);
}
2012-04-11 12:49:22 -04:00
}
2013-06-18 13:21:41 -04:00
2012-04-12 10:18:19 -04:00
if ( $post [ 'has_file' ]) {
2014-04-27 09:48:47 -04:00
// Determine size sanity
$size = 0 ;
if ( $config [ 'multiimage_method' ] == 'split' ) {
foreach ( $_FILES as $key => $file ) {
$size += $file [ 'size' ];
}
} elseif ( $config [ 'multiimage_method' ] == 'each' ) {
foreach ( $_FILES as $key => $file ) {
if ( $file [ 'size' ] > $size ) {
$size = $file [ 'size' ];
}
}
} else {
error ( _ ( 'Unrecognized file size determination method.' ));
}
2012-04-12 10:18:19 -04:00
if ( $size > $config [ 'max_filesize' ])
2012-04-11 12:49:22 -04:00
error ( sprintf3 ( $config [ 'error' ][ 'filesize' ], array (
'sz' => number_format ( $size ),
'filesz' => number_format ( $size ),
'maxsz' => number_format ( $config [ 'max_filesize' ])
)));
2014-04-27 09:48:47 -04:00
$post [ 'filesize' ] = $size ;
2012-04-11 12:49:22 -04:00
}
2012-05-07 04:22:20 -04:00
$post [ 'capcode' ] = false ;
if ( $mod && preg_match ( '/^((.+) )?## (.+)$/' , $post [ 'name' ], $matches )) {
$name = $matches [ 2 ] != '' ? $matches [ 2 ] : $config [ 'anonymous' ];
$cap = $matches [ 3 ];
if ( isset ( $config [ 'mod' ][ 'capcode' ][ $mod [ 'type' ]])) {
if ( $config [ 'mod' ][ 'capcode' ][ $mod [ 'type' ]] === true ||
( is_array ( $config [ 'mod' ][ 'capcode' ][ $mod [ 'type' ]]) &&
in_array ( $cap , $config [ 'mod' ][ 'capcode' ][ $mod [ 'type' ]])
)) {
$post [ 'capcode' ] = utf8tohtml ( $cap );
$post [ 'name' ] = $name ;
}
2010-11-05 12:46:20 -04:00
}
2012-04-11 12:49:22 -04:00
}
$trip = generate_tripcode ( $post [ 'name' ]);
$post [ 'name' ] = $trip [ 0 ];
2016-08-14 10:24:17 -04:00
$post [ 'trip' ] = isset ( $trip [ 1 ]) ? $trip [ 1 ] : '' ; // XX: Dropped posts and tripcodes
2012-04-11 12:49:22 -04:00
2013-12-23 12:42:01 -05:00
$noko = false ;
2012-04-12 10:18:19 -04:00
if ( strtolower ( $post [ 'email' ]) == 'noko' ) {
2012-04-11 12:49:22 -04:00
$noko = true ;
$post [ 'email' ] = '' ;
2013-12-20 17:52:54 -05:00
} elseif ( strtolower ( $post [ 'email' ]) == 'nonoko' ){
$noko = false ;
$post [ 'email' ] = '' ;
2013-12-23 12:42:01 -05:00
} else $noko = $config [ 'always_noko' ];
2012-04-11 12:49:22 -04:00
2012-04-12 10:18:19 -04:00
if ( $post [ 'has_file' ]) {
2014-04-27 09:48:47 -04:00
$i = 0 ;
foreach ( $_FILES as $key => $file ) {
if ( $file [ 'size' ] && $file [ 'tmp_name' ]) {
2016-05-05 04:29:13 -04:00
$file [ 'filename' ] = urldecode ( $file [ 'name' ]);
2014-04-27 09:48:47 -04:00
$file [ 'extension' ] = strtolower ( mb_substr ( $file [ 'filename' ], mb_strrpos ( $file [ 'filename' ], '.' ) + 1 ));
if ( isset ( $config [ 'filename_func' ]))
$file [ 'file_id' ] = $config [ 'filename_func' ]( $file );
else
$file [ 'file_id' ] = time () . substr ( microtime (), 2 , 3 );
if ( sizeof ( $_FILES ) > 1 )
$file [ 'file_id' ] .= " - $i " ;
$file [ 'file' ] = $board [ 'dir' ] . $config [ 'dir' ][ 'img' ] . $file [ 'file_id' ] . '.' . $file [ 'extension' ];
$file [ 'thumb' ] = $board [ 'dir' ] . $config [ 'dir' ][ 'thumb' ] . $file [ 'file_id' ] . '.' . ( $config [ 'thumb_ext' ] ? $config [ 'thumb_ext' ] : $file [ 'extension' ]);
$post [ 'files' ][] = $file ;
$i ++ ;
}
}
2012-04-11 12:49:22 -04:00
}
2014-04-27 09:48:47 -04:00
if ( empty ( $post [ 'files' ])) $post [ 'has_file' ] = false ;
2016-08-14 10:24:17 -04:00
if ( ! $dropped_post ) {
// Check for a file
if ( $post [ 'op' ] && ! isset ( $post [ 'no_longer_require_an_image_for_op' ])) {
if ( ! $post [ 'has_file' ] && $config [ 'force_image_op' ])
error ( $config [ 'error' ][ 'noimage' ]);
}
2014-04-27 09:48:47 -04:00
2016-08-14 10:24:17 -04:00
// Check for too many files
if ( sizeof ( $post [ 'files' ]) > $config [ 'max_images' ])
error ( $config [ 'error' ][ 'toomanyimages' ]);
}
2014-04-27 09:48:47 -04:00
2013-07-28 20:33:26 -04:00
if ( $config [ 'strip_combining_chars' ]) {
$post [ 'name' ] = strip_combining_chars ( $post [ 'name' ]);
$post [ 'email' ] = strip_combining_chars ( $post [ 'email' ]);
2013-07-28 20:46:00 -04:00
$post [ 'subject' ] = strip_combining_chars ( $post [ 'subject' ]);
2013-07-28 20:33:26 -04:00
$post [ 'body' ] = strip_combining_chars ( $post [ 'body' ]);
}
2016-08-14 10:24:17 -04:00
if ( ! $dropped_post ) {
// Check string lengths
if ( mb_strlen ( $post [ 'name' ]) > 35 )
error ( sprintf ( $config [ 'error' ][ 'toolong' ], 'name' ));
if ( mb_strlen ( $post [ 'email' ]) > 40 )
error ( sprintf ( $config [ 'error' ][ 'toolong' ], 'email' ));
if ( mb_strlen ( $post [ 'subject' ]) > 100 )
error ( sprintf ( $config [ 'error' ][ 'toolong' ], 'subject' ));
if ( ! $mod && mb_strlen ( $post [ 'body' ]) > $config [ 'max_body' ])
error ( $config [ 'error' ][ 'toolong_body' ]);
2017-03-03 01:25:30 -05:00
if ( ! $mod && mb_strlen ( $post [ 'body' ]) > 0 && ( mb_strlen ( $post [ 'body' ]) < $config [ 'min_body' ]))
2017-01-17 08:55:46 -05:00
error ( $config [ 'error' ][ 'tooshort_body' ]);
2016-08-14 10:24:17 -04:00
if ( mb_strlen ( $post [ 'password' ]) > 20 )
error ( sprintf ( $config [ 'error' ][ 'toolong' ], 'password' ));
}
2012-04-11 12:49:22 -04:00
wordfilters ( $post [ 'body' ]);
2013-08-31 12:04:42 -04:00
2013-07-31 18:59:54 -04:00
$post [ 'body' ] = escape_markup_modifiers ( $post [ 'body' ]);
2012-04-11 12:49:22 -04:00
2013-07-31 19:18:55 -04:00
if ( $mod && isset ( $post [ 'raw' ]) && $post [ 'raw' ]) {
2013-08-16 13:39:58 -04:00
$post [ 'body' ] .= " \n <tinyboard raw html>1</tinyboard> " ;
2013-08-16 07:25:56 -04:00
}
2016-08-14 10:24:17 -04:00
if ( ! $dropped_post )
2014-09-20 11:21:50 -04:00
if (( $config [ 'country_flags' ] && ! $config [ 'allow_no_country' ]) || ( $config [ 'country_flags' ] && $config [ 'allow_no_country' ] && ! isset ( $_POST [ 'no_country' ]))) {
2014-07-05 20:13:08 -04:00
require 'inc/lib/geoip/geoip.inc' ;
$gi = geoip\geoip_open ( 'inc/lib/geoip/GeoIPv6.dat' , GEOIP_STANDARD );
function ipv4to6 ( $ip ) {
if ( strpos ( $ip , ':' ) !== false ) {
if ( strpos ( $ip , '.' ) > 0 )
$ip = substr ( $ip , strrpos ( $ip , ':' ) + 1 );
else return $ip ; //native ipv6
}
$iparr = array_pad ( explode ( '.' , $ip ), 4 , 0 );
$part7 = base_convert (( $iparr [ 0 ] * 256 ) + $iparr [ 1 ], 10 , 16 );
$part8 = base_convert (( $iparr [ 2 ] * 256 ) + $iparr [ 3 ], 10 , 16 );
return '::ffff:' . $part7 . ':' . $part8 ;
}
if ( $country_code = geoip\geoip_country_code_by_addr_v6 ( $gi , ipv4to6 ( $_SERVER [ 'REMOTE_ADDR' ]))) {
if ( ! in_array ( strtolower ( $country_code ), array ( 'eu' , 'ap' , 'o1' , 'a1' , 'a2' )))
$post [ 'body' ] .= " \n <tinyboard flag> " . strtolower ( $country_code ) . " </tinyboard> " .
" \n <tinyboard flag alt> " . geoip\geoip_country_name_by_addr_v6 ( $gi , ipv4to6 ( $_SERVER [ 'REMOTE_ADDR' ])) . " </tinyboard> " ;
}
2013-07-31 19:18:55 -04:00
}
2015-03-24 00:19:25 -04:00
2014-04-19 08:56:59 -04:00
if ( $config [ 'user_flag' ] && isset ( $_POST [ 'user_flag' ]))
if ( ! empty ( $_POST [ 'user_flag' ]) ){
$user_flag = $_POST [ 'user_flag' ];
if ( ! isset ( $config [ 'user_flags' ][ $user_flag ]))
2014-04-27 09:48:47 -04:00
error ( _ ( 'Invalid flag selection!' ));
2014-04-19 08:56:59 -04:00
$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> " ;
}
2015-03-24 00:19:25 -04:00
2015-04-22 20:41:17 -04:00
if ( $config [ 'allowed_tags' ] && $post [ 'op' ] && isset ( $_POST [ 'tag' ]) && isset ( $config [ 'allowed_tags' ][ $_POST [ 'tag' ]])) {
2015-04-21 23:54:48 -04:00
$post [ 'body' ] .= " \n <tinyboard tag> " . $_POST [ 'tag' ] . " </tinyboard> " ;
}
2016-08-14 10:24:17 -04:00
if ( ! $dropped_post )
2015-03-24 00:19:25 -04:00
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> " ;
}
2014-04-19 08:56:59 -04:00
2013-07-31 12:05:19 -04:00
if ( mysql_version () >= 50503 ) {
2013-07-30 22:08:56 -04:00
$post [ 'body_nomarkup' ] = $post [ 'body' ]; // Assume we're using the utf8mb4 charset
2013-07-31 12:05:19 -04:00
} 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 ;
}
}
2012-04-11 12:49:22 -04:00
2013-07-31 19:18:55 -04:00
$post [ 'tracked_cites' ] = markup ( $post [ 'body' ], true );
2013-09-06 09:09:18 -04:00
2012-04-11 12:49:22 -04:00
2012-04-12 10:18:19 -04:00
if ( $post [ 'has_file' ]) {
2016-05-05 02:21:21 -04:00
$md5cmd = false ;
2016-05-05 04:53:44 -04:00
if ( $config [ 'bsd_md5' ]) $md5cmd = '/sbin/md5 -r' ;
2016-05-05 02:21:21 -04:00
if ( $config [ 'gnu_md5' ]) $md5cmd = 'md5sum' ;
$allhashes = '' ;
2014-04-27 09:48:47 -04:00
foreach ( $post [ 'files' ] as $key => & $file ) {
2015-04-21 23:54:48 -04:00
if ( $post [ 'op' ] && $config [ 'allowed_ext_op' ]) {
if ( ! in_array ( $file [ 'extension' ], $config [ 'allowed_ext_op' ]))
error ( $config [ 'error' ][ 'unknownext' ]);
}
elseif ( ! in_array ( $file [ 'extension' ], $config [ 'allowed_ext' ]) && ! in_array ( $file [ 'extension' ], $config [ 'allowed_ext_files' ]))
2014-04-27 09:48:47 -04:00
error ( $config [ 'error' ][ 'unknownext' ]);
$file [ 'is_an_image' ] = ! in_array ( $file [ 'extension' ], $config [ 'allowed_ext_files' ]);
// Truncate filename if it is too long
$file [ 'filename' ] = mb_substr ( $file [ 'filename' ], 0 , $config [ 'max_filename_len' ]);
$upload = $file [ 'tmp_name' ];
if ( ! is_readable ( $upload ))
error ( $config [ 'error' ][ 'nomove' ]);
2016-05-05 02:21:21 -04:00
if ( $md5cmd ) {
2016-07-07 05:53:40 -04:00
$output = shell_exec_error ( $md5cmd . " " . escapeshellarg ( $upload ));
2016-05-05 02:21:21 -04:00
$output = explode ( ' ' , $output );
$hash = $output [ 0 ];
}
else {
$hash = md5_file ( $upload );
}
$file [ 'hash' ] = $hash ;
$allhashes .= $hash ;
2014-04-27 09:48:47 -04:00
}
2014-09-15 19:33:37 -04:00
2016-05-05 02:21:21 -04:00
if ( count ( $post [ 'files' ]) == 1 ) {
2014-04-27 09:48:47 -04:00
$post [ 'filehash' ] = $hash ;
2016-05-05 02:21:21 -04:00
}
else {
$post [ 'filehash' ] = md5 ( $allhashes );
2014-04-27 09:48:47 -04:00
}
2013-09-06 09:09:18 -04:00
}
2016-06-09 05:08:29 -04:00
2016-08-14 10:24:17 -04:00
if ( ! hasPermission ( $config [ 'mod' ][ 'bypass_filters' ], $board [ 'uri' ]) && ! $dropped_post ) {
2016-06-09 05:08:29 -04:00
require_once 'inc/filters.php' ;
2013-09-06 09:09:18 -04:00
do_filters ( $post );
}
2016-06-09 05:08:29 -04:00
if ( $post [ 'has_file' ]) {
2014-04-27 09:48:47 -04:00
foreach ( $post [ 'files' ] as $key => & $file ) {
2016-05-05 04:22:34 -04:00
if ( $file [ 'is_an_image' ]) {
if ( $config [ 'ie_mime_type_detection' ] !== false ) {
// Check IE MIME type detection XSS exploit
$buffer = file_get_contents ( $upload , null , null , null , 255 );
if ( preg_match ( $config [ 'ie_mime_type_detection' ], $buffer )) {
undoImage ( $post );
error ( $config [ 'error' ][ 'mime_exploit' ]);
}
2012-04-11 12:49:22 -04:00
}
2012-03-18 04:53:56 -04:00
2012-04-11 12:49:22 -04:00
require_once 'inc/image.php' ;
2012-03-10 04:53:41 -05:00
2012-07-19 02:16:50 -04:00
// find dimensions of an image using GD
2014-04-27 09:48:47 -04:00
if ( ! $size = @ getimagesize ( $file [ 'tmp_name' ])) {
2012-07-19 02:16:50 -04:00
error ( $config [ 'error' ][ 'invalidimg' ]);
}
2016-05-05 04:17:14 -04:00
if ( ! in_array ( $size [ 2 ], array ( IMAGETYPE_PNG , IMAGETYPE_GIF , IMAGETYPE_JPEG , IMAGETYPE_BMP ))) {
error ( $config [ 'error' ][ 'invalidimg' ]);
}
2012-07-19 02:16:50 -04:00
if ( $size [ 0 ] > $config [ 'max_width' ] || $size [ 1 ] > $config [ 'max_height' ]) {
error ( $config [ 'error' ][ 'maxsize' ]);
2012-04-11 12:49:22 -04:00
}
2013-07-21 15:50:45 -04:00
2014-04-27 09:48:47 -04:00
if ( $config [ 'convert_auto_orient' ] && ( $file [ 'extension' ] == 'jpg' || $file [ 'extension' ] == 'jpeg' )) {
2013-07-21 15:50:45 -04:00
// The following code corrects the image orientation.
// Currently only works with the 'convert' option selected but it could easily be expanded to work with the rest if you can be bothered.
2014-04-27 09:48:47 -04:00
if ( ! ( $config [ 'redraw_image' ] || (( $config [ 'strip_exif' ] && ! $config [ 'use_exiftool' ]) && ( $file [ 'extension' ] == 'jpg' || $file [ 'extension' ] == 'jpeg' )))) {
2013-08-03 20:34:59 -04:00
if ( in_array ( $config [ 'thumb_method' ], array ( 'convert' , 'convert+gifsicle' , 'gm' , 'gm+gifsicle' ))) {
2014-04-27 09:48:47 -04:00
$exif = @ exif_read_data ( $file [ 'tmp_name' ]);
2013-08-03 20:34:59 -04:00
$gm = in_array ( $config [ 'thumb_method' ], array ( 'gm' , 'gm+gifsicle' ));
2013-08-01 21:28:16 -04:00
if ( isset ( $exif [ 'Orientation' ]) && $exif [ 'Orientation' ] != 1 ) {
2013-08-03 22:14:25 -04:00
if ( $config [ 'convert_manual_orient' ]) {
$error = shell_exec_error (( $gm ? 'gm ' : '' ) . 'convert ' .
2014-04-27 09:48:47 -04:00
escapeshellarg ( $file [ 'tmp_name' ]) . ' ' .
2013-08-04 00:48:28 -04:00
ImageConvert :: jpeg_exif_orientation ( false , $exif ) . ' ' .
2013-08-04 00:54:27 -04:00
( $config [ 'strip_exif' ] ? '+profile "*"' :
( $config [ 'use_exiftool' ] ? '' : '+profile "*"' )
) . ' ' .
2014-04-27 09:48:47 -04:00
escapeshellarg ( $file [ 'tmp_name' ]));
2013-08-04 00:54:27 -04:00
if ( $config [ 'use_exiftool' ] && ! $config [ 'strip_exif' ]) {
2013-08-04 00:48:28 -04:00
if ( $exiftool_error = shell_exec_error (
2013-08-26 18:55:03 -04:00
'exiftool -overwrite_original -q -q -orientation=1 -n ' .
2014-04-27 09:48:47 -04:00
escapeshellarg ( $file [ 'tmp_name' ])))
error ( _ ( 'exiftool failed!' ), null , $exiftool_error );
2013-08-04 00:48:28 -04:00
} else {
// TODO: Find another way to remove the Orientation tag from the EXIF profile
// without needing `exiftool`.
}
2013-08-03 22:14:25 -04:00
} else {
$error = shell_exec_error (( $gm ? 'gm ' : '' ) . 'convert ' .
2014-04-27 09:48:47 -04:00
escapeshellarg ( $file [ 'tmp_name' ]) . ' -auto-orient ' . escapeshellarg ( $upload ));
2013-08-03 22:14:25 -04:00
}
if ( $error )
2014-04-27 09:48:47 -04:00
error ( _ ( 'Could not auto-orient image!' ), null , $error );
$size = @ getimagesize ( $file [ 'tmp_name' ]);
2013-08-04 00:54:27 -04:00
if ( $config [ 'strip_exif' ])
2014-04-27 09:48:47 -04:00
$file [ 'exif_stripped' ] = true ;
2013-08-01 21:28:16 -04:00
}
2013-01-23 11:24:38 -05:00
}
}
}
2012-04-11 12:49:22 -04:00
// create image object
2014-04-27 09:48:47 -04:00
$image = new Image ( $file [ 'tmp_name' ], $file [ 'extension' ], $size );
2012-04-12 10:18:19 -04:00
if ( $image -> size -> width > $config [ 'max_width' ] || $image -> size -> height > $config [ 'max_height' ]) {
2012-04-11 12:49:22 -04:00
$image -> delete ();
error ( $config [ 'error' ][ 'maxsize' ]);
}
2014-04-27 09:48:47 -04:00
$file [ 'width' ] = $image -> size -> width ;
$file [ 'height' ] = $image -> size -> height ;
2012-04-11 12:49:22 -04:00
2012-04-12 10:18:19 -04:00
if ( $config [ 'spoiler_images' ] && isset ( $_POST [ 'spoiler' ])) {
2014-04-27 09:48:47 -04:00
$file [ 'thumb' ] = 'spoiler' ;
2011-10-01 07:43:23 -04:00
2012-04-11 12:49:22 -04:00
$size = @ getimagesize ( $config [ 'spoiler_image' ]);
2014-04-27 09:48:47 -04:00
$file [ 'thumbwidth' ] = $size [ 0 ];
$file [ 'thumbheight' ] = $size [ 1 ];
2012-04-12 10:18:19 -04:00
} elseif ( $config [ 'minimum_copy_resize' ] &&
2012-04-11 12:49:22 -04:00
$image -> size -> width <= $config [ 'thumb_width' ] &&
$image -> size -> height <= $config [ 'thumb_height' ] &&
2014-04-27 09:48:47 -04:00
$file [ 'extension' ] == ( $config [ 'thumb_ext' ] ? $config [ 'thumb_ext' ] : $file [ 'extension' ])) {
2012-04-11 12:49:22 -04:00
// Copy, because there's nothing to resize
2014-04-27 09:48:47 -04:00
copy ( $file [ 'tmp_name' ], $file [ 'thumb' ]);
2012-04-11 12:49:22 -04:00
2014-04-27 09:48:47 -04:00
$file [ 'thumbwidth' ] = $image -> size -> width ;
$file [ 'thumbheight' ] = $image -> size -> height ;
2011-03-14 07:30:42 -04:00
} else {
2012-04-11 12:49:22 -04:00
$thumb = $image -> resize (
2014-04-27 09:48:47 -04:00
$config [ 'thumb_ext' ] ? $config [ 'thumb_ext' ] : $file [ 'extension' ],
2012-04-11 12:49:22 -04:00
$post [ 'op' ] ? $config [ 'thumb_op_width' ] : $config [ 'thumb_width' ],
$post [ 'op' ] ? $config [ 'thumb_op_height' ] : $config [ 'thumb_height' ]
);
2014-04-27 09:48:47 -04:00
$thumb -> to ( $file [ 'thumb' ]);
2012-04-11 12:49:22 -04:00
2014-04-27 09:48:47 -04:00
$file [ 'thumbwidth' ] = $thumb -> width ;
$file [ 'thumbheight' ] = $thumb -> height ;
2012-04-11 12:49:22 -04:00
$thumb -> _destroy ();
2011-03-14 07:30:42 -04:00
}
2012-04-11 12:49:22 -04:00
2014-04-27 09:48:47 -04:00
if ( $config [ 'redraw_image' ] || ( !@ $file [ 'exif_stripped' ] && $config [ 'strip_exif' ] && ( $file [ 'extension' ] == 'jpg' || $file [ 'extension' ] == 'jpeg' ))) {
2013-08-04 00:48:28 -04:00
if ( ! $config [ 'redraw_image' ] && $config [ 'use_exiftool' ]) {
2013-08-26 18:55:03 -04:00
if ( $error = shell_exec_error ( 'exiftool -overwrite_original -ignoreMinorErrors -q -q -all= ' .
2014-04-27 09:48:47 -04:00
escapeshellarg ( $file [ 'tmp_name' ])))
2014-05-09 19:31:16 -04:00
error ( _ ( 'Could not strip EXIF metadata!' ), null , $error );
2013-08-03 20:34:59 -04:00
} else {
2014-04-27 09:48:47 -04:00
$image -> to ( $file [ 'file' ]);
2013-08-03 20:34:59 -04:00
$dont_copy_file = true ;
}
2011-12-13 04:15:46 -05:00
}
2012-04-11 12:49:22 -04:00
$image -> destroy ();
2010-11-05 12:46:20 -04:00
} else {
2017-03-04 11:41:52 -05:00
if ( $file [ 'extension' ] == " pdf " && $config [ 'pdf_file_thumbnail' ]){
$path = $file [ 'thumb' ];
$error = shell_exec_error ( 'convert -thumbnail x300 -background white -alpha remove ' .
escapeshellarg ( $file [ 'tmp_name' ] . '[0]' ) . ' ' .
escapeshellarg ( $file [ 'thumb' ]));
if ( $error ){
$path = sprintf ( $config [ 'file_thumb' ], isset ( $config [ 'file_icons' ][ $file [ 'extension' ]]) ? $config [ 'file_icons' ][ $file [ ' ext
ension ']] : $config[' file_icons '][' default ' ]);
}
$file [ 'thumb' ] = basename ( $file [ 'thumb' ]);
$size = @ getimagesize ( $path );
$file [ 'thumbwidth' ] = $size [ 0 ];
$file [ 'thumbheight' ] = $size [ 1 ];
$file [ 'width' ] = $size [ 0 ];
$file [ 'height' ] = $size [ 1 ];
}
else {
2012-04-11 12:49:22 -04:00
// not an image
//copy($config['file_thumb'], $post['thumb']);
2014-04-27 09:48:47 -04:00
$file [ 'thumb' ] = 'file' ;
2013-08-18 06:53:01 -04:00
$size = @ getimagesize ( sprintf ( $config [ 'file_thumb' ],
2014-04-27 09:48:47 -04:00
isset ( $config [ 'file_icons' ][ $file [ 'extension' ]]) ?
$config [ 'file_icons' ][ $file [ 'extension' ]] : $config [ 'file_icons' ][ 'default' ]));
$file [ 'thumbwidth' ] = $size [ 0 ];
$file [ 'thumbheight' ] = $size [ 1 ];
2017-03-04 11:41:52 -05:00
}
2010-11-05 12:46:20 -04:00
}
2016-06-09 05:08:29 -04:00
2016-06-10 06:41:53 -04:00
if ( $config [ 'tesseract_ocr' ] && $file [ 'thumb' ] != 'file' ) { // Let's OCR it!
2016-06-09 05:08:29 -04:00
$fname = $file [ 'tmp_name' ];
if ( $file [ 'height' ] > 500 || $file [ 'width' ] > 500 ) {
$fname = $file [ 'thumb' ];
}
if ( $fname == 'spoiler' ) { // We don't have that much CPU time, do we?
}
else {
2017-03-01 21:26:51 -05:00
$tmpname = __DIR__ . " /tmp/tesseract/ " . rand ( 0 , 10000000 );
2016-06-09 05:08:29 -04:00
// 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' ]);
$tmpname .= " .txt " ;
$value = @ file_get_contents ( $tmpname );
@ unlink ( $tmpname );
if ( $value && trim ( $value )) {
// This one has an effect, that the body is appended to a post body. So you can write a correct
// spamfilter.
$post [ 'body_nomarkup' ] .= " <tinyboard ocr image $key > " . htmlspecialchars ( $value ) . " </tinyboard> " ;
}
}
}
2012-04-20 05:04:37 -04:00
if ( ! isset ( $dont_copy_file ) || ! $dont_copy_file ) {
2014-04-27 09:48:47 -04:00
if ( isset ( $file [ 'file_tmp' ])) {
if ( !@ rename ( $file [ 'tmp_name' ], $file [ 'file' ]))
2013-08-12 08:51:46 -04:00
error ( $config [ 'error' ][ 'nomove' ]);
2014-04-27 09:48:47 -04:00
chmod ( $file [ 'file' ], 0644 );
} elseif ( !@ move_uploaded_file ( $file [ 'tmp_name' ], $file [ 'file' ]))
2012-04-20 05:04:37 -04:00
error ( $config [ 'error' ][ 'nomove' ]);
2014-04-29 14:50:28 -04:00
}
2014-04-27 09:48:47 -04:00
}
2012-11-14 15:33:27 -05:00
if ( $config [ 'image_reject_repost' ]) {
if ( $p = getPostByHash ( $post [ 'filehash' ])) {
undoImage ( $post );
error ( sprintf ( $config [ 'error' ][ 'fileexists' ],
2013-12-23 13:01:08 -05:00
( $post [ 'mod' ] ? $config [ 'root' ] . $config [ 'file_mod' ] . '?/' : $config [ 'root' ]) .
( $board [ 'dir' ] . $config [ 'dir' ][ 'res' ] .
2012-11-14 15:33:27 -05:00
( $p [ 'thread' ] ?
$p [ 'thread' ] . '.html#' . $p [ 'id' ]
:
$p [ 'id' ] . '.html'
2013-12-23 13:01:08 -05:00
))
2012-11-14 15:33:27 -05:00
));
}
} else if ( ! $post [ 'op' ] && $config [ 'image_reject_repost_in_thread' ]) {
if ( $p = getPostByHashInThread ( $post [ 'filehash' ], $post [ 'thread' ])) {
undoImage ( $post );
error ( sprintf ( $config [ 'error' ][ 'fileexistsinthread' ],
2013-12-23 13:01:08 -05:00
( $post [ 'mod' ] ? $config [ 'root' ] . $config [ 'file_mod' ] . '?/' : $config [ 'root' ]) .
( $board [ 'dir' ] . $config [ 'dir' ][ 'res' ] .
2012-11-14 15:33:27 -05:00
( $p [ 'thread' ] ?
$p [ 'thread' ] . '.html#' . $p [ 'id' ]
:
$p [ 'id' ] . '.html'
2013-12-23 13:01:08 -05:00
))
2012-11-14 15:33:27 -05:00
));
}
}
2014-04-27 09:48:47 -04:00
}
2012-04-11 12:49:22 -04:00
2016-06-09 05:08:29 -04:00
// Do filters again if OCRing
2016-08-14 10:24:17 -04:00
if ( $config [ 'tesseract_ocr' ] && ! hasPermission ( $config [ 'mod' ][ 'bypass_filters' ], $board [ 'uri' ]) && ! $dropped_post ) {
2016-06-09 05:08:29 -04:00
do_filters ( $post );
}
2016-08-14 10:24:17 -04:00
if ( ! hasPermission ( $config [ 'mod' ][ 'postunoriginal' ], $board [ 'uri' ]) && $config [ 'robot_enable' ] && checkRobot ( $post [ 'body_nomarkup' ]) && ! $dropped_post ) {
2012-04-11 12:49:22 -04:00
undoImage ( $post );
2012-04-12 10:18:19 -04:00
if ( $config [ 'robot_mute' ]) {
2012-04-11 12:49:22 -04:00
error ( sprintf ( $config [ 'error' ][ 'muted' ], mute ()));
2010-11-30 04:40:37 -05:00
} else {
2012-04-11 12:49:22 -04:00
error ( $config [ 'error' ][ 'unoriginal' ]);
2010-11-05 12:46:20 -04:00
}
}
2012-04-11 12:49:22 -04:00
// Remove board directories before inserting them into the database.
2012-04-12 10:18:19 -04:00
if ( $post [ 'has_file' ]) {
2014-04-27 09:48:47 -04:00
foreach ( $post [ 'files' ] as $key => & $file ) {
$file [ 'file_path' ] = $file [ 'file' ];
$file [ 'thumb_path' ] = $file [ 'thumb' ];
$file [ 'file' ] = mb_substr ( $file [ 'file' ], mb_strlen ( $board [ 'dir' ] . $config [ 'dir' ][ 'img' ]));
if ( $file [ 'is_an_image' ] && $file [ 'thumb' ] != 'spoiler' )
$file [ 'thumb' ] = mb_substr ( $file [ 'thumb' ], mb_strlen ( $board [ 'dir' ] . $config [ 'dir' ][ 'thumb' ]));
}
2012-04-11 12:49:22 -04:00
}
$post = ( object ) $post ;
2014-04-29 15:18:17 -04:00
$post -> files = array_map ( function ( $a ) { return ( object ) $a ; }, $post -> files );
2015-03-10 07:48:59 -04:00
2014-04-29 15:18:17 -04:00
$error = event ( 'post' , $post );
$post -> files = array_map ( function ( $a ) { return ( array ) $a ; }, $post -> files );
if ( $error ) {
2012-04-11 12:49:22 -04:00
undoImage (( array ) $post );
error ( $error );
}
$post = ( array ) $post ;
2014-04-27 09:48:47 -04:00
if ( $post [ 'files' ])
$post [ 'files' ] = $post [ 'files' ];
$post [ 'num_files' ] = sizeof ( $post [ 'files' ]);
2012-04-11 12:49:22 -04:00
2012-05-27 06:55:56 -04:00
$post [ 'id' ] = $id = post ( $post );
2015-03-10 08:28:55 -04:00
$post [ 'slug' ] = slugify ( $post );
2012-04-11 12:49:22 -04:00
2016-08-14 10:24:17 -04:00
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 -> bindValue ( ':board' , $dropped_post [ 'board' ]);
$query -> bindValue ( ':id' , $id );
$query -> bindValue ( ':message_id' , $dropped_post [ 'msgid' ]);
$query -> bindValue ( ':message_id_digest' , sha1 ( $dropped_post [ 'msgid' ]));
$query -> bindValue ( ':headers' , $dropped_post [ 'headers' ]);
$query -> execute () or error ( db_error ( $query ));
2016-08-14 18:56:06 -04:00
} // ^^^^^ For inbound posts ^^^^^
elseif ( $config [ 'nntpchan' ][ 'enabled' ] && $config [ 'nntpchan' ][ 'group' ]) {
// vvvvv For outbound posts vvvvv
require_once ( 'inc/nntpchan/nntpchan.php' );
$msgid = gen_msgid ( $post [ 'board' ], $post [ 'id' ]);
list ( $headers , $files ) = post2nntp ( $post , $msgid );
$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 -> 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 ));
// Let's broadcast it!
nntp_publish ( $message , $msgid );
2016-08-14 10:24:17 -04:00
}
2016-08-14 18:56:06 -04:00
2013-09-06 09:09:18 -04:00
insertFloodPost ( $post );
2015-04-03 02:56:28 -04:00
// Handle cyclical threads
if ( ! $post [ 'op' ] && isset ( $thread [ 'cycle' ]) && $thread [ 'cycle' ]) {
// Query is a bit weird due to "This version of MariaDB doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'" (MariaDB Ver 15.1 Distrib 10.0.17-MariaDB, for Linux (x86_64))
$query = prepare ( sprintf ( 'DELETE FROM ``posts_%s`` WHERE `thread` = :thread AND `id` NOT IN (SELECT `id` FROM (SELECT `id` FROM ``posts_%s`` WHERE `thread` = :thread ORDER BY `id` DESC LIMIT :limit) i)' , $board [ 'uri' ], $board [ 'uri' ]));
$query -> bindValue ( ':thread' , $post [ 'thread' ]);
$query -> bindValue ( ':limit' , $config [ 'cycle_limit' ], PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
2016-12-13 16:11:54 -05:00
if ( $config [ 'slack' ])
{
function slack ( $message , $room = " reports " , $icon = " :no_entry_sign: " )
{
$room = ( $room ) ? $room : " reports " ;
$data = " payload= " . json_encode ( array (
" channel " => " # { $room } " ,
" text " => urlencode ( $message ),
" icon_emoji " => $icon
));
// You can get your webhook endpoint from your Slack settings
// For some reason using the configuration key doesn't work
$ch = curl_init ( $config [ 'slack_incoming_webhook_endpoint' ]);
curl_setopt ( $ch , CURLOPT_SSL_VERIFYPEER , false );
curl_setopt ( $ch , CURLOPT_CUSTOMREQUEST , " POST " );
curl_setopt ( $ch , CURLOPT_POSTFIELDS , $data );
curl_setopt ( $ch , CURLOPT_RETURNTRANSFER , true );
$result = curl_exec ( $ch );
curl_close ( $ch );
return $result ;
}
$postcontent = mb_substr ( $thread [ 'body_nomarkup' ], 0 , 120 ) . '... _*(POST TRIMMED)*_' ;
$slackmessage = '<' . $config [ 'domain' ] . " /mod.php?/ " . $board [ 'dir' ] . $config [ 'dir' ][ 'res' ] . ( $thread [ 'thread' ] ? $thread [ 'thread' ] : $id ) . " .html " . ( $thread [ 'thread' ] ? '#' . $id : '' ) . '> \n ' . $reason . '\n ' . $postcontent . '\n' ;
$slackresult = slack ( $slackmessage , $config [ 'slack_channel' ]);
}
2015-04-03 02:56:28 -04:00
}
2013-09-06 09:09:18 -04:00
2012-05-07 09:51:15 -04:00
if ( isset ( $post [ 'antispam_hash' ])) {
incrementSpamHash ( $post [ 'antispam_hash' ]);
}
2012-04-11 12:49:22 -04:00
2013-08-29 04:55:25 -04:00
if ( isset ( $post [ 'tracked_cites' ]) && ! empty ( $post [ 'tracked_cites' ])) {
2013-08-28 22:38:37 -04:00
$insert_rows = array ();
2012-04-12 10:18:19 -04:00
foreach ( $post [ 'tracked_cites' ] as $cite ) {
2013-08-28 22:38:37 -04:00
$insert_rows [] = '(' .
$pdo -> quote ( $board [ 'uri' ]) . ', ' . ( int ) $id . ', ' .
$pdo -> quote ( $cite [ 0 ]) . ', ' . ( int ) $cite [ 1 ] . ')' ;
2012-04-11 12:49:22 -04:00
}
2013-08-30 23:33:26 -04:00
query ( 'INSERT INTO ``cites`` VALUES ' . implode ( ', ' , $insert_rows )) or error ( db_error ());
2012-04-11 12:49:22 -04:00
}
2013-06-18 13:21:41 -04:00
if ( ! $post [ 'op' ] && strtolower ( $post [ 'email' ]) != 'sage' && ! $thread [ 'sage' ] && ( $config [ 'reply_limit' ] == 0 || $numposts [ 'replies' ] + 1 < $config [ 'reply_limit' ])) {
2012-04-11 12:49:22 -04:00
bumpThread ( $post [ 'thread' ]);
}
2012-04-12 10:18:19 -04:00
if ( isset ( $_SERVER [ 'HTTP_REFERER' ])) {
2012-04-11 12:49:22 -04:00
// Tell Javascript that we posted successfully
2012-04-12 10:18:19 -04:00
if ( isset ( $_COOKIE [ $config [ 'cookies' ][ 'js' ]]))
2012-04-11 12:49:22 -04:00
$js = json_decode ( $_COOKIE [ $config [ 'cookies' ][ 'js' ]]);
else
$js = ( object ) array ();
// Tell it to delete the cached post for referer
$js -> { $_SERVER [ 'HTTP_REFERER' ]} = true ;
// Encode and set cookie
setcookie ( $config [ 'cookies' ][ 'js' ], json_encode ( $js ), 0 , $config [ 'cookies' ][ 'jail' ] ? $config [ 'cookies' ][ 'path' ] : '/' , null , false , false );
}
$root = $post [ 'mod' ] ? $config [ 'root' ] . $config [ 'file_mod' ] . '?/' : $config [ 'root' ];
2013-12-20 17:52:54 -05:00
if ( $noko ) {
2012-04-11 12:49:22 -04:00
$redirect = $root . $board [ 'dir' ] . $config [ 'dir' ][ 'res' ] .
2015-03-10 07:48:59 -04:00
link_for ( $post , false , false , $thread ) . ( ! $post [ 'op' ] ? '#' . $id : '' );
2013-08-10 17:16:30 -04:00
if ( ! $post [ 'op' ] && isset ( $_SERVER [ 'HTTP_REFERER' ])) {
$regex = array (
'board' => str_replace ( '%s' , '(\w{1,8})' , preg_quote ( $config [ 'board_path' ], '/' )),
'page' => str_replace ( '%d' , '(\d+)' , preg_quote ( $config [ 'file_page' ], '/' )),
2015-03-10 07:48:59 -04:00
'page50' => '(' . str_replace ( '%d' , '(\d+)' , preg_quote ( $config [ 'file_page50' ], '/' )) . '|' .
str_replace ( array ( '%d' , '%s' ), array ( '(\d+)' , '[a-z0-9-]+' ), preg_quote ( $config [ 'file_page50_slug' ], '/' )) . ')' ,
2013-08-10 17:16:30 -04:00
'res' => preg_quote ( $config [ 'dir' ][ 'res' ], '/' ),
);
if ( preg_match ( '/\/' . $regex [ 'board' ] . $regex [ 'res' ] . $regex [ 'page50' ] . '([?&].*)?$/' , $_SERVER [ 'HTTP_REFERER' ])) {
$redirect = $root . $board [ 'dir' ] . $config [ 'dir' ][ 'res' ] .
2015-03-10 07:48:59 -04:00
link_for ( $post , true , false , $thread ) . ( ! $post [ 'op' ] ? '#' . $id : '' );
2013-08-10 17:16:30 -04:00
}
}
2012-04-11 12:49:22 -04:00
} else {
$redirect = $root . $board [ 'dir' ] . $config [ 'file_index' ];
}
2015-03-31 03:17:22 -04:00
buildThread ( $post [ 'op' ] ? $id : $post [ 'thread' ]);
2012-04-11 12:49:22 -04:00
2012-04-12 10:18:19 -04:00
if ( $config [ 'syslog' ])
2012-04-11 12:49:22 -04:00
_syslog ( LOG_INFO , 'New post: /' . $board [ 'dir' ] . $config [ 'dir' ][ 'res' ] .
2015-03-10 07:48:59 -04:00
link_for ( $post ) . ( ! $post [ 'op' ] ? '#' . $id : '' ));
2012-04-11 12:49:22 -04:00
2013-06-21 16:36:20 -04:00
if ( ! $post [ 'mod' ]) header ( 'X-Associated-Content: "' . $redirect . '"' );
2013-07-18 15:19:03 -04:00
2013-09-15 00:03:27 -04:00
if ( ! isset ( $_POST [ 'json_response' ])) {
header ( 'Location: ' . $redirect , true , $config [ 'redirect_http' ]);
} else {
header ( 'Content-Type: text/json; charset=utf-8' );
echo json_encode ( array (
'redirect' => $redirect ,
2013-12-20 17:52:54 -05:00
'noko' => $noko ,
2013-09-15 00:03:27 -04:00
'id' => $id
));
}
2015-03-31 03:17:22 -04:00
if ( $config [ 'try_smarter' ] && $post [ 'op' ])
$build_pages = range ( 1 , $config [ 'max_pages' ]);
if ( $post [ 'op' ])
2016-05-07 21:09:20 -04:00
clean ( $id );
2015-03-31 03:17:22 -04:00
event ( 'post-after' , $post );
buildIndex ();
// 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 ();
if ( $post [ 'op' ])
rebuildThemes ( 'post-thread' , $board [ 'uri' ]);
else
rebuildThemes ( 'post' , $board [ 'uri' ]);
2013-09-20 22:51:23 -04:00
} elseif ( isset ( $_POST [ 'appeal' ])) {
if ( ! isset ( $_POST [ 'ban_id' ]))
error ( $config [ 'error' ][ 'bot' ]);
$ban_id = ( int ) $_POST [ 'ban_id' ];
$bans = Bans :: find ( $_SERVER [ 'REMOTE_ADDR' ]);
foreach ( $bans as $_ban ) {
if ( $_ban [ 'id' ] == $ban_id ) {
$ban = $_ban ;
break ;
}
}
if ( ! isset ( $ban )) {
error ( _ ( " That ban doesn't exist or is not for you. " ));
}
if ( $ban [ 'expires' ] && $ban [ 'expires' ] - $ban [ 'created' ] <= $config [ 'ban_appeals_min_length' ]) {
error ( _ ( " You cannot appeal a ban of this length. " ));
}
$query = query ( " SELECT `denied` FROM ``ban_appeals`` WHERE `ban_id` = $ban_id " ) or error ( db_error ());
$ban_appeals = $query -> fetchAll ( PDO :: FETCH_COLUMN );
if ( count ( $ban_appeals ) >= $config [ 'ban_appeals_max' ]) {
error ( _ ( " You cannot appeal this ban again. " ));
}
foreach ( $ban_appeals as $is_denied ) {
if ( ! $is_denied )
error ( _ ( " There is already a pending appeal for this ban. " ));
}
$query = prepare ( " INSERT INTO ``ban_appeals`` VALUES (NULL, :ban_id, :time, :message, 0) " );
$query -> bindValue ( ':ban_id' , $ban_id , PDO :: PARAM_INT );
$query -> bindValue ( ':time' , time (), PDO :: PARAM_INT );
$query -> bindValue ( ':message' , $_POST [ 'appeal' ]);
$query -> execute () or error ( db_error ( $query ));
displayBan ( $ban );
2012-04-11 12:49:22 -04:00
} else {
2012-04-12 10:18:19 -04:00
if ( ! file_exists ( $config [ 'has_installed' ])) {
2012-04-11 12:49:22 -04:00
header ( 'Location: install.php' , true , $config [ 'redirect_http' ]);
} else {
// They opened post.php in their browser manually.
error ( $config [ 'error' ][ 'nopost' ]);
}
}