フォーク元 tak4/bibis
199 行
4.7 KiB
PHP
199 行
4.7 KiB
PHP
<?php
|
|
if (BIBIS_DEBUG) {
|
|
ini_set('display_errors', 1);
|
|
ini_set('display_startup_errors', 1);
|
|
error_reporting(E_ALL);
|
|
}
|
|
|
|
define('GUEST_ID', '-');
|
|
define('NOREPLY_ID', '-');
|
|
define('GUESTNAME', 'GUEST');
|
|
define('DELETEDNAME', 'DELETED');
|
|
define('DELETEDTEXT', 'この書き込みは削除されました。');
|
|
define('ACCEPT_IMAGE_TYPE', ['image/png', 'image/jpeg', 'image/gif']);
|
|
define('SESSION_NAME', 'bibis');
|
|
|
|
date_default_timezone_set('UTC');
|
|
|
|
ini_set('zlib.output_compression', 1);
|
|
|
|
if (OPEN_BASEDIR > '') {
|
|
ini_set('open_basedir', OPEN_BASEDIR);
|
|
}
|
|
|
|
session_name(SESSION_NAME);
|
|
session_start(['cookie_httponly' => 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 '<input type="hidden" name="' . htmlspecialchars($token_key) . '" value="' . $hashed . '">';
|
|
}
|
|
|
|
// String
|
|
|
|
function url_to_link($s) {
|
|
return preg_replace(
|
|
'/((http|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])?)/',
|
|
'<a href="\1" rel="noopener noreferrer">\1</a>',
|
|
$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;
|
|
}
|