2011-06-15 19:11:52 +02:00
< ? php
2012-04-11 18:49:22 +02:00
/*
2014-04-12 20:12:42 +02:00
* Copyright ( c ) 2010 - 2014 Tinyboard Development Group
2012-04-11 18:49:22 +02:00
*/
2014-10-17 09:32:39 +02:00
require " ./inc/functions.php " ;
require " ./inc/anti-bot.php " ;
2012-04-11 18:49:22 +02:00
2014-10-17 09:32:39 +02:00
// The dnsbls is an optional DNS blacklist include.
// Squelch warnings if it doesn't exist.
@ include " ./inc/dnsbls.php " ;
2012-04-11 18:49:22 +02:00
// Fix for magic quotes
if ( get_magic_quotes_gpc ()) {
function strip_array ( $var ) {
2012-04-12 13:56:01 +02:00
return is_array ( $var ) ? array_map ( 'strip_array' , $var ) : stripslashes ( $var );
2010-11-05 17:46:20 +01:00
}
2012-04-11 18:49:22 +02:00
$_GET = strip_array ( $_GET );
$_POST = strip_array ( $_POST );
}
2012-04-12 16:18:19 +02:00
if ( isset ( $_POST [ 'delete' ])) {
2012-04-11 18:49:22 +02:00
// Delete
2012-04-12 16:18:19 +02:00
if ( ! isset ( $_POST [ 'board' ], $_POST [ 'password' ]))
2012-04-11 18:49:22 +02:00
error ( $config [ 'error' ][ 'bot' ]);
$password = & $_POST [ 'password' ];
2012-04-12 16:18:19 +02:00
if ( $password == '' )
2012-04-11 18:49:22 +02:00
error ( $config [ 'error' ][ 'invalidpassword' ]);
$delete = array ();
2012-04-12 16:18:19 +02:00
foreach ( $_POST as $post => $value ) {
if ( preg_match ( '/^delete_(\d+)$/' , $post , $m )) {
2012-04-11 18:49:22 +02:00
$delete [] = ( int ) $m [ 1 ];
2011-01-21 03:14:11 +01:00
}
2012-04-11 18:49:22 +02:00
}
2015-02-17 01:24:11 +01:00
if ( checkDNSBL ()) error ( " Tor users may not delete posts. " );
2011-01-21 03:14:11 +01:00
2012-04-11 18:49:22 +02:00
// Check if board exists
2012-04-12 16:18:19 +02:00
if ( ! openBoard ( $_POST [ 'board' ]))
2012-04-11 18:49:22 +02:00
error ( $config [ 'error' ][ 'noboard' ]);
// Check if banned
checkBan ( $board [ 'uri' ]);
2014-05-06 00:03:51 +02:00
// Check if deletion enabled
if ( ! $config [ 'allow_delete' ])
2014-12-03 09:16:01 +01:00
error ( _ ( 'Users are not allowed to delete their own posts on this board.' ));
2012-04-11 18:49:22 +02:00
2012-04-12 16:18:19 +02:00
if ( empty ( $delete ))
2012-04-11 18:49:22 +02:00
error ( $config [ 'error' ][ 'nodelete' ]);
2011-01-21 03:14:11 +01:00
2012-04-12 16:18:19 +02:00
foreach ( $delete as & $id ) {
2013-08-01 04:14:26 +02:00
$query = prepare ( sprintf ( " SELECT `thread`, `time`,`password` FROM ``posts_%s`` WHERE `id` = :id " , $board [ 'uri' ]));
2012-04-11 18:49:22 +02:00
$query -> bindValue ( ':id' , $id , PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
2011-07-27 05:40:27 +02:00
2013-08-01 02:51:43 +02:00
if ( $post = $query -> fetch ( PDO :: FETCH_ASSOC )) {
2014-05-06 21:53:05 +02: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 18:49:22 +02:00
error ( $config [ 'error' ][ 'invalidpassword' ]);
2011-01-21 03:14:11 +01:00
2014-05-06 21:53:05 +02:00
if ( $post [ 'time' ] > time () - $config [ 'delete_time' ] && ( ! $thread || $thread [ 'password' ] != $password )) {
2012-04-11 18:49:22 +02:00
error ( sprintf ( $config [ 'error' ][ 'delete_too_soon' ], until ( $post [ 'time' ] + $config [ 'delete_time' ])));
}
2011-01-21 03:14:11 +01:00
2012-04-12 16:18:19 +02:00
if ( isset ( $_POST [ 'file' ])) {
2012-04-11 18:49:22 +02:00
// Delete just the file
deleteFile ( $id );
2015-02-26 02:21:49 +01:00
modLog ( " User deleted file from his own post # $id " );
2012-04-11 18:49:22 +02:00
} else {
// Delete entire post
deletePost ( $id );
2015-02-26 02:21:49 +01:00
modLog ( " User deleted his own post # $id " );
2011-01-21 03:14:11 +01:00
}
2012-04-11 18:49:22 +02:00
_syslog ( LOG_INFO , 'Deleted post: ' .
'/' . $board [ 'dir' ] . $config [ 'dir' ][ 'res' ] . sprintf ( $config [ 'file_page' ], $post [ 'thread' ] ? $post [ 'thread' ] : $id ) . ( $post [ 'thread' ] ? '#' . $id : '' )
);
2011-01-21 03:14:11 +01:00
}
2012-04-11 18:49:22 +02:00
}
2011-02-20 07:19:57 +01:00
2012-04-11 18:49:22 +02:00
buildIndex ();
2013-08-26 05:23:02 +02:00
2012-04-11 18:49:22 +02:00
$is_mod = isset ( $_POST [ 'mod' ]) && $_POST [ 'mod' ];
$root = $is_mod ? $config [ 'root' ] . $config [ 'file_mod' ] . '?/' : $config [ 'root' ];
2015-03-31 10:17:20 +02:00
2013-09-15 20:42:13 +02: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 10:17:20 +02: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' ]);
} elseif ( isset ( $_POST [ 'report' ])) {
2014-05-06 00:03:51 +02:00
if ( ! isset ( $_POST [ 'board' ], $_POST [ 'reason' ]))
2012-04-11 18:49:22 +02:00
error ( $config [ 'error' ][ 'bot' ]);
$report = array ();
2012-04-12 16:18:19 +02:00
foreach ( $_POST as $post => $value ) {
if ( preg_match ( '/^delete_(\d+)$/' , $post , $m )) {
2012-04-11 18:49:22 +02:00
$report [] = ( int ) $m [ 1 ];
2011-02-20 07:19:57 +01:00
}
2012-04-11 18:49:22 +02:00
}
2015-02-17 01:24:11 +01:00
if ( checkDNSBL ()) error ( " Tor users may not report posts. " );
2011-02-20 07:19:57 +01:00
2012-04-11 18:49:22 +02:00
// Check if board exists
2012-04-12 16:18:19 +02:00
if ( ! openBoard ( $_POST [ 'board' ]))
2012-04-11 18:49:22 +02:00
error ( $config [ 'error' ][ 'noboard' ]);
// Check if banned
checkBan ( $board [ 'uri' ]);
2012-04-12 16:18:19 +02:00
if ( empty ( $report ))
2012-04-11 18:49:22 +02:00
error ( $config [ 'error' ][ 'noreport' ]);
2012-04-12 16:18:19 +02:00
if ( count ( $report ) > $config [ 'report_limit' ])
2012-04-11 18:49:22 +02:00
error ( $config [ 'error' ][ 'toomanyreports' ]);
2015-03-13 05:45:57 +01: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 18:49:22 +02:00
2013-08-01 00:59:54 +02:00
$reason = escape_markup_modifiers ( $_POST [ 'reason' ]);
2012-04-11 18:49:22 +02:00
markup ( $reason );
2012-04-12 16:18:19 +02:00
foreach ( $report as & $id ) {
2014-10-21 14:50:25 +02:00
$query = prepare (
" SELECT
`thread` ,
`post_clean` . `clean_local` ,
`post_clean` . `clean_global`
FROM `posts_{$board['uri']}`
LEFT JOIN `post_clean`
ON `post_clean` . `board_id` = '{$board[' uri ']}'
AND `post_clean` . `post_id` = : id
WHERE `id` = : id "
);
2012-04-11 18:49:22 +02:00
$query -> bindValue ( ':id' , $id , PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
2014-10-21 14:50:25 +02:00
if ( $post = $query -> fetch ( PDO :: FETCH_ASSOC ) ) {
$report_local = ! $post [ 'clean_local' ];
$report_global = isset ( $_POST [ 'global' ]) && ! $post [ 'clean_global' ];
if ( $report_local || $report_global ) {
$thread = $post [ 'thread' ];
if ( $config [ 'syslog' ]) {
_syslog ( LOG_INFO , 'Reported post: ' .
'/' . $board [ 'dir' ] . $config [ 'dir' ][ 'res' ] . sprintf ( $config [ 'file_page' ], $thread ? $thread : $id ) . ( $thread ? '#' . $id : '' ) .
' for "' . $reason . '"'
);
}
$query = prepare ( " INSERT INTO `reports` (`time`, `ip`, `board`, `post`, `reason`, `local`, `global`) VALUES (:time, :ip, :board, :post, :reason, :local, :global) " );
$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 -> bindValue ( ':local' , $report_local , PDO :: PARAM_BOOL );
$query -> bindValue ( ':global' , $report_global , PDO :: PARAM_BOOL );
$query -> execute () or error ( db_error ( $query ));
}
}
2012-04-11 18:49:22 +02:00
}
$is_mod = isset ( $_POST [ 'mod' ]) && $_POST [ 'mod' ];
$root = $is_mod ? $config [ 'root' ] . $config [ 'file_mod' ] . '?/' : $config [ 'root' ];
2013-09-15 20:42:13 +02:00
if ( ! isset ( $_POST [ 'json_response' ])) {
2015-03-13 05:45:57 +01:00
$index = $root . $board [ 'dir' ] . $config [ 'file_index' ];
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 20:42:13 +02:00
} else {
header ( 'Content-Type: text/json' );
echo json_encode ( array ( 'success' => true ));
}
2014-10-21 14:50:25 +02:00
}
elseif ( isset ( $_POST [ 'post' ])) {
2015-04-14 17:01:32 +02:00
if ( ! isset ( $_POST [ 'body' ], $_POST [ 'board' ])) {
2012-04-11 18:49:22 +02:00
error ( $config [ 'error' ][ 'bot' ]);
2015-04-14 17:01:32 +02:00
}
$post = array (
'board' => $_POST [ 'board' ],
'files' => array (),
'time' => time (), // Timezone independent UNIX timecode.
);
2014-04-18 14:32:05 +02:00
// Check if board exists
if ( ! openBoard ( $post [ 'board' ]))
error ( $config [ 'error' ][ 'noboard' ]);
2012-04-11 18:49:22 +02:00
2012-04-12 16:18:19 +02:00
if ( ! isset ( $_POST [ 'name' ]))
2012-04-11 18:49:22 +02:00
$_POST [ 'name' ] = $config [ 'anonymous' ];
2012-04-12 16:18:19 +02:00
if ( ! isset ( $_POST [ 'email' ]))
2012-04-11 18:49:22 +02:00
$_POST [ 'email' ] = '' ;
2012-08-30 12:07:23 +02:00
if ( ! isset ( $_POST [ 'subject' ]))
$_POST [ 'subject' ] = '' ;
2012-04-12 16:18:19 +02:00
if ( ! isset ( $_POST [ 'password' ]))
2015-04-14 17:01:32 +02:00
$_POST [ 'password' ] = '' ;
2012-04-11 18:49:22 +02:00
2012-04-12 16:18:19 +02:00
if ( isset ( $_POST [ 'thread' ])) {
2012-04-11 18:49:22 +02:00
$post [ 'op' ] = false ;
$post [ 'thread' ] = round ( $_POST [ 'thread' ]);
} else
$post [ 'op' ] = true ;
2014-04-18 14:32:05 +02:00
2015-01-01 07:39:49 +01:00
// Check if banned
checkBan ( $board [ 'uri' ]);
2012-04-11 18:49:22 +02:00
// Check for CAPTCHA right after opening the board so the "return" link is in there
2012-04-12 16:18:19 +02:00
if ( $config [ 'recaptcha' ]) {
if ( ! isset ( $_POST [ 'recaptcha_challenge_field' ]) || ! isset ( $_POST [ 'recaptcha_response_field' ]))
2011-02-12 07:25:15 +01:00
error ( $config [ 'error' ][ 'bot' ]);
2012-04-11 18:49:22 +02:00
// Check what reCAPTCHA has to say...
$resp = recaptcha_check_answer ( $config [ 'recaptcha_private' ],
$_SERVER [ 'REMOTE_ADDR' ],
$_POST [ 'recaptcha_challenge_field' ],
$_POST [ 'recaptcha_response_field' ]);
2012-04-12 16:18:19 +02:00
if ( ! $resp -> is_valid ) {
2012-04-11 18:49:22 +02:00
error ( $config [ 'error' ][ 'captcha' ]);
2011-02-16 10:37:57 +01:00
}
2012-04-11 18:49:22 +02:00
}
2014-10-06 12:35:37 +02:00
2014-11-14 15:09:52 +01:00
// Same, but now with our custom captcha provider
2015-01-29 08:18:05 +01:00
//if ($config['captcha']['enabled']) {
//New thread captcha
if (( $config [ 'captcha' ][ 'enabled' ]) || (( $post [ 'op' ]) && ( $config [ 'new_thread_capt' ])) ) {
2014-11-14 15:09:52 +01:00
$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' ] .
'<script>if (actually_load_captcha !== undefined) actually_load_captcha("' . $config [ 'captcha' ][ 'provider_get' ] . '", "' . $config [ 'captcha' ][ 'extra' ] . '");</script>' );
}
}
2014-11-13 06:08:32 +01:00
//if (!(($post['op'] && $_POST['post'] == $config['button_newtopic']) ||
//(!$post['op'] && $_POST['post'] == $config['button_reply'])))
2014-10-10 18:52:51 +02:00
//error($config['error']['bot']);
2012-04-11 18:49:22 +02:00
2014-10-06 12:35:37 +02:00
// Check the referrer
if ( $config [ 'referer_match' ] !== false &&
2014-11-13 06:08:32 +01:00
( ! isset ( $_SERVER [ 'HTTP_REFERER' ]) || ! preg_match ( $config [ 'referer_match' ], rawurldecode ( $_SERVER [ 'HTTP_REFERER' ])))) {
2014-10-06 12:35:37 +02:00
error ( $config [ 'error' ][ 'referer' ]);
2014-11-13 06:08:32 +01:00
}
2012-04-12 16:18:19 +02:00
if ( $post [ 'mod' ] = isset ( $_POST [ 'mod' ]) && $_POST [ 'mod' ]) {
2015-01-01 07:35:21 +01:00
check_login ( false );
2012-04-12 16:18:19 +02:00
if ( ! $mod ) {
2012-04-12 13:56:01 +02:00
// Liar. You're not a mod.
error ( $config [ 'error' ][ 'notamod' ]);
}
$post [ 'sticky' ] = $post [ 'op' ] && isset ( $_POST [ 'sticky' ]);
$post [ 'locked' ] = $post [ 'op' ] && isset ( $_POST [ 'lock' ]);
$post [ 'raw' ] = isset ( $_POST [ 'raw' ]);
2012-04-12 16:18:19 +02:00
if ( $post [ 'sticky' ] && ! hasPermission ( $config [ 'mod' ][ 'sticky' ], $board [ 'uri' ]))
2012-04-12 13:56:01 +02:00
error ( $config [ 'error' ][ 'noaccess' ]);
2012-04-12 16:18:19 +02:00
if ( $post [ 'locked' ] && ! hasPermission ( $config [ 'mod' ][ 'lock' ], $board [ 'uri' ]))
2012-04-12 13:56:01 +02:00
error ( $config [ 'error' ][ 'noaccess' ]);
2012-04-12 16:18:19 +02:00
if ( $post [ 'raw' ] && ! hasPermission ( $config [ 'mod' ][ 'rawhtml' ], $board [ 'uri' ]))
2012-04-12 13:56:01 +02:00
error ( $config [ 'error' ][ 'noaccess' ]);
}
2015-02-26 10:12:12 +01:00
if ( ! $post [ 'mod' ]) {
2014-04-30 22:46:20 +02:00
$post [ 'antispam_hash' ] = checkSpam ( array ( $board [ 'uri' ], isset ( $post [ 'thread' ]) ? $post [ 'thread' ] : ( $config [ 'try_smarter' ] && isset ( $_POST [ 'page' ]) ? 0 - ( int ) $_POST [ 'page' ] : null )));
2015-02-26 10:12:12 +01:00
if ( $post [ 'antispam_hash' ] === true && $config [ 'enable_antibot' ])
2012-05-07 15:51:15 +02:00
error ( $config [ 'error' ][ 'spam' ]);
2015-02-26 10:12:12 +01:00
}
2012-04-11 18:49:22 +02:00
2012-04-12 16:18:19 +02:00
if ( $config [ 'robot_enable' ] && $config [ 'robot_mute' ]) {
2012-04-11 18:49:22 +02:00
checkMute ();
}
//Check if thread exists
2012-04-12 16:18:19 +02:00
if ( ! $post [ 'op' ]) {
2015-04-03 08:56:28 +02:00
$query = prepare ( sprintf ( " SELECT `sticky`,`locked`,`cycle`,`sage` FROM ``posts_%s`` WHERE `id` = :id AND `thread` IS NULL LIMIT 1 " , $board [ 'uri' ]));
2012-04-11 18:49:22 +02:00
$query -> bindValue ( ':id' , $post [ 'thread' ], PDO :: PARAM_INT );
$query -> execute () or error ( db_error ());
2013-08-01 02:51:43 +02:00
if ( ! $thread = $query -> fetch ( PDO :: FETCH_ASSOC )) {
2012-04-11 18:49:22 +02:00
// Non-existant
error ( $config [ 'error' ][ 'nonexistant' ]);
2011-10-10 17:58:22 +02:00
}
2012-04-11 18:49:22 +02:00
}
2011-05-18 09:05:48 +02:00
2012-04-11 18:49:22 +02:00
// Check for an embed field
2012-04-12 16:18:19 +02:00
if ( $config [ 'enable_embedding' ] && isset ( $_POST [ 'embed' ]) && ! empty ( $_POST [ 'embed' ])) {
2012-04-11 18:49:22 +02:00
// yep; validate it
$value = $_POST [ 'embed' ];
2012-04-12 16:18:19 +02:00
foreach ( $config [ 'embedding' ] as & $embed ) {
2013-07-20 00:36:12 +02:00
if ( preg_match ( $embed [ 0 ], $value )) {
// Valid link
$post [ 'embed' ] = $value ;
// This is bad, lol.
2012-04-11 18:49:22 +02:00
$post [ 'no_longer_require_an_image_for_op' ] = true ;
break ;
2011-05-18 09:05:48 +02:00
}
2010-11-05 17:46:20 +01:00
}
2012-04-12 16:18:19 +02:00
if ( ! isset ( $post [ 'embed' ])) {
2012-04-11 18:49:22 +02:00
error ( $config [ 'error' ][ 'invalid_embed' ]);
2011-02-22 01:09:43 +01:00
}
2012-04-11 18:49:22 +02:00
}
2012-04-12 16:18:19 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'bypass_field_disable' ], $board [ 'uri' ])) {
if ( $config [ 'field_disable_name' ])
2012-04-11 18:49:22 +02:00
$_POST [ 'name' ] = $config [ 'anonymous' ]; // "forced anonymous"
2012-04-12 16:18:19 +02:00
if ( $config [ 'field_disable_email' ])
2012-04-11 18:49:22 +02:00
$_POST [ 'email' ] = '' ;
2015-02-17 01:35:37 +01:00
if ( $config [ 'field_email_selectbox' ] && $_POST [ 'email' ] != 'sage' )
$_POST [ 'email' ] = '' ;
2012-04-11 18:49:22 +02:00
2012-04-12 16:18:19 +02:00
if ( $config [ 'field_disable_password' ])
2012-04-11 18:49:22 +02:00
$_POST [ 'password' ] = '' ;
2012-08-30 12:07:23 +02:00
if ( $config [ 'field_disable_subject' ] || ( ! $post [ 'op' ] && $config [ 'field_disable_reply_subject' ]))
$_POST [ 'subject' ] = '' ;
2012-04-11 18:49:22 +02:00
}
2013-08-12 14:51:46 +02:00
if ( $config [ 'allow_upload_by_url' ] && isset ( $_POST [ 'file_url' ]) && ! empty ( $_POST [ 'file_url' ])) {
$post [ 'file_url' ] = $_POST [ 'file_url' ];
2013-09-14 21:48:37 +02:00
if ( ! preg_match ( '@^https?://@' , $post [ 'file_url' ]))
2013-08-12 14:51:46 +02:00
error ( $config [ 'error' ][ 'invalidimg' ]);
2013-08-26 04:13:40 +02: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 ));
2013-08-12 14:51:46 +02:00
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' );
2013-08-12 15:35:27 +02:00
function unlink_tmp_file ( $file ) {
@ unlink ( $file );
2013-08-27 00:13:23 +02:00
fatal_error_handler ();
2013-08-12 15:35:27 +02:00
}
register_shutdown_function ( 'unlink_tmp_file' , $post [ 'file_tmp' ]);
2013-08-12 14:51:46 +02: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 10:54:10 +02:00
curl_setopt ( $curl , CURLOPT_TIMEOUT , $config [ 'upload_by_url_timeout' ]);
2013-08-12 14:51:46 +02:00
curl_setopt ( $curl , CURLOPT_USERAGENT , 'Tinyboard' );
curl_setopt ( $curl , CURLOPT_BINARYTRANSFER , true );
curl_setopt ( $curl , CURLOPT_FILE , $fp );
2013-08-12 16:07:23 +02:00
curl_setopt ( $curl , CURLOPT_PROTOCOLS , CURLPROTO_HTTP | CURLPROTO_HTTPS );
2013-08-12 14:51:46 +02:00
if ( curl_exec ( $curl ) === false )
2014-05-28 01:45:05 +02:00
error ( $config [ 'error' ][ 'nomove' ] . '<br/>Curl says: ' . curl_error ( $curl ));
2013-08-12 14:51:46 +02:00
curl_close ( $curl );
fclose ( $fp );
$_FILES [ 'file' ] = array (
2013-08-26 04:13:40 +02:00
'name' => basename ( $url_without_params ),
2013-08-12 14:51:46 +02:00
'tmp_name' => $post [ 'file_tmp' ],
2014-04-29 20:50:28 +02:00
'file_tmp' => true ,
2013-08-12 14:51:46 +02:00
'error' => 0 ,
'size' => filesize ( $post [ 'file_tmp' ])
);
}
2012-04-11 18:49:22 +02:00
$post [ 'name' ] = $_POST [ 'name' ] != '' ? $_POST [ 'name' ] : $config [ 'anonymous' ];
$post [ 'subject' ] = $_POST [ 'subject' ];
2012-08-26 18:18:31 +02:00
$post [ 'email' ] = str_replace ( ' ' , '%20' , htmlspecialchars ( $_POST [ 'email' ]));
2015-03-11 00:21:15 +01:00
if ( isset ( $_POST [ 'no-bump' ])) {
if ( ! empty ( $post [ 'email' ])) {
$post [ 'email' ] .= '+sage' ;
} else {
$post [ 'email' ] = 'sage' ;
}
}
2012-04-11 18:49:22 +02:00
$post [ 'body' ] = $_POST [ 'body' ];
$post [ 'password' ] = $_POST [ 'password' ];
2014-07-04 23:15:47 +02:00
$post [ 'has_file' ] = ( ! isset ( $post [ 'embed' ]) && (( $post [ 'op' ] && ! isset ( $post [ 'no_longer_require_an_image_for_op' ]) && $config [ 'force_image_op' ]) || ! empty ( $_FILES [ 'file' ][ 'name' ])));
2015-01-05 13:39:33 +01:00
2015-02-17 01:42:31 +01:00
// Handle our Tor users
$tor = checkDNSBL ();
if ( $tor && ! ( isset ( $_SERVER [ 'HTTP_X_TOR' ], $_SERVER [ 'REMOTE_ADDR' ]) && $_SERVER [ 'REMOTE_ADDR' ] == '127.0.0.2' && $_SERVER [ 'HTTP_X_TOR' ] = 'true' ))
error ( 'To post on 8chan over Tor, you must use the hidden service for security reasons. You can find it at <a href="http://fullchan4jtta4sx.onion">http://fullchan4jtta4sx.onion</a>.' );
if ( $tor && $post [ 'has_file' ])
error ( 'Sorry. Tor users can\'t upload files.' );
if ( $tor && ! $config [ 'tor_posting' ])
error ( 'Sorry. The owner of this board has decided not to allow Tor posters for some reason...' );
2015-02-27 15:34:16 +01:00
if ( $post [ 'has_file' ] && $config [ 'disable_images' ]) {
error ( $config [ 'error' ][ 'images_disabled' ]);
}
2012-04-11 18:49:22 +02:00
2012-04-12 16:18:19 +02:00
if ( ! ( $post [ 'has_file' ] || isset ( $post [ 'embed' ])) || (( $post [ 'op' ] && $config [ 'force_body_op' ]) || ( ! $post [ 'op' ] && $config [ 'force_body' ]))) {
2014-12-14 12:28:38 +01:00
// http://stackoverflow.com/a/4167053
$stripped_whitespace = preg_replace ( '/^[\pZ\pC]+|[\pZ\pC]+$/u' , '' , $post [ 'body' ]);
2012-04-12 16:18:19 +02:00
if ( $stripped_whitespace == '' ) {
2012-04-11 18:49:22 +02:00
error ( $config [ 'error' ][ 'tooshort_body' ]);
2011-01-19 02:37:31 +01:00
}
2012-04-11 18:49:22 +02:00
}
2014-12-14 12:25:43 +01:00
if ( $config [ 'force_subject_op' ] && $post [ 'op' ]) {
$stripped_whitespace = preg_replace ( '/^[\pZ\pC]+|[\pZ\pC]+$/u' , '' , $post [ 'subject' ]);
if ( $stripped_whitespace == '' ) {
error ( _ ( 'It is required to enter a subject when starting a new thread on this board.' ));
}
}
2012-04-11 18:49:22 +02:00
2013-06-18 19:21:41 +02:00
if ( ! $post [ 'op' ]) {
// Check if thread is locked
// but allow mods to post
if ( $thread [ 'locked' ] && ! hasPermission ( $config [ 'mod' ][ 'postinlocked' ], $board [ 'uri' ]))
2012-04-11 18:49:22 +02:00
error ( $config [ 'error' ][ 'locked' ]);
2013-06-18 19:21:41 +02:00
$numposts = numPosts ( $post [ 'thread' ]);
if ( $config [ 'reply_hard_limit' ] != 0 && $config [ 'reply_hard_limit' ] <= $numposts [ 'replies' ])
error ( $config [ 'error' ][ 'reply_hard_limit' ]);
if ( $post [ 'has_file' ] && $config [ 'image_hard_limit' ] != 0 && $config [ 'image_hard_limit' ] <= $numposts [ 'images' ])
error ( $config [ 'error' ][ 'image_hard_limit' ]);
2012-04-11 18:49:22 +02:00
}
2013-06-18 19:21:41 +02:00
2012-04-12 16:18:19 +02:00
if ( $post [ 'has_file' ]) {
2014-04-27 15:48:47 +02: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 16:18:19 +02:00
if ( $size > $config [ 'max_filesize' ])
2012-04-11 18:49:22 +02:00
error ( sprintf3 ( $config [ 'error' ][ 'filesize' ], array (
'sz' => number_format ( $size ),
'filesz' => number_format ( $size ),
'maxsz' => number_format ( $config [ 'max_filesize' ])
)));
2014-04-27 15:48:47 +02:00
$post [ 'filesize' ] = $size ;
2012-04-11 18:49:22 +02:00
}
2012-05-07 10:22:20 +02:00
$post [ 'capcode' ] = false ;
2013-10-27 23:13:09 +01:00
if ( $mod && preg_match ( '/^((.+) )?## (.+)$/' , $post [ 'name' ], $matches ) && ( in_array ( $board [ 'uri' ], $mod [ 'boards' ]) or $mod [ 'boards' ][ 0 ] == '*' )) {
2012-05-07 10:22:20 +02:00
$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 17:46:20 +01:00
}
2012-04-11 18:49:22 +02:00
}
$trip = generate_tripcode ( $post [ 'name' ]);
$post [ 'name' ] = $trip [ 0 ];
$post [ 'trip' ] = isset ( $trip [ 1 ]) ? $trip [ 1 ] : '' ;
2013-12-23 18:42:01 +01:00
$noko = false ;
2012-04-12 16:18:19 +02:00
if ( strtolower ( $post [ 'email' ]) == 'noko' ) {
2012-04-11 18:49:22 +02:00
$noko = true ;
$post [ 'email' ] = '' ;
2013-12-20 23:52:54 +01:00
} elseif ( strtolower ( $post [ 'email' ]) == 'nonoko' ){
$noko = false ;
$post [ 'email' ] = '' ;
2013-12-23 18:42:01 +01:00
} else $noko = $config [ 'always_noko' ];
2012-04-11 18:49:22 +02:00
2012-04-12 16:18:19 +02:00
if ( $post [ 'has_file' ]) {
2014-04-27 15:48:47 +02:00
$i = 0 ;
foreach ( $_FILES as $key => $file ) {
if ( $file [ 'size' ] && $file [ 'tmp_name' ]) {
$file [ 'filename' ] = urldecode ( get_magic_quotes_gpc () ? stripslashes ( $file [ 'name' ]) : $file [ 'name' ]);
$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 " ;
2014-09-26 00:53:56 +02:00
$file [ 'file' ] = $config [ 'dir' ][ 'img_root' ] . $board [ 'dir' ] . $config [ 'dir' ][ 'img' ] . $file [ 'file_id' ] . '.' . $file [ 'extension' ];
$file [ 'thumb' ] = $config [ 'dir' ][ 'img_root' ] . $board [ 'dir' ] . $config [ 'dir' ][ 'thumb' ] . $file [ 'file_id' ] . '.' . ( $config [ 'thumb_ext' ] ? $config [ 'thumb_ext' ] : $file [ 'extension' ]);
2014-04-27 15:48:47 +02:00
$post [ 'files' ][] = $file ;
$i ++ ;
}
}
2012-04-11 18:49:22 +02:00
}
2014-04-27 15:48:47 +02:00
if ( empty ( $post [ 'files' ])) $post [ 'has_file' ] = false ;
// 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' ]);
}
// Check for too many files
if ( sizeof ( $post [ 'files' ]) > $config [ 'max_images' ])
error ( $config [ 'error' ][ 'toomanyimages' ]);
2013-07-29 02:33:26 +02:00
if ( $config [ 'strip_combining_chars' ]) {
$post [ 'name' ] = strip_combining_chars ( $post [ 'name' ]);
$post [ 'email' ] = strip_combining_chars ( $post [ 'email' ]);
2013-07-29 02:46:00 +02:00
$post [ 'subject' ] = strip_combining_chars ( $post [ 'subject' ]);
2013-07-29 02:33:26 +02:00
$post [ 'body' ] = strip_combining_chars ( $post [ 'body' ]);
}
2012-04-11 18:49:22 +02:00
// Check string lengths
2012-04-12 16:18:19 +02:00
if ( mb_strlen ( $post [ 'name' ]) > 35 )
2012-04-11 18:49:22 +02:00
error ( sprintf ( $config [ 'error' ][ 'toolong' ], 'name' ));
2012-04-12 16:18:19 +02:00
if ( mb_strlen ( $post [ 'email' ]) > 40 )
2012-04-11 18:49:22 +02:00
error ( sprintf ( $config [ 'error' ][ 'toolong' ], 'email' ));
2012-04-12 16:18:19 +02:00
if ( mb_strlen ( $post [ 'subject' ]) > 100 )
2012-04-11 18:49:22 +02:00
error ( sprintf ( $config [ 'error' ][ 'toolong' ], 'subject' ));
2012-04-12 16:18:19 +02:00
if ( ! $mod && mb_strlen ( $post [ 'body' ]) > $config [ 'max_body' ])
2012-04-11 18:49:22 +02:00
error ( $config [ 'error' ][ 'toolong_body' ]);
2014-12-14 12:25:43 +01:00
if ( mb_strlen ( $post [ 'body' ]) < $config [ 'min_body' ] && $post [ 'op' ])
2015-04-04 04:37:11 +02:00
error ( sprintf ( _ ( 'OP must be at least %d chars on this board.' ), $config [ 'min_body' ]));
2012-04-12 16:18:19 +02:00
if ( mb_strlen ( $post [ 'password' ]) > 20 )
2012-04-11 18:49:22 +02:00
error ( sprintf ( $config [ 'error' ][ 'toolong' ], 'password' ));
2013-07-29 02:33:26 +02:00
2012-04-11 18:49:22 +02:00
wordfilters ( $post [ 'body' ]);
2015-04-04 04:36:03 +02:00
if ( $config [ 'max_newlines' ] > 0 ) {
preg_match_all ( " / \n / " , $post [ 'body' ], $nlmatches );
if ( isset ( $nlmatches [ 0 ]) && sizeof ( $nlmatches [ 0 ]) > $config [ 'max_newlines' ])
error ( sprintf ( _ ( 'Your post contains too many lines. This board only allows %d maximum.' ), $config [ 'max_newlines' ]));
}
2013-08-31 18:04:42 +02:00
2013-08-01 00:59:54 +02:00
$post [ 'body' ] = escape_markup_modifiers ( $post [ 'body' ]);
2012-04-11 18:49:22 +02:00
2013-08-16 13:25:56 +02:00
if ( $mod && isset ( $post [ 'raw' ]) && $post [ 'raw' ]) {
2013-08-16 19:39:58 +02:00
$post [ 'body' ] .= " \n <tinyboard raw html>1</tinyboard> " ;
2013-08-16 13:25:56 +02:00
}
2015-03-16 09:31:01 +01:00
if (( $config [ 'country_flags' ] && ( ! $config [ 'allow_no_country' ] || $config [ 'force_flag' ])) || ( $config [ 'country_flags' ] && $config [ 'allow_no_country' ] && ! isset ( $_POST [ 'no_country' ]))) {
2014-02-18 18:31:09 +01:00
require 'inc/lib/geoip/geoip.inc' ;
2014-02-19 00:01:40 +01:00
$gi = geoip\geoip_open ( 'inc/lib/geoip/GeoIPv6.dat' , GEOIP_STANDARD );
2014-02-11 14:40:22 +01:00
2014-02-18 18:31:09 +01:00
function ipv4to6 ( $ip ) {
2014-02-11 14:40:22 +01:00
if ( strpos ( $ip , ':' ) !== false ) {
2014-02-18 18:31:09 +01:00
if ( strpos ( $ip , '.' ) > 0 )
2014-02-11 14:40:22 +01:00
$ip = substr ( $ip , strrpos ( $ip , ':' ) + 1 );
else return $ip ; //native ipv6
2014-02-18 18:31:09 +01:00
}
$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 ;
2013-08-16 13:08:01 +02:00
}
2014-02-11 14:40:22 +01:00
2015-03-16 09:31:01 +01:00
$country_code = geoip\geoip_country_code_by_addr_v6 ( $gi , ipv4to6 ( $_SERVER [ 'REMOTE_ADDR' ]));
$country_name = geoip\geoip_country_name_by_addr_v6 ( $gi , ipv4to6 ( $_SERVER [ 'REMOTE_ADDR' ]));
if ( ! $country_code ) $country_code = 'A1' ;
if ( ! $country_name ) $country_name = 'Unknown' ;
$post [ 'body' ] .= " \n <tinyboard flag> " . strtolower ( $country_code ) . " </tinyboard> " .
" \n <tinyboard flag alt> $country_name </tinyboard> " ;
2013-08-16 13:08:01 +02:00
}
2015-03-16 09:31:01 +01: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 ]))
error ( _ ( 'Invalid flag selection!' ));
2014-04-19 14:56:59 +02:00
2015-03-16 09:31:01 +01:00
$flag_alt = isset ( $user_flag_alt ) ? $user_flag_alt : $config [ 'user_flags' ][ $user_flag ];
2014-04-19 14:56:59 +02:00
2015-03-16 09:31:01 +01:00
$post [ 'body' ] .= " \n <tinyboard flag> " . strtolower ( $user_flag ) . " </tinyboard> " .
" \n <tinyboard flag alt> " . $flag_alt . " </tinyboard> " ;
} else if ( $config [ 'force_flag' ]) {
error ( _ ( 'You must choose a flag to post on this board!' ));
}
2014-04-19 14:56:59 +02:00
}
2013-07-31 18:05:19 +02:00
if ( mysql_version () >= 50503 ) {
2013-07-31 04:08:56 +02:00
$post [ 'body_nomarkup' ] = $post [ 'body' ]; // Assume we're using the utf8mb4 charset
2015-04-16 20:02:11 +02:00
}
else {
2013-07-31 18:05:19 +02:00
// 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 18:49:22 +02:00
2014-12-14 12:25:43 +01:00
$post [ 'tracked_cites' ] = markup ( $post [ 'body' ], true , $post [ 'op' ]);
2013-09-06 15:09:18 +02:00
2012-04-11 18:49:22 +02:00
2012-04-12 16:18:19 +02:00
if ( $post [ 'has_file' ]) {
2014-10-22 08:53:29 +02:00
$allhashes = '' ;
2015-02-26 02:21:49 +01:00
2014-04-27 15:48:47 +02:00
foreach ( $post [ 'files' ] as $key => & $file ) {
if ( ! in_array ( $file [ 'extension' ], $config [ 'allowed_ext' ]) && ! in_array ( $file [ 'extension' ], $config [ 'allowed_ext_files' ]))
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' ]);
2014-10-22 08:53:29 +02:00
$md5cmd = $config [ 'bsd_md5' ] ? 'md5 -r' : 'md5sum' ;
if ( ( $output = shell_exec_error ( " cat " . escapeshellarg ( $upload ) . " | $md5cmd " )) !== false ) {
$explodedvar = explode ( ' ' , $output );
$hash = $explodedvar [ 0 ];
} else {
$hash = md5_file ( $upload );
}
2015-02-26 02:26:04 +01:00
// filter files by MD5
$query = prepare ( 'SELECT * FROM ``filters`` WHERE `type` = "md5" and `value` = :value' );
$query -> bindValue ( ':value' , $hash );
$result = $query -> execute () or error ( db_error ());
if ( $row = $query -> fetch ()) {
$reason = utf8tohtml ( $row [ 'reason' ]);
error ( " Sorry, cannot upload. Matched MD5 of disallowed file. Reason: { $reason } " );
}
2014-10-22 08:53:29 +02:00
$file [ 'hash' ] = $hash ;
$allhashes .= $hash ;
2014-04-27 15:48:47 +02:00
}
2011-01-18 14:41:43 +01:00
2014-10-22 08:53:29 +02:00
if ( count ( $post [ 'files' ]) == 1 ) {
2014-04-27 15:48:47 +02:00
$post [ 'filehash' ] = $hash ;
2014-10-22 08:53:29 +02:00
} else {
$post [ 'filehash' ] = md5 ( $allhashes );
2014-04-27 15:48:47 +02:00
}
2013-09-06 15:09:18 +02:00
}
if ( ! hasPermission ( $config [ 'mod' ][ 'bypass_filters' ], $board [ 'uri' ])) {
require_once 'inc/filters.php' ;
2011-03-26 12:50:03 +01:00
2013-09-06 15:09:18 +02:00
do_filters ( $post );
}
2015-04-14 17:01:32 +02:00
if ( $post [ 'has_file' ]) {
2014-04-27 15:48:47 +02:00
foreach ( $post [ 'files' ] as $key => & $file ) {
if ( $file [ 'is_an_image' ] && $config [ 'ie_mime_type_detection' ] !== false ) {
2012-04-11 18:49:22 +02:00
// Check IE MIME type detection XSS exploit
$buffer = file_get_contents ( $upload , null , null , null , 255 );
2012-04-12 16:18:19 +02:00
if ( preg_match ( $config [ 'ie_mime_type_detection' ], $buffer )) {
2012-04-11 18:49:22 +02:00
undoImage ( $post );
error ( $config [ 'error' ][ 'mime_exploit' ]);
}
2012-03-18 09:53:56 +01:00
2012-04-11 18:49:22 +02:00
require_once 'inc/image.php' ;
2012-03-10 10:53:41 +01:00
2012-07-19 08:16:50 +02:00
// find dimensions of an image using GD
2014-04-27 15:48:47 +02:00
if ( ! $size = @ getimagesize ( $file [ 'tmp_name' ])) {
2012-07-19 08:16:50 +02:00
error ( $config [ 'error' ][ 'invalidimg' ]);
}
if ( $size [ 0 ] > $config [ 'max_width' ] || $size [ 1 ] > $config [ 'max_height' ]) {
error ( $config [ 'error' ][ 'maxsize' ]);
2012-04-11 18:49:22 +02:00
}
2013-07-21 21:50:45 +02:00
2014-04-27 15:48:47 +02:00
if ( $config [ 'convert_auto_orient' ] && ( $file [ 'extension' ] == 'jpg' || $file [ 'extension' ] == 'jpeg' )) {
2013-07-21 21:50:45 +02: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 15:48:47 +02:00
if ( ! ( $config [ 'redraw_image' ] || (( $config [ 'strip_exif' ] && ! $config [ 'use_exiftool' ]) && ( $file [ 'extension' ] == 'jpg' || $file [ 'extension' ] == 'jpeg' )))) {
2013-08-04 02:34:59 +02:00
if ( in_array ( $config [ 'thumb_method' ], array ( 'convert' , 'convert+gifsicle' , 'gm' , 'gm+gifsicle' ))) {
2014-04-27 15:48:47 +02:00
$exif = @ exif_read_data ( $file [ 'tmp_name' ]);
2013-08-04 02:34:59 +02:00
$gm = in_array ( $config [ 'thumb_method' ], array ( 'gm' , 'gm+gifsicle' ));
2013-08-02 03:28:16 +02:00
if ( isset ( $exif [ 'Orientation' ]) && $exif [ 'Orientation' ] != 1 ) {
2013-08-04 04:14:25 +02:00
if ( $config [ 'convert_manual_orient' ]) {
$error = shell_exec_error (( $gm ? 'gm ' : '' ) . 'convert ' .
2014-04-27 15:48:47 +02:00
escapeshellarg ( $file [ 'tmp_name' ]) . ' ' .
2013-08-04 06:48:28 +02:00
ImageConvert :: jpeg_exif_orientation ( false , $exif ) . ' ' .
2013-08-04 06:54:27 +02:00
( $config [ 'strip_exif' ] ? '+profile "*"' :
( $config [ 'use_exiftool' ] ? '' : '+profile "*"' )
) . ' ' .
2014-04-27 15:48:47 +02:00
escapeshellarg ( $file [ 'tmp_name' ]));
2013-08-04 06:54:27 +02:00
if ( $config [ 'use_exiftool' ] && ! $config [ 'strip_exif' ]) {
2013-08-04 06:48:28 +02:00
if ( $exiftool_error = shell_exec_error (
2013-08-27 00:55:03 +02:00
'exiftool -overwrite_original -q -q -orientation=1 -n ' .
2014-04-27 15:48:47 +02:00
escapeshellarg ( $file [ 'tmp_name' ])))
error ( _ ( 'exiftool failed!' ), null , $exiftool_error );
2013-08-04 06:48:28 +02:00
} else {
// TODO: Find another way to remove the Orientation tag from the EXIF profile
// without needing `exiftool`.
}
2013-08-04 04:14:25 +02:00
} else {
$error = shell_exec_error (( $gm ? 'gm ' : '' ) . 'convert ' .
2014-04-27 15:48:47 +02:00
escapeshellarg ( $file [ 'tmp_name' ]) . ' -auto-orient ' . escapeshellarg ( $upload ));
2013-08-04 04:14:25 +02:00
}
if ( $error )
2014-04-27 15:48:47 +02:00
error ( _ ( 'Could not auto-orient image!' ), null , $error );
$size = @ getimagesize ( $file [ 'tmp_name' ]);
2013-08-04 06:54:27 +02:00
if ( $config [ 'strip_exif' ])
2014-04-27 15:48:47 +02:00
$file [ 'exif_stripped' ] = true ;
2013-08-02 03:28:16 +02:00
}
2013-01-23 17:24:38 +01:00
}
}
}
2012-04-11 18:49:22 +02:00
// create image object
2014-04-27 15:48:47 +02:00
$image = new Image ( $file [ 'tmp_name' ], $file [ 'extension' ], $size );
2012-04-12 16:18:19 +02:00
if ( $image -> size -> width > $config [ 'max_width' ] || $image -> size -> height > $config [ 'max_height' ]) {
2012-04-11 18:49:22 +02:00
$image -> delete ();
error ( $config [ 'error' ][ 'maxsize' ]);
}
2014-04-27 15:48:47 +02:00
$file [ 'width' ] = $image -> size -> width ;
$file [ 'height' ] = $image -> size -> height ;
2012-04-11 18:49:22 +02:00
2012-04-12 16:18:19 +02:00
if ( $config [ 'spoiler_images' ] && isset ( $_POST [ 'spoiler' ])) {
2014-04-27 15:48:47 +02:00
$file [ 'thumb' ] = 'spoiler' ;
2011-10-01 13:43:23 +02:00
2012-04-11 18:49:22 +02:00
$size = @ getimagesize ( $config [ 'spoiler_image' ]);
2014-04-27 15:48:47 +02:00
$file [ 'thumbwidth' ] = $size [ 0 ];
$file [ 'thumbheight' ] = $size [ 1 ];
2012-04-12 16:18:19 +02:00
} elseif ( $config [ 'minimum_copy_resize' ] &&
2012-04-11 18:49:22 +02:00
$image -> size -> width <= $config [ 'thumb_width' ] &&
$image -> size -> height <= $config [ 'thumb_height' ] &&
2014-04-27 15:48:47 +02:00
$file [ 'extension' ] == ( $config [ 'thumb_ext' ] ? $config [ 'thumb_ext' ] : $file [ 'extension' ])) {
2012-04-11 18:49:22 +02:00
// Copy, because there's nothing to resize
2014-04-27 15:48:47 +02:00
copy ( $file [ 'tmp_name' ], $file [ 'thumb' ]);
2012-04-11 18:49:22 +02:00
2014-04-27 15:48:47 +02:00
$file [ 'thumbwidth' ] = $image -> size -> width ;
$file [ 'thumbheight' ] = $image -> size -> height ;
2011-03-14 12:30:42 +01:00
} else {
2012-04-11 18:49:22 +02:00
$thumb = $image -> resize (
2014-04-27 15:48:47 +02:00
$config [ 'thumb_ext' ] ? $config [ 'thumb_ext' ] : $file [ 'extension' ],
2012-04-11 18:49:22 +02:00
$post [ 'op' ] ? $config [ 'thumb_op_width' ] : $config [ 'thumb_width' ],
$post [ 'op' ] ? $config [ 'thumb_op_height' ] : $config [ 'thumb_height' ]
);
2014-04-27 15:48:47 +02:00
$thumb -> to ( $file [ 'thumb' ]);
2012-04-11 18:49:22 +02:00
2014-04-27 15:48:47 +02:00
$file [ 'thumbwidth' ] = $thumb -> width ;
$file [ 'thumbheight' ] = $thumb -> height ;
2012-04-11 18:49:22 +02:00
$thumb -> _destroy ();
2011-03-14 12:30:42 +01:00
}
2012-04-11 18:49:22 +02:00
2014-04-27 15:48:47 +02:00
if ( $config [ 'redraw_image' ] || ( !@ $file [ 'exif_stripped' ] && $config [ 'strip_exif' ] && ( $file [ 'extension' ] == 'jpg' || $file [ 'extension' ] == 'jpeg' ))) {
2013-08-04 06:48:28 +02:00
if ( ! $config [ 'redraw_image' ] && $config [ 'use_exiftool' ]) {
2013-08-27 00:55:03 +02:00
if ( $error = shell_exec_error ( 'exiftool -overwrite_original -ignoreMinorErrors -q -q -all= ' .
2014-04-27 15:48:47 +02:00
escapeshellarg ( $file [ 'tmp_name' ])))
2014-05-10 01:31:16 +02:00
error ( _ ( 'Could not strip EXIF metadata!' ), null , $error );
2013-08-04 02:34:59 +02:00
} else {
2014-04-27 15:48:47 +02:00
$image -> to ( $file [ 'file' ]);
2013-08-04 02:34:59 +02:00
$dont_copy_file = true ;
}
2011-12-13 10:15:46 +01:00
}
2012-04-11 18:49:22 +02:00
$image -> destroy ();
2010-11-05 17:46:20 +01:00
} else {
2012-04-11 18:49:22 +02:00
// not an image
//copy($config['file_thumb'], $post['thumb']);
2014-04-27 15:48:47 +02:00
$file [ 'thumb' ] = 'file' ;
2013-08-18 12:53:01 +02:00
$size = @ getimagesize ( sprintf ( $config [ 'file_thumb' ],
2014-04-27 15:48:47 +02:00
isset ( $config [ 'file_icons' ][ $file [ 'extension' ]]) ?
$config [ 'file_icons' ][ $file [ 'extension' ]] : $config [ 'file_icons' ][ 'default' ]));
$file [ 'thumbwidth' ] = $size [ 0 ];
$file [ 'thumbheight' ] = $size [ 1 ];
2010-11-05 17:46:20 +01:00
}
2012-04-20 11:04:37 +02:00
if ( ! isset ( $dont_copy_file ) || ! $dont_copy_file ) {
2014-04-27 15:48:47 +02:00
if ( isset ( $file [ 'file_tmp' ])) {
if ( !@ rename ( $file [ 'tmp_name' ], $file [ 'file' ]))
2013-08-12 14:51:46 +02:00
error ( $config [ 'error' ][ 'nomove' ]);
2014-04-27 15:48:47 +02:00
chmod ( $file [ 'file' ], 0644 );
} elseif ( !@ move_uploaded_file ( $file [ 'tmp_name' ], $file [ 'file' ]))
2012-04-20 11:04:37 +02:00
error ( $config [ 'error' ][ 'nomove' ]);
2014-04-29 20:50:28 +02:00
}
2012-04-20 11:04:37 +02:00
}
2014-04-27 15:48:47 +02:00
2012-11-14 21:33:27 +01:00
if ( $config [ 'image_reject_repost' ]) {
if ( $p = getPostByHash ( $post [ 'filehash' ])) {
undoImage ( $post );
error ( sprintf ( $config [ 'error' ][ 'fileexists' ],
2013-12-23 19:01:08 +01:00
( $post [ 'mod' ] ? $config [ 'root' ] . $config [ 'file_mod' ] . '?/' : $config [ 'root' ]) .
( $board [ 'dir' ] . $config [ 'dir' ][ 'res' ] .
2012-11-14 21:33:27 +01:00
( $p [ 'thread' ] ?
$p [ 'thread' ] . '.html#' . $p [ 'id' ]
:
$p [ 'id' ] . '.html'
2013-12-23 19:01:08 +01:00
))
2012-11-14 21:33:27 +01: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 19:01:08 +01:00
( $post [ 'mod' ] ? $config [ 'root' ] . $config [ 'file_mod' ] . '?/' : $config [ 'root' ]) .
( $board [ 'dir' ] . $config [ 'dir' ][ 'res' ] .
2012-11-14 21:33:27 +01:00
( $p [ 'thread' ] ?
$p [ 'thread' ] . '.html#' . $p [ 'id' ]
:
$p [ 'id' ] . '.html'
2013-12-23 19:01:08 +01:00
))
2012-11-14 21:33:27 +01:00
));
}
}
2014-04-27 15:48:47 +02:00
}
2012-04-11 18:49:22 +02:00
2012-04-12 16:18:19 +02:00
if ( ! hasPermission ( $config [ 'mod' ][ 'postunoriginal' ], $board [ 'uri' ]) && $config [ 'robot_enable' ] && checkRobot ( $post [ 'body_nomarkup' ])) {
2012-04-11 18:49:22 +02:00
undoImage ( $post );
2012-04-12 16:18:19 +02:00
if ( $config [ 'robot_mute' ]) {
2012-04-11 18:49:22 +02:00
error ( sprintf ( $config [ 'error' ][ 'muted' ], mute ()));
2010-11-30 10:40:37 +01:00
} else {
2012-04-11 18:49:22 +02:00
error ( $config [ 'error' ][ 'unoriginal' ]);
2010-11-05 17:46:20 +01:00
}
}
2012-04-11 18:49:22 +02:00
// Remove board directories before inserting them into the database.
2012-04-12 16:18:19 +02:00
if ( $post [ 'has_file' ]) {
2014-04-27 15:48:47 +02:00
foreach ( $post [ 'files' ] as $key => & $file ) {
$file [ 'file_path' ] = $file [ 'file' ];
$file [ 'thumb_path' ] = $file [ 'thumb' ];
2014-09-26 00:53:56 +02:00
$file [ 'file' ] = mb_substr ( $file [ 'file' ], mb_strlen ( $config [ 'dir' ][ 'img_root' ] . $board [ 'dir' ] . $config [ 'dir' ][ 'img' ]));
2014-04-27 15:48:47 +02:00
if ( $file [ 'is_an_image' ] && $file [ 'thumb' ] != 'spoiler' )
2014-09-26 00:53:56 +02:00
$file [ 'thumb' ] = mb_substr ( $file [ 'thumb' ], mb_strlen ( $config [ 'dir' ][ 'img_root' ] . $board [ 'dir' ] . $config [ 'dir' ][ 'thumb' ]));
2014-04-27 15:48:47 +02:00
}
2012-04-11 18:49:22 +02:00
}
$post = ( object ) $post ;
2014-04-29 21:18:17 +02:00
$post -> files = array_map ( function ( $a ) { return ( object ) $a ; }, $post -> files );
$error = event ( 'post' , $post );
$post -> files = array_map ( function ( $a ) { return ( array ) $a ; }, $post -> files );
if ( $error ) {
2012-04-11 18:49:22 +02:00
undoImage (( array ) $post );
error ( $error );
}
$post = ( array ) $post ;
2014-04-27 15:48:47 +02:00
if ( $post [ 'files' ])
$post [ 'files' ] = $post [ 'files' ];
$post [ 'num_files' ] = sizeof ( $post [ 'files' ]);
2012-04-11 18:49:22 +02:00
2015-04-14 17:01:32 +02:00
// Commit the post to the database.
2012-05-27 12:55:56 +02:00
$post [ 'id' ] = $id = post ( $post );
2012-04-11 18:49:22 +02:00
2013-09-06 15:09:18 +02:00
insertFloodPost ( $post );
2015-04-14 17:01:32 +02:00
// Update statistics for this board.
updateStatisticsForPost ( $post );
2015-04-03 08:56:28 +02: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))
2015-04-03 09:06:29 +02:00
$query = prepare ( sprintf ( 'SELECT `id` 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' ]));
2015-04-03 08:56:28 +02:00
$query -> bindValue ( ':thread' , $post [ 'thread' ]);
$query -> bindValue ( ':limit' , $config [ 'cycle_limit' ], PDO :: PARAM_INT );
$query -> execute () or error ( db_error ( $query ));
2015-04-03 09:06:29 +02:00
while ( $dpost = $query -> fetch ()) {
deletePost ( $dpost [ 'id' ], false , false );
}
2015-04-03 08:56:28 +02:00
}
2013-09-06 15:09:18 +02:00
2012-05-07 15:51:15 +02:00
if ( isset ( $post [ 'antispam_hash' ])) {
incrementSpamHash ( $post [ 'antispam_hash' ]);
}
2012-04-11 18:49:22 +02:00
2013-08-29 10:55:25 +02:00
if ( isset ( $post [ 'tracked_cites' ]) && ! empty ( $post [ 'tracked_cites' ])) {
2013-08-29 04:38:37 +02:00
$insert_rows = array ();
2012-04-12 16:18:19 +02:00
foreach ( $post [ 'tracked_cites' ] as $cite ) {
2013-08-29 04:38:37 +02:00
$insert_rows [] = '(' .
$pdo -> quote ( $board [ 'uri' ]) . ', ' . ( int ) $id . ', ' .
$pdo -> quote ( $cite [ 0 ]) . ', ' . ( int ) $cite [ 1 ] . ')' ;
2012-04-11 18:49:22 +02:00
}
2013-08-31 05:33:26 +02:00
query ( 'INSERT INTO ``cites`` VALUES ' . implode ( ', ' , $insert_rows )) or error ( db_error ());
2012-04-11 18:49:22 +02:00
}
2015-04-04 03:49:02 +02:00
if ( ! $post [ 'op' ] && ! isset ( $_POST [ 'no-bump' ]) && strtolower ( $post [ 'email' ]) != 'sage' && ! $thread [ 'sage' ] && ( $thread [ 'cycle' ] || $config [ 'reply_limit' ] == 0 || $numposts [ 'replies' ] + 1 < $config [ 'reply_limit' ])) {
2012-04-11 18:49:22 +02:00
bumpThread ( $post [ 'thread' ]);
}
2012-04-12 16:18:19 +02:00
if ( isset ( $_SERVER [ 'HTTP_REFERER' ])) {
2012-04-11 18:49:22 +02:00
// Tell Javascript that we posted successfully
2012-04-12 16:18:19 +02:00
if ( isset ( $_COOKIE [ $config [ 'cookies' ][ 'js' ]]))
2012-04-11 18:49:22 +02: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 23:52:54 +01:00
if ( $noko ) {
2012-04-11 18:49:22 +02:00
$redirect = $root . $board [ 'dir' ] . $config [ 'dir' ][ 'res' ] .
sprintf ( $config [ 'file_page' ], $post [ 'op' ] ? $id : $post [ 'thread' ]) . ( ! $post [ 'op' ] ? '#' . $id : '' );
2013-08-10 23:16:30 +02: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' ], '/' )),
'page50' => str_replace ( '%d' , '(\d+)' , preg_quote ( $config [ 'file_page50' ], '/' )),
'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' ] .
sprintf ( $config [ 'file_page50' ], $post [ 'op' ] ? $id : $post [ 'thread' ]) . ( ! $post [ 'op' ] ? '#' . $id : '' );
}
}
2012-04-11 18:49:22 +02:00
} else {
$redirect = $root . $board [ 'dir' ] . $config [ 'file_index' ];
}
2015-03-31 10:17:20 +02:00
buildThread ( $post [ 'op' ] ? $id : $post [ 'thread' ]);
2012-04-11 18:49:22 +02:00
2012-04-12 16:18:19 +02:00
if ( $config [ 'syslog' ])
2012-04-11 18:49:22 +02:00
_syslog ( LOG_INFO , 'New post: /' . $board [ 'dir' ] . $config [ 'dir' ][ 'res' ] .
2012-04-13 19:43:04 +02:00
sprintf ( $config [ 'file_page' ], $post [ 'op' ] ? $id : $post [ 'thread' ]) . ( ! $post [ 'op' ] ? '#' . $id : '' ));
2012-04-11 18:49:22 +02:00
2013-06-21 22:36:20 +02:00
if ( ! $post [ 'mod' ]) header ( 'X-Associated-Content: "' . $redirect . '"' );
2013-07-18 21:19:03 +02:00
2013-09-15 06:03:27 +02: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 23:52:54 +01:00
'noko' => $noko ,
2013-09-15 06:03:27 +02:00
'id' => $id
));
}
2015-03-31 10:17:20 +02:00
if ( $config [ 'try_smarter' ] && $post [ 'op' ])
$build_pages = range ( 1 , $config [ 'max_pages' ]);
if ( $post [ 'op' ])
clean ();
event ( 'post-after' , $post );
buildIndex ();
2015-04-14 17:01:32 +02:00
2015-03-31 10:17:20 +02:00
// We are already done, let's continue our heavy-lifting work in the background (if we run off FastCGI)
2015-04-14 17:01:32 +02:00
if ( function_exists ( 'fastcgi_finish_request' )) {
2015-03-31 10:17:20 +02:00
@ fastcgi_finish_request ();
2015-04-14 17:01:32 +02:00
}
if ( $post [ 'op' ]) {
2015-03-31 10:17:20 +02:00
rebuildThemes ( 'post-thread' , $board [ 'uri' ]);
2015-04-14 17:01:32 +02:00
}
else {
2015-03-31 10:17:20 +02:00
rebuildThemes ( 'post' , $board [ 'uri' ]);
2015-04-14 17:01:32 +02:00
}
}
elseif ( isset ( $_POST [ 'appeal' ])) {
2013-09-21 04:51:23 +02:00
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 );
2014-10-21 14:50:25 +02:00
}
else {
2012-04-12 16:18:19 +02:00
if ( ! file_exists ( $config [ 'has_installed' ])) {
2012-04-11 18:49:22 +02:00
header ( 'Location: install.php' , true , $config [ 'redirect_http' ]);
} else {
// They opened post.php in their browser manually.
error ( $config [ 'error' ][ 'nopost' ]);
}
}