true]); set_csrf_token(); // HTTP function get_fp() { return md5( ($_SERVER['HTTP_USER_AGENT'] ?? '') . ($_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? '') . ($_SERVER['HTTP_ACCEPT_ENCODING'] ?? '') . ($_SERVER['HTTP_ACCEPT'] ?? '') ); } function has_cookie() { return isset($_COOKIE['bibis']); } function on_error($code, $errors) { http_response_code(400); if (function_exists('bibis_http_header')) { bibis_http_header(); } $view['errors'] = $errors; require(__DIR__ . '/view/header.php'); exit; } function output_html($view, $_components) { if (function_exists('bibis_http_header')) { bibis_http_header(); } foreach ($_components as $_name) { require(__DIR__ . "/view/$_name"); } exit; } // CSRF token function set_csrf_token() { if (empty($_SESSION['csrf_token'])) { $_SESSION["csrf_token"] = bin2hex(random_bytes(32)); } } function get_csrf_token() { if (!REQUIRE_COOKIE && !isset($_SESSION['user'])) { $date = date('YmdH'); return $date . get_fp(); } return $_SESSION['csrf_token'] ?? null; } function get_csrf_token_2($force_cookie = false) { if (!REQUIRE_COOKIE && !isset($_SESSION['user'])) { $date = date('YmdH', strtotime('-1 hour')); return $date . get_fp(); } return $_SESSION['csrf_token'] ?? null; } function get_csrf_token_hashed($prefix = '', $token = null) { if ($token === null) { $token = get_csrf_token(); } if ($token === null) { return null; } return md5($prefix . $token); } function check_csrf_token() { $hashed = get_csrf_token_hashed(); $hashed_2 = get_csrf_token_hashed('', get_csrf_token_2()); if ($hashed === null || $hashed_2 === null) { return ['CSRF トークンが不正。要再試行。']; } $token_key = get_csrf_token_hashed('csrf_token'); $csrf_token = $_POST[$token_key] ?? ''; if ($csrf_token !== $hashed && $csrf_token !== $hashed_2) { return ['CSRF トークンが不正。要再試行。']; } return []; } function output_csrf_token_hidden() { $hashed = get_csrf_token_hashed(); if ($hashed === null) { return ''; } $token_key = get_csrf_token_hashed('csrf_token'); return ''; } // String function url_to_link($s) { return preg_replace( '/((http|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])?)/', '\1', $s ); } function mbtrim($s) { return preg_replace('/^\s+|\s+$/u', '', $s); } function twochan_trip($tripkey) { // twochan_trip('atomikka') -> '◆.../5Betyws' // Thanks: https://refirio.org/view/62 // Test data: https://trip-table.kokage.cc/sample01.php $tripkey = mb_convert_encoding($tripkey, 'sjis-win'); $salt = substr($tripkey . 'H.', 1, 2); $salt = preg_replace('/[^\.-z]/', '.', $salt); $salt = strtr($salt, ':;<=>?@[\\]^_`', 'ABCDEFGabcdef'); $trip = crypt($tripkey, $salt); $trip = substr($trip, -10); return '◆' . $trip; } function parse_key_value($s, $key_list) { $result = []; $lines = explode(PHP_EOL, $s); foreach ($lines as $line) { foreach ($key_list as $key) { if (strpos($line, "{$key}=") === 0) { $value = explode("{$key}=", $line, 2)[1] ?? null; $result[$key] = $value; $value = null; } } $key = null; } $lines = null; $line = null; return $result; } // File function mkdir_p($path, $permission = 0700) { if (file_exists($path)) { return true; } return mkdir($path, $permission); } function get_image_type($s) { $finfo = finfo_open(FILEINFO_MIME_TYPE); $type = finfo_buffer($finfo, $s); if (isset($type) && in_array($type, ACCEPT_IMAGE_TYPE)) { return $type; } return null; } function sitebase($path = '') { return SITEBASE . $path; } function get_style_css() { if (THEME === null || THEME === '') { return sitebase('style.css'); } return sitebase('theme/' . THEME); } // Limit and permission function can_post() { if (!post_limited()) { return false; } if (!ENABLE_GUEST && !isset($_SESSION['user'])) { return false; } return true; } function post_limited() { return ENABLE_POST && (count_post_today() < POST_LIMIT_PER_DAY) && (count_post() < POST_LIMIT); } function can_regist() { return ENABLE_REGISTER; }