diff --git a/core/imageboard/image.php b/core/imageboard/image.php index fbfcc1a2..f3fce5e7 100644 --- a/core/imageboard/image.php +++ b/core/imageboard/image.php @@ -191,7 +191,13 @@ class Image { return null; } fwrite($fp, json_encode($req)); - $data = fgets($fp, 1024); + $data = ""; + while (($buffer = fgets($fp, 4096)) !== false) { + $data .= $buffer; + } + if (!feof($fp)) { + die("Error: unexpected fgets() fail in query_accelerator($req)\n"); + } fclose($fp); return json_decode($data); } diff --git a/core/sys_config.php b/core/sys_config.php index 296885a8..7f07e6db 100644 --- a/core/sys_config.php +++ b/core/sys_config.php @@ -41,6 +41,7 @@ _d("CORE_EXTS", "bbcode,user,mail,upload,image,view,handle_pixel,ext_manager,set _d("EXTRA_EXTS", ""); // string optional extra extensions _d("BASE_URL", null); // string force a specific base URL (default is auto-detect) _d("MIN_PHP_VERSION", '7.0');// string minimum supported PHP version +_d("SLOW_PAGES", null); // float log pages which take more time than this _d("ENABLED_MODS", "imageboard"); /* diff --git a/core/user.php b/core/user.php index 05ea7466..49868789 100644 --- a/core/user.php +++ b/core/user.php @@ -105,11 +105,19 @@ class User { $user = User::by_name($name); if($user) { if($user->passhash == md5(strtolower($name) . $pass)) { + log_info("core-user", "Migrating from md5 to bcrypt for ".html_escape($name)); $user->set_password($pass); } if(password_verify($pass, $user->passhash)) { + log_info("core-user", "Logged in as ".html_escape($name)." ({$user->class->name})"); return $user; } + else { + log_warning("core-user", "Failed to log in as ".html_escape($name)." (Invalid password)"); + } + } + else { + log_warning("core-user", "Failed to log in as ".html_escape($name)." (Invalid username)"); } return null; } diff --git a/core/util.php b/core/util.php index 965b56a3..09b87dab 100644 --- a/core/util.php +++ b/core/util.php @@ -350,6 +350,18 @@ function get_debug_info(): string { return $debug; } +function log_slow() { + global $_shm_load_start; + if(!is_null(SLOW_PAGES)) { + $_time = microtime(true) - $_shm_load_start; + if($_time > SLOW_PAGES) { + $_query = _get_query(); + $_dbg = get_debug_info(); + file_put_contents("data/slow-pages.log", "$_time $_query $_dbg\n", FILE_APPEND | LOCK_EX); + } + } +} + function score_assert_handler($file, $line, $code, $desc = null) { $file = basename($file); print("Assertion failed at $file:$line: $code ($desc)"); @@ -389,7 +401,7 @@ function _sanitise_environment() { date_default_timezone_set(TIMEZONE); } - ini_set('zend.assertions', 1); // generate assertions + # ini_set('zend.assertions', 1); // generate assertions ini_set('assert.exception', 1); // throw exceptions when failed if(DEBUG) { error_reporting(E_ALL); diff --git a/ext/admin/main.php b/ext/admin/main.php index c240ea7b..04da836c 100644 --- a/ext/admin/main.php +++ b/ext/admin/main.php @@ -130,16 +130,15 @@ class AdminPage extends Extension { $reason = @$_POST['reason']; assert(strlen($query) > 1); - log_warning("admin", "Mass deleting: $query"); - $count = 0; - foreach(Image::find_images(0, 1000000, Tag::explode($query)) as $image) { + $images = Image::find_images(0, 1000000, Tag::explode($query)); + $count = count($images); + log_warning("admin", "Mass-deleting $count images from $query", true); + foreach($images as $image) { if($reason && class_exists("ImageBan")) { send_event(new AddImageHashBanEvent($image->hash, $reason)); } send_event(new ImageDeletionEvent($image)); - $count++; } - log_debug("admin", "Deleted $count images", true); $page->set_mode("redirect"); $page->set_redirect(make_link("post/list")); diff --git a/ext/autocomplete/main.php b/ext/autocomplete/main.php index af6ad166..d3ed6900 100644 --- a/ext/autocomplete/main.php +++ b/ext/autocomplete/main.php @@ -14,10 +14,24 @@ class AutoComplete extends Extension { if($event->page_matches("api/internal/autocomplete")) { if(!isset($_GET["s"])) return; + $page->set_mode("data"); + $page->set_type("application/json"); + + $s = strtolower($_GET["s"]); + if( + $s == '' || + $s[0] == '_' || + $s[0] == '%' || + strlen($s) > 32 + ) { + $page->set_data("{}"); + return; + } + //$limit = 0; - $cache_key = "autocomplete-" . strtolower($_GET["s"]); + $cache_key = "autocomplete-$s"; $limitSQL = ""; - $SQLarr = array("search"=>$_GET["s"]."%"); + $SQLarr = array("search"=>"$s%"); if(isset($_GET["limit"]) && $_GET["limit"] !== 0){ $limitSQL = "LIMIT :limit"; $SQLarr['limit'] = $_GET["limit"]; @@ -37,8 +51,6 @@ class AutoComplete extends Extension { $database->cache->set($cache_key, $res, 600); } - $page->set_mode("data"); - $page->set_type("application/json"); $page->set_data(json_encode($res)); } diff --git a/ext/handle_video/main.php b/ext/handle_video/main.php index ec3ad58f..95e4a048 100644 --- a/ext/handle_video/main.php +++ b/ext/handle_video/main.php @@ -64,7 +64,7 @@ class VideoFileHandler extends DataHandlerExtension { $orig_size = $this->video_size($inname); $scaled_size = get_thumbnail_size($orig_size[0], $orig_size[1]); - $cmd = escapeshellcmd(Tag::implode([ + $cmd = escapeshellcmd(implode(" ", [ escapeshellarg($ffmpeg), "-y", "-i", escapeshellarg($inname), "-vf", "scale={$scaled_size[0]}:{$scaled_size[1]}", @@ -76,12 +76,13 @@ class VideoFileHandler extends DataHandlerExtension { exec($cmd, $output, $ret); - if ((int)$ret == (int)1) { + if ((int)$ret == (int)0) { $ok = true; + log_error('handle_video', "Generating thumbnail with command `$cmd`, returns $ret"); + } + else { + log_debug('handle_video', "Generating thumbnail with command `$cmd`, returns $ret"); } - - // error_log("Generating thumbnail with command `$cmd`, returns $ret"); - log_debug('handle_video', "Generating thumbnail with command `$cmd`, returns $ret"); return $ok; } @@ -89,7 +90,7 @@ class VideoFileHandler extends DataHandlerExtension { protected function video_size(string $filename) { global $config; $ffmpeg = $config->get_string("thumb_ffmpeg_path"); - $cmd = escapeshellcmd(Tag::implode([ + $cmd = escapeshellcmd(implode(" ", [ escapeshellarg($ffmpeg), "-y", "-i", escapeshellarg($filename), "-vstats" @@ -100,15 +101,17 @@ class VideoFileHandler extends DataHandlerExtension { $regex_sizes = "/Video: .* ([0-9]{1,4})x([0-9]{1,4})/"; if (preg_match($regex_sizes, $output, $regs)) { if (preg_match("/displaymatrix: rotation of (90|270).00 degrees/", $output)) { - return [$regs[2], $regs[1]]; + $size = [$regs[2], $regs[1]]; } else { - return [$regs[1], $regs[2]]; + $size = [$regs[1], $regs[2]]; } } else { - return [1, 1]; + $size = [1, 1]; } + log_debug('handle_video', "Getting video size with `$cmd`, returns $output -- $size[0], $size[1]"); + return $size; } /** diff --git a/ext/ipban/main.php b/ext/ipban/main.php index 59e53d70..bb95ff98 100644 --- a/ext/ipban/main.php +++ b/ext/ipban/main.php @@ -43,7 +43,11 @@ class IPBan extends Extension { if($config->get_int("ext_ipban_version") < 8) { $this->install(); } - $config->set_default_string("ipban_message", "If you couldn't possibly be guilty of what you're banned for, the person we banned probably had a dynamic IP address and so do you. See http://whatismyipaddress.com/dynamic-static for more information.\n"); + $config->set_default_string("ipban_message", +'
IP $IP has been banned until $DATE by $ADMIN because of $REASON +
If you couldn\'t possibly be guilty of what you\'re banned for, the person we banned probably had a dynamic IP address and so do you. +
See http://whatismyipaddress.com/dynamic-static for more information. +
$CONTACT');
$this->check_ip_ban();
}
@@ -84,7 +88,7 @@ class IPBan extends Extension {
public function onSetupBuilding(SetupBuildingEvent $event) {
$sb = new SetupBlock("IP Ban");
- $sb->add_longtext_option("ipban_message", 'Message to show to banned users:');
+ $sb->add_longtext_option("ipban_message", 'Message to show to banned users:
(with $IP, $DATE, $ADMIN, $REASON, and $CONTACT)');
$event->panel->add_block($sb);
}
@@ -226,14 +230,20 @@ class IPBan extends Extension {
$admin = User::by_id($row[$prefix.'banner_id']);
$date = date("Y-m-d", $row[$prefix.'end_timestamp']);
$msg = $config->get_string("ipban_message");
- header("HTTP/1.0 403 Forbidden");
- print "IP $ip has been banned until $date by {$admin->name} because of $reason\n";
- print "
$msg"; - + $msg = str_replace('$IP', $ip, $msg); + $msg = str_replace('$DATE', $date, $msg); + $msg = str_replace('$ADMIN', $admin->name, $msg); + $msg = str_replace('$REASON', $reason, $msg); $contact_link = contact_link(); if(!empty($contact_link)) { - print "
Contact the staff (be sure to include this message)"; + $msg = str_replace('$CONTACT', "Contact the staff (be sure to include this message)", $msg); } + else { + $msg = str_replace('$CONTACT', "", $msg); + } + header("HTTP/1.0 403 Forbidden"); + print "$msg"; + exit; } } diff --git a/ext/rss_images/main.php b/ext/rss_images/main.php index 9fd6c072..13e49a79 100644 --- a/ext/rss_images/main.php +++ b/ext/rss_images/main.php @@ -91,13 +91,13 @@ class RSS_Images extends Extension { $link = make_http(make_link("post/view/{$image->id}")); $tags = html_escape($image->get_tag_list()); - $owner = $image->get_owner(); $thumb_url = $image->get_thumb_link(); $image_url = $image->get_image_link(); $posted = date(DATE_RSS, strtotime($image->posted)); $content = html_escape( + "
" . $this->theme->build_thumb_html($image) . "
" . - "Uploaded by " . html_escape($owner->name) . "
" + "For legal reasons, we need to point out that:"+ "
A) this site contains material not suitable for minors"+
"
B) cookies may be used"+
- "
Click here if you're an adult, and you're ok with that"+ + "
Common Tags | |||||
Common Source | |||||
Tags | |||||
Source | |||||
Uploaded from: "; $n = 0; @@ -190,8 +190,18 @@ class UserPageTheme extends Themelet { } } + $html .= " | Logged Events:";
+ $n = 0;
+ foreach($events as $ip => $count) {
+ $html .= ' '.$ip.' ('.$count.')'; + if(++$n >= 20) { + $html .= " ..."; + break; + } + } + $html .= " |
(Most recent at top) |