"); $replace = array("&", "<", ">"); return str_replace($search, $replace, $string); } function cleanQuotes($string) { $search = array("'", "\""); $replace = array("'", """); return str_replace($search, $replace, $string); } function plural($count, $singular, $plural) { if ($plural == 's') { $plural = $singular . $plural; } return ($count == 1 ? $singular : $plural); } function threadUpdated($id) { rebuildThread($id); rebuildIndexes(); } function newPost($parent = TINYIB_NEWTHREAD) { return array( 'parent' => $parent, 'timestamp' => '0', 'bumped' => '0', 'ip' => '', 'name' => '', 'tripcode' => '', 'email' => '', 'nameblock' => '', 'subject' => '', 'message' => '', 'password' => '', 'file' => '', 'file_hex' => '', 'file_original' => '', 'file_size' => '0', 'file_size_formatted' => '', 'image_width' => '0', 'image_height' => '0', 'thumb' => '', 'thumb_width' => '0', 'thumb_height' => '0', 'stickied' => '0', 'locked' => '0', 'moderated' => '1' ); } function convertBytes($number) { $len = strlen($number); if ($len < 4) { return sprintf("%dB", $number); } elseif ($len <= 6) { return sprintf("%0.2fKB", $number / 1024); } elseif ($len <= 9) { return sprintf("%0.2fMB", $number / 1024 / 1024); } return sprintf("%0.2fGB", $number / 1024 / 1024 / 1024); } function nameAndTripcode($name) { if (preg_match("/(#|!)(.*)/", $name, $regs)) { $cap = $regs[2]; $cap_full = '#' . $regs[2]; if (function_exists('mb_convert_encoding')) { $recoded_cap = mb_convert_encoding($cap, 'SJIS', 'UTF-8'); if ($recoded_cap != '') { $cap = $recoded_cap; } } if (strpos($name, '#') === false) { $cap_delimiter = '!'; } elseif (strpos($name, '!') === false) { $cap_delimiter = '#'; } else { $cap_delimiter = (strpos($name, '#') < strpos($name, '!')) ? '#' : '!'; } if (preg_match("/(.*)(" . $cap_delimiter . ")(.*)/", $cap, $regs_secure)) { $cap = $regs_secure[1]; $cap_secure = $regs_secure[3]; $is_secure_trip = true; } else { $is_secure_trip = false; } $tripcode = ""; if ($cap != "") { // Copied from Futabally $cap = strtr($cap, "&", "&"); $cap = strtr($cap, ",", ", "); $salt = substr($cap . "H.", 1, 2); $salt = preg_replace("/[^\.-z]/", ".", $salt); $salt = strtr($salt, ":;<=>?@[\\]^_`", "ABCDEFGabcdef"); $tripcode = substr(crypt($cap, $salt), -10); } if ($is_secure_trip) { if ($cap != "") { $tripcode .= "!"; } $tripcode .= "!" . substr(md5($cap_secure . TINYIB_TRIPSEED), 2, 10); } return array(preg_replace("/(" . $cap_delimiter . ")(.*)/", "", $name), $tripcode); } return array($name, ""); } function nameBlock($name, $tripcode, $email, $timestamp, $capcode) { global $tinyib_anonymous; $anonymous = $tinyib_anonymous[array_rand($tinyib_anonymous)]; $output = ''; $output .= ($name == '' && $tripcode == '') ? $anonymous : $name; if ($tripcode != '') { $output .= '!' . $tripcode; } $output .= ''; if ($email != '' && strtolower($email) != 'noko') { $output = '' . $output . ''; } return $output . $capcode . ' ' . formatDate($timestamp); } function writePage($filename, $contents) { $tempfile = tempnam('res/', TINYIB_BOARD . 'tmp'); /* Create the temporary file */ $fp = fopen($tempfile, 'w'); fwrite($fp, $contents); fclose($fp); /* If we aren't able to use the rename function, try the alternate method */ if (!@rename($tempfile, $filename)) { copy($tempfile, $filename); unlink($tempfile); } chmod($filename, 0664); /* it was created 0600 */ } function fixLinksInRes($html) { $search = array(' href="css/', ' src="js/', ' href="src/', ' href="thumb/', ' href="res/', ' href="imgboard.php', ' href="catalog.html', ' href="favicon.ico', 'src="thumb/', 'src="inc/', 'src="sticky.png', 'src="lock.png', ' action="imgboard.php', ' action="catalog.html'); $replace = array(' href="../css/', ' src="../js/', ' href="../src/', ' href="../thumb/', ' href="../res/', ' href="../imgboard.php', ' href="../catalog.html', ' href="../favicon.ico', 'src="../thumb/', 'src="../inc/', 'src="../sticky.png', 'src="../lock.png', ' action="../imgboard.php', ' action="../catalog.html'); return str_replace($search, $replace, $html); } function _postLink($matches) { $post = postByID($matches[1]); if ($post) { $is_op = $post['parent'] == TINYIB_NEWTHREAD; return '' . $matches[0] . ''; } return $matches[0]; } function postLink($message) { return preg_replace_callback('/>>([0-9]+)/', '_postLink', $message); } function _finishWordBreak($matches) { return '' . str_replace(TINYIB_WORDBREAK_IDENTIFIER, '
', $matches[4]) . ''; } function finishWordBreak($message) { return str_replace(TINYIB_WORDBREAK_IDENTIFIER, '
', preg_replace_callback('/(.*?)<\/a>/', '_finishWordBreak', $message)); } function colorQuote($message) { if (substr($message, -1, 1) != "\n") { $message .= "\n"; } return preg_replace('/^(>[^\>](.*))\n/m', '\\1' . "\n", $message); } function deletePostImages($post) { if (!isEmbed($post['file_hex']) && $post['file'] != '') { @unlink('src/' . $post['file']); } if ($post['thumb'] != '') { @unlink('thumb/' . $post['thumb']); } } function deletePost($id) { $id = intval($id); $is_op = false; $parent = 0; $op = array(); $posts = postsInThreadByID($id, false); foreach ($posts as $post) { if ($post['parent'] == TINYIB_NEWTHREAD) { if ($post['id'] == $id) { $is_op = true; } $op = $post; continue; } else if ($post['id'] == $id) { $parent = $post['parent']; } deletePostImages($post); deleteReportsByPost($post['id']); deletePostByID($post['id']); } if (!empty($op)) { deletePostImages($op); deleteReportsByPost($op['id']); deletePostByID($op['id']); } if ($is_op) { @unlink('res/' . $id . '.html'); return; } $current_bumped = 0; $new_bumped = 0; $posts = postsInThreadByID($parent, false); foreach ($posts as $post) { if ($post['parent'] == TINYIB_NEWTHREAD) { $current_bumped = $post['bumped']; } else if ($post['id'] == $id || strtolower($post['email']) == 'sage') { continue; } $new_bumped = $post['timestamp']; } if ($new_bumped >= $current_bumped) { return; } updatePostBumped($parent, $new_bumped); rebuildIndexes(); } function checkCAPTCHA($mode) { if ($mode === 'hcaptcha') { $captcha = isset($_POST['h-captcha-response']) ? $_POST['h-captcha-response'] : ''; if ($captcha == '') { fancyDie('Failed CAPTCHA. Reason:
Please click the checkbox labeled "I am human".'); } $data = array( 'secret' => TINYIB_HCAPTCHA_SECRET, 'response' => $captcha ); $verify = curl_init(); curl_setopt($verify, CURLOPT_URL, "https://hcaptcha.com/siteverify"); curl_setopt($verify, CURLOPT_POST, true); curl_setopt($verify, CURLOPT_POSTFIELDS, http_build_query($data)); curl_setopt($verify, CURLOPT_RETURNTRANSFER, true); $verifyResponse = curl_exec($verify); $responseData = json_decode($verifyResponse); if (!isset($responseData->success) || !$responseData->success) { fancyDie('Failed CAPTCHA.'); } } else if ($mode === 'recaptcha') { require_once 'inc/recaptcha/autoload.php'; $captcha = isset($_POST['g-recaptcha-response']) ? $_POST['g-recaptcha-response'] : ''; $failed_captcha = true; $recaptcha = new \ReCaptcha\ReCaptcha(TINYIB_RECAPTCHA_SECRET); $resp = $recaptcha->verify($captcha, remoteAddress()); if ($resp->isSuccess()) { $failed_captcha = false; } if ($failed_captcha) { $captcha_error = 'Failed CAPTCHA.'; $error_reason = ''; if (count($resp->getErrorCodes()) == 1) { $error_codes = $resp->getErrorCodes(); $error_reason = $error_codes[0]; } if ($error_reason == 'missing-input-response') { $captcha_error .= ' Please click the checkbox labeled "I\'m not a robot".'; } else { $captcha_error .= ' Reason:'; foreach ($resp->getErrorCodes() as $error) { $captcha_error .= '
' . $error; } } fancyDie($captcha_error); } } else if ($mode) { // Simple CAPTCHA $captcha = isset($_POST['captcha']) ? strtolower(trim($_POST['captcha'])) : ''; $captcha_solution = isset($_SESSION['tinyibcaptcha']) ? strtolower(trim($_SESSION['tinyibcaptcha'])) : ''; if ($captcha == '') { fancyDie(__('Please enter the CAPTCHA text.')); } else if ($captcha != $captcha_solution) { fancyDie(__('Incorrect CAPTCHA text entered. Please try again.
Click the image to retrieve a new CAPTCHA.')); } } } function checkBanned() { $ban = banByIP(remoteAddress()); if ($ban) { if ($ban['expire'] == 0 || $ban['expire'] > time()) { $expire = ($ban['expire'] > 0) ? ('
This ban will expire ' . formatDate($ban['expire'])) : '
This ban is permanent and will not expire.'; $reason = ($ban['reason'] == '') ? '' : ('
Reason: ' . $ban['reason']); fancyDie('Your IP address ' . remoteAddress() . ' has been banned from posting on this image board. ' . $expire . $reason); } else { clearExpiredBans(); } } } function checkKeywords($text) { $keywords = allKeywords(); foreach ($keywords as $keyword) { if (substr($keyword['text'], 0, 7) == 'regexp:') { if (preg_match(substr($keyword['text'], 7), $text)) { $keyword['text'] = substr($keyword['text'], 7); return $keyword; } continue; } if (stripos($text, $keyword['text']) !== false) { return $keyword; } } return array(); } function checkFlood() { if (TINYIB_DELAY > 0) { $lastpost = lastPostByIP(); if ($lastpost) { if ((time() - $lastpost['timestamp']) < TINYIB_DELAY) { fancyDie("Please wait a moment before posting again. You will be able to make another post in " . (TINYIB_DELAY - (time() - $lastpost['timestamp'])) . " " . plural(TINYIB_DELAY - (time() - $lastpost['timestamp']), "second", "seconds") . "."); } } } } function checkMessageSize() { if (TINYIB_MAXMESSAGE > 0 && _strlen($_POST['message']) > TINYIB_MAXMESSAGE) { fancyDie(sprintf(__('Please shorten your message, or post it in multiple parts. Your message is %1$d characters long, and the maximum allowed is %2$d.'), _strlen($_POST['message']), TINYIB_MAXMESSAGE)); } } function checkAutoHide($post) { if (TINYIB_AUTOHIDE <= 0) { return; } $reports = reportsByPost($post['id']); if (count($reports) >= TINYIB_AUTOHIDE) { approvePostByID($post['id'], 0); $parent_id = $post['parent'] == TINYIB_NEWTHREAD ? $post['id'] : $post['parent']; threadUpdated($parent_id); } } function manageCheckLogIn($requireKey) { $account = array(); $loggedin = false; $isadmin = false; $key = (isset($_GET['manage']) && $_GET['manage'] != '') ? hashData($_GET['manage']) : ''; if ($key == '' && isset($_SESSION['tinyib_key'])) { $key = $_SESSION['tinyib_key']; } if (TINYIB_MANAGEKEY != '' && $key !== hashData(TINYIB_MANAGEKEY)) { $_SESSION['tinyib_key'] = ''; $_SESSION['tinyib_account'] = ''; session_destroy(); if ($requireKey) { fancyDie(__('Invalid key.')); } return array($account, $loggedin, $isadmin); } if (isset($_POST['username']) && isset($_POST['managepassword']) && $_POST['username'] != '' && $_POST['managepassword'] != '') { checkCAPTCHA(TINYIB_MANAGECAPTCHA); $a = accountByUsername($_POST['username']); if (empty($a) || hashData($_POST['managepassword'], true) !== $a['password']) { fancyDie(__('Invalid username or password.')); } $_SESSION['tinyib_key'] = hashData(TINYIB_MANAGEKEY); $_SESSION['tinyib_username'] = $a['username']; $_SESSION['tinyib_password'] = $a['password']; // Prevent reauthentication $_POST['username'] = ''; $_POST['managepassword'] = ''; } if (isset($_SESSION['tinyib_username']) && isset($_SESSION['tinyib_password'])) { $a = accountByUsername($_SESSION['tinyib_username']); if (!empty($a) && $a['password'] == $_SESSION['tinyib_password'] && $a['role'] != TINYIB_DISABLED) { $account = $a; $loggedin = true; if ($account['role'] == TINYIB_SUPER_ADMINISTRATOR || $account['role'] == TINYIB_ADMINISTRATOR) { $isadmin = true; } $account['lastactive'] = time(); updateAccount($account); } } return array($account, $loggedin, $isadmin); } function manageLogAction($action) { global $account; $account_id = 0; if (isset($account['id'])) { $account_id = $account['id']; } $log = array( 'timestamp' => time(), 'account' => $account_id, 'message' => $action, ); insertLog($log); } function setParent() { if (isset($_POST["parent"])) { if ($_POST["parent"] != TINYIB_NEWTHREAD) { if (!threadExistsByID($_POST['parent'])) { fancyDie(__('Invalid parent thread ID supplied, unable to create post.')); } return $_POST["parent"]; } } return TINYIB_NEWTHREAD; } function getParent($post) { if ($post['parent'] == TINYIB_NEWTHREAD) { return $post['id']; } return $post['parent']; } function isStaffPost() { if (isset($_POST['staffpost'])) { list($loggedin, $isadmin) = manageCheckLogIn(false); return $loggedin; } return false; } function validateFileUpload() { switch ($_FILES['file']['error']) { case UPLOAD_ERR_OK: break; case UPLOAD_ERR_FORM_SIZE: fancyDie(sprintf(__('That file is larger than %s.'), TINYIB_MAXKBDESC)); break; case UPLOAD_ERR_INI_SIZE: fancyDie(sprintf(__('The uploaded file exceeds the upload_max_filesize directive (%s) in php.ini.'), ini_get('upload_max_filesize'))); break; case UPLOAD_ERR_PARTIAL: fancyDie(__('The uploaded file was only partially uploaded.')); break; case UPLOAD_ERR_NO_FILE: fancyDie(__('No file was uploaded.')); break; case UPLOAD_ERR_NO_TMP_DIR: fancyDie(__('Missing a temporary folder.')); break; case UPLOAD_ERR_CANT_WRITE: fancyDie(__('Failed to write file to disk')); break; default: fancyDie(__('Unable to save the uploaded file.')); } } function checkDuplicateFile($hex) { $hexmatches = postsByHex($hex); if (count($hexmatches) > 0) { foreach ($hexmatches as $hexmatch) { fancyDie(sprintf(__('Duplicate file uploaded. That file has already been posted here.'), 'res/' . (($hexmatch['parent'] == TINYIB_NEWTHREAD) ? $hexmatch['id'] : $hexmatch['parent']) . '.html#' . $hexmatch['id'])); } } } function thumbnailDimensions($post) { if ($post['parent'] == TINYIB_NEWTHREAD) { $max_width = TINYIB_MAXWOP; $max_height = TINYIB_MAXHOP; } else { $max_width = TINYIB_MAXW; $max_height = TINYIB_MAXH; } return ($post['image_width'] > $max_width || $post['image_height'] > $max_height) ? array($max_width, $max_height) : array($post['image_width'], $post['image_height']); } function videoDimensions($file_location) { $discard = ''; $exit_status = 1; exec("ffprobe -version", $discard, $exit_status); if ($exit_status != 0) { fancyDie('FFMPEG is not installed, or the commands ffmpeg and ffprobe are not in the server\'s $PATH.
Install FFMPEG, or set TINYIB_THUMBNAIL to \'gd\' or \'imagemagick\'.'); } $dimensions = ''; $exit_status = 1; exec("ffprobe -hide_banner -loglevel error -of csv=p=0 -select_streams v -show_entries stream=width,height $file_location", $dimensions, $exit_status); if ($exit_status != 0) { return array(0, 0); } if (is_array($dimensions)) { $dimensions = $dimensions[0]; } $split = explode(',', $dimensions); if (count($split) != 2) { return array(0, 0); } return array(intval($split[0]), intval($split[1])); } function videoDuration($file_location) { $discard = ''; $exit_status = 1; exec("ffprobe -version", $discard, $exit_status); if ($exit_status != 0) { fancyDie('FFMPEG is not installed, or the commands ffmpeg and ffprobe are not in the server\'s $PATH.
Install FFMPEG, or set TINYIB_THUMBNAIL to \'gd\' or \'imagemagick\'.'); } $duration = ''; $exit_status = 1; exec("ffprobe -hide_banner -loglevel error -of csv=p=0 -show_entries format=duration $file_location", $duration, $exit_status); if ($exit_status != 0) { return 0; } if (is_array($duration)) { $duration = $duration[0]; } return floatval($duration); } function ffmpegThumbnail($file_location, $thumb_location, $new_w, $new_h) { $discard = ''; $exit_status = 1; exec("ffmpeg -version", $discard, $exit_status); if ($exit_status != 0) { fancyDie('FFMPEG is not installed, or the commands ffmpeg and ffprobe are not in the server\'s $PATH.
Install FFMPEG, or set TINYIB_THUMBNAIL to \'gd\' or \'imagemagick\'.'); } $quarter = videoDuration($file_location) / 4; $exit_status = 1; exec("ffmpeg -hide_banner -loglevel error -ss $quarter -i $file_location -frames:v 1 -vf scale=w=$new_w:h=$new_h:force_original_aspect_ratio=decrease $thumb_location", $discard, $exit_status); if ($exit_status != 0) { return false; } } function createThumbnail($file_location, $thumb_location, $new_w, $new_h, $spoiler) { $system = explode(".", $thumb_location); $system = array_reverse($system); if (TINYIB_THUMBNAIL == 'gd' || (TINYIB_THUMBNAIL == 'ffmpeg' && preg_match("/jpg|jpeg/", $system[0]))) { if (preg_match("/jpg|jpeg/", $system[0])) { $src_img = imagecreatefromjpeg($file_location); } else if (preg_match("/png/", $system[0])) { $src_img = imagecreatefrompng($file_location); } else if (preg_match("/gif/", $system[0])) { $src_img = imagecreatefromgif($file_location); } else { return false; } if (!$src_img) { fancyDie(__('Unable to read the uploaded file while creating its thumbnail. A common cause for this is an incorrect extension when the file is actually of a different type.')); } $old_x = imageSX($src_img); $old_y = imageSY($src_img); $percent = ($old_x > $old_y) ? ($new_w / $old_x) : ($new_h / $old_y); $thumb_w = round($old_x * $percent); $thumb_h = round($old_y * $percent); $dst_img = imagecreatetruecolor($thumb_w, $thumb_h); if (preg_match("/png/", $system[0]) && imagepng($src_img, $thumb_location)) { imagealphablending($dst_img, false); imagesavealpha($dst_img, true); $color = imagecolorallocatealpha($dst_img, 0, 0, 0, 0); imagefilledrectangle($dst_img, 0, 0, $thumb_w, $thumb_h, $color); imagecolortransparent($dst_img, $color); imagecopyresampled($dst_img, $src_img, 0, 0, 0, 0, $thumb_w, $thumb_h, $old_x, $old_y); } else { fastimagecopyresampled($dst_img, $src_img, 0, 0, 0, 0, $thumb_w, $thumb_h, $old_x, $old_y); } if (preg_match("/png/", $system[0])) { if (!imagepng($dst_img, $thumb_location)) { return false; } } else if (preg_match("/jpg|jpeg/", $system[0])) { if (!imagejpeg($dst_img, $thumb_location, 70)) { return false; } } else if (preg_match("/gif/", $system[0])) { if (!imagegif($dst_img, $thumb_location)) { return false; } } imagedestroy($dst_img); imagedestroy($src_img); } else if (TINYIB_THUMBNAIL == 'ffmpeg') { ffmpegThumbnail($file_location, $thumb_location, $new_w, $new_h); } else { // ImageMagick $discard = ''; $exit_status = 1; exec("convert -version", $discard, $exit_status); if ($exit_status != 0) { fancyDie('ImageMagick is not installed, or the convert command is not in the server\'s $PATH.
Install ImageMagick, or set TINYIB_THUMBNAIL to \'gd\' or \'ffmpeg\'.'); } $exit_status = 1; exec("convert $file_location -auto-orient -thumbnail '" . $new_w . "x" . $new_h . "' -coalesce -layers OptimizeFrame -depth 4 -type palettealpha $thumb_location", $discard, $exit_status); if ($exit_status != 0) { return false; } } if (!$spoiler) { return true; } if (preg_match("/jpg|jpeg/", $system[0])) { $src_img = imagecreatefromjpeg($thumb_location); } else if (preg_match("/png/", $system[0])) { $src_img = imagecreatefrompng($thumb_location); } else if (preg_match("/gif/", $system[0])) { $src_img = imagecreatefromgif($thumb_location); } else { return true; } if (!$src_img) { fancyDie(__('Unable to read the uploaded file while creating its thumbnail. A common cause for this is an incorrect extension when the file is actually of a different type.')); } $gaussian = array(array(1.0, 2.0, 1.0), array(2.0, 4.0, 2.0), array(1.0, 2.0, 1.0)); for ($x = 1; $x <= 149; $x++) { imageconvolution($src_img, $gaussian, 16, 0); } if (preg_match("/png/", $system[0])) { if (!imagepng($src_img, $thumb_location)) { return false; } } else if (preg_match("/jpg|jpeg/", $system[0])) { if (!imagejpeg($src_img, $thumb_location, 70)) { return false; } } else if (preg_match("/gif/", $system[0])) { if (!imagegif($src_img, $thumb_location)) { return false; } } imagedestroy($src_img); return true; } function fastimagecopyresampled(&$dst_image, &$src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h, $quality = 3) { // Author: Tim Eckel - Date: 12/17/04 - Project: FreeRingers.net - Freely distributable. if (empty($src_image) || empty($dst_image)) { return false; } if ($quality <= 1) { $temp = imagecreatetruecolor($dst_w + 1, $dst_h + 1); imagecopyresized($temp, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w + 1, $dst_h + 1, $src_w, $src_h); imagecopyresized($dst_image, $temp, 0, 0, 0, 0, $dst_w, $dst_h, $dst_w, $dst_h); imagedestroy($temp); } elseif ($quality < 5 && (($dst_w * $quality) < $src_w || ($dst_h * $quality) < $src_h)) { $tmp_w = $dst_w * $quality; $tmp_h = $dst_h * $quality; $temp = imagecreatetruecolor($tmp_w + 1, $tmp_h + 1); imagecopyresized($temp, $src_image, $dst_x * $quality, $dst_y * $quality, $src_x, $src_y, $tmp_w + 1, $tmp_h + 1, $src_w, $src_h); imagecopyresampled($dst_image, $temp, 0, 0, 0, 0, $dst_w, $dst_h, $tmp_w, $tmp_h); imagedestroy($temp); } else { imagecopyresampled($dst_image, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h); } return true; } function addVideoOverlay($thumb_location) { if (!file_exists('video_overlay.png')) { return; } if (TINYIB_THUMBNAIL == 'gd' || TINYIB_THUMBNAIL == 'ffmpeg') { if (substr($thumb_location, -4) == ".jpg") { $thumbnail = imagecreatefromjpeg($thumb_location); } else { $thumbnail = imagecreatefrompng($thumb_location); } list($width, $height, $type, $attr) = getimagesize($thumb_location); $overlay_play = imagecreatefrompng('video_overlay.png'); imagealphablending($overlay_play, false); imagesavealpha($overlay_play, true); list($overlay_width, $overlay_height, $overlay_type, $overlay_attr) = getimagesize('video_overlay.png'); if (substr($thumb_location, -4) == ".png") { imagecolortransparent($thumbnail, imagecolorallocatealpha($thumbnail, 0, 0, 0, 127)); imagealphablending($thumbnail, true); imagesavealpha($thumbnail, true); } imagecopy($thumbnail, $overlay_play, ($width / 2) - ($overlay_width / 2), ($height / 2) - ($overlay_height / 2), 0, 0, $overlay_width, $overlay_height); if (substr($thumb_location, -4) == ".jpg") { imagejpeg($thumbnail, $thumb_location); } else { imagepng($thumbnail, $thumb_location); } } else { // imagemagick $discard = ''; $exit_status = 1; exec("convert $thumb_location video_overlay.png -gravity center -composite -quality 75 $thumb_location", $discard, $exit_status); } } function strallpos($haystack, $needle, $offset = 0) { $result = array(); for ($i = $offset; $i < _strlen($haystack); $i++) { $pos = _strpos($haystack, $needle, $i); if ($pos !== False) { $offset = $pos; if ($offset >= $i) { $i = $offset; $result[] = $offset; } } } return $result; } function url_get_contents($url) { if (!function_exists('curl_init')) { return file_get_contents($url); } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $output = curl_exec($ch); $responsecode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if (intval($responsecode) != 200) { return ''; } return $output; } function isEmbed($file_hex) { global $tinyib_embeds; return in_array($file_hex, array_keys($tinyib_embeds)); } function getEmbed($url) { global $tinyib_embeds; foreach ($tinyib_embeds as $service => $service_url) { $service_url = str_ireplace("TINYIBEMBED", urlencode($url), $service_url); $data = url_get_contents($service_url); if ($data != '') { $result = json_decode($data, true); if (!empty($result)) { return array($service, $result); } } } return array('', array()); } function attachFile($post, $filepath, $filename, $uploaded, $spoiler) { global $tinyib_uploads; if (!is_file($filepath) || !is_readable($filepath)) { @unlink($filepath); fancyDie(__('File transfer failure. Please retry the submission.')); } $file_mime_split = explode(' ', trim(mime_content_type($filepath))); if (count($file_mime_split) > 0) { $file_mime = strtolower(array_pop($file_mime_split)); } else { if (!@getimagesize($filepath)) { @unlink($filepath); fancyDie(__('Failed to read the MIME type and size of the uploaded file. Please retry the submission.')); } $file_mime = mime_content_type($filepath); } if (empty($file_mime) || !isset($tinyib_uploads[$file_mime])) { fancyDie(supportedFileTypes()); } $file_name_pre = time() . substr(microtime(), 2, 3); $file_name = $file_name_pre . '.' . $tinyib_uploads[$file_mime][0]; $file_src = 'src/' . $file_name; if ($uploaded) { if (!move_uploaded_file($filepath, $file_src)) { fancyDie(__('Could not copy uploaded file.')); } } else { if (!rename($filepath, $file_src)) { @unlink($filepath); fancyDie(__('Could not copy uploaded file.')); } } $filepath = $file_src; $filesize = filesize($filepath); if (filesize($filepath) != $filesize) { @unlink($filepath); fancyDie(__('File transfer failure. Please go back and try again.')); } else if (TINYIB_MAXKB > 0 && $filesize > (TINYIB_MAXKB * 1024)) { @unlink($filepath); fancyDie(sprintf(__('That file is larger than %s.'), TINYIB_MAXKBDESC)); } if (TINYIB_STRIPMETADATA) { stripMetadata($filepath); } $post['file'] = $file_name; $post['file_original'] = trim(htmlentities(_substr($filename, 0, 50), ENT_QUOTES)); $post['file_hex'] = md5_file($filepath); $post['file_size'] = $filesize; $post['file_size_formatted'] = convertBytes($post['file_size']); checkDuplicateFile($post['file_hex']); if (in_array($file_mime, array('image/jpeg', 'image/pjpeg', 'image/png', 'image/gif', 'application/x-shockwave-flash'))) { $file_info = getimagesize($file_src); $post['image_width'] = $file_info[0] != '' ? $file_info[0] : 0; $post['image_height'] = $file_info[1] != '' ? $file_info[1] : 0; } if (isset($tinyib_uploads[$file_mime][1])) { $thumbfile_split = explode('.', $tinyib_uploads[$file_mime][1]); $post['thumb'] = $file_name_pre . 's.' . array_pop($thumbfile_split); if (!copy($tinyib_uploads[$file_mime][1], 'thumb/' . $post['thumb'])) { @unlink($file_src); fancyDie(__('Could not create thumbnail.')); } if ($file_mime == 'application/x-shockwave-flash') { addVideoOverlay('thumb/' . $post['thumb']); } } else if (in_array($file_mime, array('image/jpeg', 'image/pjpeg', 'image/png', 'image/gif'))) { $post['thumb'] = $file_name_pre . 's.' . $tinyib_uploads[$file_mime][0]; list($thumb_maxwidth, $thumb_maxheight) = thumbnailDimensions($post); if (!createThumbnail($file_src, 'thumb/' . $post['thumb'], $thumb_maxwidth, $thumb_maxheight, $spoiler)) { @unlink($file_src); fancyDie(__('Could not create thumbnail.')); } } else if ($file_mime == 'audio/webm' || $file_mime == 'video/webm' || $file_mime == 'audio/mp4' || $file_mime == 'video/mp4') { list($post['image_width'], $post['image_height']) = videoDimensions($file_src); if ($post['image_width'] > 0 && $post['image_height'] > 0) { list($thumb_maxwidth, $thumb_maxheight) = thumbnailDimensions($post); $post['thumb'] = $file_name_pre . 's.jpg'; ffmpegThumbnail($file_src, 'thumb/' . $post['thumb'], $thumb_maxwidth, $thumb_maxheight); $thumb_info = getimagesize('thumb/' . $post['thumb']); $post['thumb_width'] = $thumb_info[0]; $post['thumb_height'] = $thumb_info[1]; if ($post['thumb_width'] <= 0 || $post['thumb_height'] <= 0) { @unlink($file_src); @unlink('thumb/' . $post['thumb']); fancyDie(__('Sorry, your video appears to be corrupt.')); } addVideoOverlay('thumb/' . $post['thumb']); } $duration = videoDuration($file_src); if ($duration > 0) { $mins = floor(round($duration / 1000) / 60); $secs = str_pad(floor(round($duration / 1000) % 60), 2, '0', STR_PAD_LEFT); $post['file_original'] = "$mins:$secs" . ($post['file_original'] != '' ? (', ' . $post['file_original']) : ''); } } if ($post['thumb'] != '') { $thumb_info = getimagesize('thumb/' . $post['thumb']); $post['thumb_width'] = $thumb_info[0]; $post['thumb_height'] = $thumb_info[1]; if ($post['thumb_width'] <= 0 || $post['thumb_height'] <= 0) { @unlink($file_src); @unlink('thumb/' . $post['thumb']); fancyDie(__('Sorry, your video appears to be corrupt.')); } } return $post; } function stripMetadata($filename) { $discard = ''; $exit_status = 1; exec("exiftool -ver", $discard, $exit_status); if ($exit_status != 0) { fancyDie('ExifTool is not installed, or the exiftool executable is not in the server\'s $PATH.
Install ExifTool, or set TINYIB_STRIPMETADATA to false.'); } $discard = ''; $exit_status = 1; exec("exiftool -All= -overwrite_original_in_place " . escapeshellarg($filename), $discard, $exit_status); } function formatDate($timestamp) { return @strftime(TINYIB_DATEFMT, $timestamp); } function remoteAddress() { if (TINYIB_CLOUDFLARE && isset($_SERVER['HTTP_CF_CONNECTING_IP'])) { return $_SERVER['HTTP_CF_CONNECTING_IP']; } return $_SERVER['REMOTE_ADDR']; } function installedViaGit() { return is_dir('.git'); }