level 7 typing

This commit is contained in:
Shish 2024-01-20 20:48:47 +00:00
parent 8bd00f60c1
commit 82a3ce25c2
81 changed files with 383 additions and 277 deletions

View file

@ -308,7 +308,7 @@ class BasePage
assert($this->file, "file should not be null with PageMode::FILE");
// https://gist.github.com/codler/3906826
$size = false_throws(filesize($this->file)); // File size
$size = filesize_ex($this->file); // File size
$length = $size; // Content length
$start = 0; // Start byte
$end = $size - 1; // End byte

View file

@ -131,7 +131,7 @@ class PostgreSQL extends DBEngine
// shimmie functions for export to sqlite
function _unix_timestamp(string $date): int
{
return false_throws(strtotime($date));
return strtotime_ex($date);
}
function _now(): string
{

View file

@ -149,7 +149,7 @@ abstract class ExtensionInfo
public string $name;
public string $license;
public string $description;
/** @var array<string, string> */
/** @var array<string, string|null> */
public array $authors = [];
/** @var string[] */
public array $dependencies = [];
@ -322,7 +322,7 @@ abstract class DataHandlerExtension extends Extension
throw new UploadException("Invalid or corrupted file");
}
$existing = Image::by_hash(false_throws(md5_file($event->tmpname)));
$existing = Image::by_hash(md5_file_ex($event->tmpname));
if (!is_null($existing)) {
if ($config->get_string(ImageConfig::UPLOAD_COLLISION_HANDLER) == ImageConfig::COLLISION_MERGE) {
// Right now tags are the only thing that get merged, so
@ -343,8 +343,8 @@ abstract class DataHandlerExtension extends Extension
assert(is_readable($filename));
$image = new Image();
$image->tmp_file = $filename;
$image->filesize = false_throws(filesize($filename));
$image->hash = false_throws(md5_file($filename));
$image->filesize = filesize_ex($filename);
$image->hash = md5_file_ex($filename);
$image->filename = (($pos = strpos($event->metadata['filename'], '?')) !== false) ? substr($event->metadata['filename'], 0, $pos) : $event->metadata['filename'];
$image->set_mime(MimeType::get_for_file($filename, get_file_ext($event->metadata["filename"]) ?? null));
if (empty($image->get_mime())) {

View file

@ -79,7 +79,7 @@ function full_copy(string $source, string $target): void
if (is_dir($source)) {
@mkdir($target);
$d = false_throws(dir($source));
$d = dir_ex($source);
while (true) {
$entry = $d->read();
@ -627,24 +627,11 @@ function parse_to_milliseconds(string $input): int
*/
function autodate(string $date, bool $html = true): string
{
$cpu = date('c', false_throws(strtotime($date)));
$hum = date('F j, Y; H:i', false_throws(strtotime($date)));
$cpu = date('c', strtotime_ex($date));
$hum = date('F j, Y; H:i', strtotime_ex($date));
return ($html ? "<time datetime='$cpu'>$hum</time>" : $hum);
}
/**
* @template T
* @param T|false $x
* @return T
*/
function false_throws(mixed $x): mixed
{
if($x === false) {
throw new \Exception("Unexpected false");
}
return $x;
}
/**
* Check if a given string is a valid date-time. ( Format: yyyy-mm-dd hh:mm:ss )
*/
@ -738,7 +725,7 @@ function validate_input(array $inputs): array
} elseif (in_array('bool', $flags)) {
$outputs[$key] = bool_escape($value);
} elseif (in_array('date', $flags)) {
$outputs[$key] = date("Y-m-d H:i:s", false_throws(strtotime(trim($value))));
$outputs[$key] = date("Y-m-d H:i:s", strtotime_ex(trim($value)));
} elseif (in_array('string', $flags)) {
if (in_array('trim', $flags)) {
$value = trim($value);

88
core/stdlib_ex.php Normal file
View file

@ -0,0 +1,88 @@
<?php
/**
* @template T
* @param T|false $x
* @return T
*/
function false_throws(mixed $x): mixed
{
if($x === false) {
throw new \Exception("Unexpected false");
}
return $x;
}
/**
* @template T
* @param T|null $x
* @return T
*/
function null_throws(mixed $x): mixed
{
if($x === null) {
throw new \Exception("Unexpected null");
}
return $x;
}
/**
* @param int<1,max> $depth
*/
function json_encode_ex(mixed $value, int|null $flags = 0, int $depth = 512): string
{
return false_throws(json_encode($value, $flags, $depth));
}
function strtotime_ex(string $time, int|null $now = null): int
{
return false_throws(strtotime($time, $now));
}
function md5_file_ex(string $filename, bool|null $raw_output = false): string
{
return false_throws(md5_file($filename, $raw_output));
}
/**
* @return string[]
*/
function glob_ex(string $pattern, int|null $flags = 0): array
{
return false_throws(glob($pattern, $flags));
}
function file_get_contents_ex(string $filename): string
{
return false_throws(file_get_contents($filename));
}
function filesize_ex(string $filename): int
{
return false_throws(filesize($filename));
}
function inet_ntop_ex(string $in_addr): string
{
return false_throws(inet_ntop($in_addr));
}
function inet_pton_ex(string $ip_address): string
{
return false_throws(inet_pton($ip_address));
}
function dir_ex(string $directory): \Directory
{
return false_throws(dir($directory));
}
function exec_ex(string $command): string
{
return false_throws(exec($command));
}
function filter_var_ex(mixed $variable, int $filter = FILTER_DEFAULT, mixed $options = null): mixed
{
return false_throws(filter_var($variable, $filter, $options));
}

View file

@ -169,7 +169,7 @@ function get_real_ip(): string
if(is_trusted_proxy()) {
if (isset($_SERVER['HTTP_X_REAL_IP'])) {
if(filter_var($ip, FILTER_VALIDATE_IP)) {
if(filter_var_ex($ip, FILTER_VALIDATE_IP)) {
$ip = $_SERVER['HTTP_X_REAL_IP'];
}
}
@ -177,7 +177,7 @@ function get_real_ip(): string
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
$last_ip = $ips[count($ips) - 1];
if(filter_var($last_ip, FILTER_VALIDATE_IP)) {
if(filter_var_ex($last_ip, FILTER_VALIDATE_IP)) {
$ip = $last_ip;
}
}
@ -194,7 +194,7 @@ function get_session_ip(Config $config): string
{
$mask = $config->get_string("session_hash_mask", "255.255.0.0");
$addr = get_real_ip();
$addr = false_throws(inet_ntop(false_throws(inet_pton($addr)) & false_throws(inet_pton($mask))));
$addr = inet_ntop_ex(inet_pton_ex($addr) & inet_pton_ex($mask));
return $addr;
}
@ -796,3 +796,12 @@ function generate_key(int $length = 20): string
return $randomString;
}
function shm_tempnam(string $prefix = ""): string
{
if(!is_dir("data/temp")) {
mkdir("data/temp");
}
$temp = false_throws(realpath("data/temp"));
return false_throws(tempnam($temp, $prefix));
}

View file

@ -105,7 +105,7 @@ class AliasEditor extends Extension
if ($user->can(Permissions::MANAGE_ALIAS_LIST)) {
if (count($_FILES) > 0) {
$tmp = $_FILES['alias_file']['tmp_name'];
$contents = false_throws(file_get_contents($tmp));
$contents = file_get_contents_ex($tmp);
$this->add_alias_csv($contents);
log_info("alias_editor", "Imported aliases from file", "Imported aliases"); # FIXME: how many?
$page->set_mode(PageMode::REDIRECT);

View file

@ -19,6 +19,12 @@ class AuthorSetEvent extends Event
}
}
/**
* @phpstan-type ArtistArtist array{id:int,artist_id:int,user_name:string,name:string,notes:string,type:string,posts:int}
* @phpstan-type ArtistAlias array{id:int,alias_id:int,alias_name:string,alias:string}
* @phpstan-type ArtistMember array{id:int,name:string}
* @phpstan-type ArtistUrl array{id:int,url:string}
*/
class Artists extends Extension
{
/** @var ArtistsTheme */
@ -514,7 +520,7 @@ class Artists extends Extension
}
/**
* @return array<string, mixed>
* @return ArtistAlias
*/
private function get_alias_by_id(int $aliasID): array
{
@ -523,7 +529,7 @@ class Artists extends Extension
}
/**
* @return array<string, mixed>
* @return ArtistUrl
*/
private function get_url_by_id(int $urlID): array
{
@ -532,7 +538,7 @@ class Artists extends Extension
}
/**
* @return array<string, mixed>
* @return ArtistMember
*/
private function get_member_by_id(int $memberID): array
{
@ -617,6 +623,7 @@ class Artists extends Extension
// URLS MATCHING SECTION
$i = 0;
assert(is_string($urlsAsString));
$urlsAsString = str_replace("\r\n", "\n", $urlsAsString);
$urlsAsString = str_replace("\n\r", "\n", $urlsAsString);
$urlsAsArray = empty($urlsAsString) ? [] : explode("\n", $urlsAsString);
@ -747,6 +754,7 @@ class Artists extends Extension
}
if (!is_null($urls)) {
assert(is_string($urls));
//delete double "separators"
$urls = str_replace("\r\n", "\n", $urls);
$urls = str_replace("\n\r", "\n", $urls);
@ -782,7 +790,7 @@ class Artists extends Extension
}
/**
* @return array<string, mixed>
* @return ArtistArtist
*/
private function get_artist(int $artistID): array
{
@ -799,7 +807,7 @@ class Artists extends Extension
}
/**
* @return array<string, mixed>
* @return ArtistMember[]
*/
private function get_members(int $artistID): array
{
@ -818,7 +826,7 @@ class Artists extends Extension
}
/**
* @return array<string, mixed>
* @return ArtistUrl[]
*/
private function get_urls(int $artistID): array
{

View file

@ -111,7 +111,7 @@ class AutoTagger extends Extension
if ($user->can(Permissions::MANAGE_AUTO_TAG)) {
if (count($_FILES) > 0) {
$tmp = $_FILES['auto_tag_file']['tmp_name'];
$contents = false_throws(file_get_contents($tmp));
$contents = file_get_contents_ex($tmp);
$count = $this->add_auto_tag_csv($contents);
log_info(AutoTaggerInfo::KEY, "Imported $count auto-tag definitions from file from file", "Imported $count auto-tag definitions");
$page->set_mode(PageMode::REDIRECT);

View file

@ -23,7 +23,7 @@ class AutoComplete extends Extension
$page->set_mode(PageMode::DATA);
$page->set_mime(MimeType::JSON);
$page->set_data(json_encode($res));
$page->set_data(json_encode_ex($res));
}
}

View file

@ -141,7 +141,7 @@ class BlotterTheme extends Themelet
$i_close = "";
//$id = $entries[$i]['id'];
$messy_date = $entries[$i]['entry_date'];
$clean_date = date("y/m/d", strtotime($messy_date));
$clean_date = date("y/m/d", strtotime_ex($messy_date));
$entry_text = $entries[$i]['entry_text'];
if ($entries[$i]['important'] == 'Y') {
$i_open = "<span style='color: #$i_color;'>";
@ -171,7 +171,7 @@ class BlotterTheme extends Themelet
$i_close = "";
//$id = $entry['id'];
$messy_date = $entry['entry_date'];
$clean_date = date("m/d/y", strtotime($messy_date));
$clean_date = date("m/d/y", strtotime_ex($messy_date));
$entry_text = $entry['entry_text'];
if ($entry['important'] == 'Y') {
$i_open = "<span style='color: #$i_color'>";
@ -192,7 +192,7 @@ class BlotterTheme extends Themelet
$out_text = "No blotter entries yet.";
$in_text = "Empty.";
} else {
$clean_date = date("m/d/y", strtotime($entries[0]['entry_date']));
$clean_date = date("m/d/y", strtotime_ex($entries[0]['entry_date']));
$out_text = "Blotter updated: {$clean_date}";
$in_text = "<ul>$entries_list</ul>";
}

View file

@ -28,7 +28,7 @@ class BrowserSearch extends Extension
$search_title = $config->get_string(SetupConfig::TITLE);
$search_form_url = search_link(['{searchTerms}']);
$suggenton_url = make_link('browser_search/')."{searchTerms}";
$icon_b64 = base64_encode(false_throws(file_get_contents("ext/static_files/static/favicon.ico")));
$icon_b64 = base64_encode(file_get_contents_ex("ext/static_files/static/favicon.ico"));
// Now for the XML
$xml = "
@ -71,7 +71,7 @@ class BrowserSearch extends Extension
// And to do stuff with it. We want our output to look like:
// ["shimmie",["shimmies","shimmy","shimmie","21 shimmies","hip shimmies","skea shimmies"],[],[]]
$page->set_mode(PageMode::DATA);
$page->set_data(json_encode([$tag_search, $tags, [], []]));
$page->set_data(json_encode_ex([$tag_search, $tags, [], []]));
}
}

View file

@ -87,7 +87,7 @@ class BulkAddCSV extends Extension
$linenum = 1;
$list = "";
$csvhandle = fopen($csvfile, "r");
$csvhandle = false_throws(fopen($csvfile, "r"));
while (($csvdata = fgetcsv($csvhandle, 0, ",")) !== false) {
if (count($csvdata) != 5) {

View file

@ -48,7 +48,7 @@ class BulkDownload extends Extension
if ($user->can(Permissions::BULK_DOWNLOAD) &&
($event->action == BulkDownload::DOWNLOAD_ACTION_NAME)) {
$download_filename = $user->name . '-' . date('YmdHis') . '.zip';
$zip_filename = false_throws(tempnam(sys_get_temp_dir(), "shimmie_bulk_download"));
$zip_filename = shm_tempnam("bulk_download");
$zip = new \ZipArchive();
$size_total = 0;
$max_size = $config->get_int(BulkDownloadConfig::SIZE_LIMIT);

View file

@ -40,7 +40,7 @@ class BulkImportExport extends DataHandlerExtension
continue;
}
$tmpfile = tempnam(sys_get_temp_dir(), "shimmie_bulk_import");
$tmpfile = shm_tempnam("bulk_import");
$stream = $zip->getStream($item->hash);
if ($stream === false) {
throw new SCoreException("Could not import " . $item->hash . ": File not in zip");
@ -105,7 +105,7 @@ class BulkImportExport extends DataHandlerExtension
if ($user->can(Permissions::BULK_EXPORT) &&
($event->action == self::EXPORT_ACTION_NAME)) {
$download_filename = $user->name . '-' . date('YmdHis') . '.zip';
$zip_filename = tempnam(sys_get_temp_dir(), "shimmie_bulk_export");
$zip_filename = shm_tempnam("bulk_export");
$zip = new \ZipArchive();
$json_data = [];
@ -126,7 +126,7 @@ class BulkImportExport extends DataHandlerExtension
$zip->addFile($img_loc, $image->hash);
}
$json_data = json_encode($json_data, JSON_PRETTY_PRINT);
$json_data = json_encode_ex($json_data, JSON_PRETTY_PRINT);
$zip->addFromString(self::EXPORT_INFO_FILE_NAME, $json_data);
$zip->close();
@ -163,7 +163,7 @@ class BulkImportExport extends DataHandlerExtension
$info = $zip->getStream(self::EXPORT_INFO_FILE_NAME);
if ($info !== false) {
try {
$json_string = stream_get_contents($info);
$json_string = false_throws(stream_get_contents($info));
$json_data = json_decode($json_string);
return $json_data;
} finally {

View file

@ -311,7 +311,7 @@ class CommentList extends Extension
LIMIT :limit OFFSET :offset
", ["limit" => $threads_per_page, "offset" => $start]);
$user_ratings = Extension::is_enabled(RatingsInfo::KEY) ? Ratings::get_user_class_privs($user) : "";
$user_ratings = Extension::is_enabled(RatingsInfo::KEY) ? Ratings::get_user_class_privs($user) : [];
$images = [];
while ($row = $result->fetch()) {
@ -369,7 +369,7 @@ class CommentList extends Extension
public function onUserPageBuilding(UserPageBuildingEvent $event): void
{
$i_days_old = ((time() - strtotime($event->display_user->join_date)) / 86400) + 1;
$i_days_old = ((time() - strtotime_ex($event->display_user->join_date)) / 86400) + 1;
$i_comment_count = Comment::count_comments_by_user($event->display_user);
$h_comment_rate = sprintf("%.1f", ($i_comment_count / $i_days_old));
$event->add_stats("Comments made: $i_comment_count, $h_comment_rate per day");
@ -651,7 +651,7 @@ class CommentList extends Extension
}
// advanced sanity checks
elseif (strlen($comment) / strlen(gzcompress($comment)) > 10) {
elseif (strlen($comment) / strlen(false_throws(gzcompress($comment))) > 10) {
throw new CommentPostingException("Comment too repetitive~");
} elseif ($user->is_anonymous() && !$this->hash_match()) {
$page->add_cookie("nocache", "Anonymous Commenter", time() + 60 * 60 * 24, "/");

View file

@ -59,7 +59,7 @@ class CommentListTheme extends Themelet
$comment_count = count($comments);
if ($comment_limit > 0 && $comment_count > $comment_limit) {
$comment_html .= "<p>showing $comment_limit of $comment_count comments</p>";
$comments = array_slice($comments, -$comment_limit);
$comments = array_slice($comments, negative_int($comment_limit));
$this->show_anon_id = false;
} else {
$this->show_anon_id = true;
@ -255,7 +255,7 @@ class CommentListTheme extends Themelet
$h_del = "";
if ($user->can(Permissions::DELETE_COMMENT)) {
$comment_preview = substr(html_unescape($tfe->stripped), 0, 50);
$j_delete_confirm_message = json_encode("Delete comment by {$comment->owner_name}:\n$comment_preview");
$j_delete_confirm_message = json_encode_ex("Delete comment by {$comment->owner_name}:\n$comment_preview");
$h_delete_script = html_escape("return confirm($j_delete_confirm_message);");
$h_delete_link = make_link("comment/delete/$i_comment_id/$i_image_id");
$h_del = " - <a onclick='$h_delete_script' href='$h_delete_link'>Del</a>";

View file

@ -235,7 +235,7 @@ class CronUploader extends Extension
$running = false;
$lockfile = fopen($this->get_lock_file(), "w");
$lockfile = false_throws(fopen($this->get_lock_file(), "w"));
try {
if (!flock($lockfile, LOCK_EX | LOCK_NB)) {
$running = true;
@ -343,7 +343,7 @@ class CronUploader extends Extension
throw new SCoreException("User does not have permission to run cron upload");
}
$lockfile = fopen($this->get_lock_file(), "w");
$lockfile = false_throws(fopen($this->get_lock_file(), "w"));
if (!flock($lockfile, LOCK_EX | LOCK_NB)) {
throw new SCoreException("Cron upload process is already running");
}

View file

@ -311,7 +311,7 @@ class DanbooruApi extends Extension
}
} elseif (isset($_REQUEST['source']) || isset($_REQUEST['post']['source'])) { // A url was provided
$source = isset($_REQUEST['source']) ? $_REQUEST['source'] : $_REQUEST['post']['source'];
$file = tempnam(sys_get_temp_dir(), "shimmie_transload");
$file = shm_tempnam("transload");
assert($file !== false);
try {
fetch_url($source, $file);

View file

@ -15,7 +15,7 @@ class EmoticonList extends Extension
public function onPageRequest(PageRequestEvent $event): void
{
if ($event->page_matches("emote/list")) {
$this->theme->display_emotes(glob("ext/emoticons/default/*"));
$this->theme->display_emotes(glob_ex("ext/emoticons/default/*"));
}
}
}

View file

@ -18,7 +18,7 @@ class Eokm extends Extension
$password = $config->get_string("eokm_password");
if ($username && $password) {
$ch = curl_init("https://api.eokmhashdb.nl/v1/check/md5");
$ch = false_throws(curl_init("https://api.eokmhashdb.nl/v1/check/md5"));
// curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/xml', $additionalHeaders));
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);

View file

@ -120,9 +120,9 @@ class ET extends Extension
if (file_exists(".git")) {
try {
$commitHash = trim(exec('git log --pretty="%h" -n1 HEAD'));
$commitBranch = trim(exec('git rev-parse --abbrev-ref HEAD'));
$commitOrigin = trim(exec('git config --get remote.origin.url'));
$commitHash = trim(exec_ex('git log --pretty="%h" -n1 HEAD'));
$commitBranch = trim(exec_ex('git rev-parse --abbrev-ref HEAD'));
$commitOrigin = trim(exec_ex('git config --get remote.origin.url'));
$commitOrigin = preg_replace("#//.*@#", "//xxx@", $commitOrigin);
$info['git'] = [
'commit' => $commitHash,
@ -146,7 +146,7 @@ class ET extends Extension
foreach ($info as $title => $section) {
$data .= "$title:\n";
foreach ($section as $k => $v) {
$data .= " $k: " . json_encode($v, JSON_UNESCAPED_SLASHES) . "\n";
$data .= " $k: " . json_encode_ex($v, JSON_UNESCAPED_SLASHES) . "\n";
}
$data .= "\n";
}

View file

@ -78,7 +78,7 @@ class Favorites extends Extension
public function onUserPageBuilding(UserPageBuildingEvent $event): void
{
$i_favorites_count = Search::count_images(["favorited_by={$event->display_user->name}"]);
$i_days_old = ((time() - strtotime($event->display_user->join_date)) / 86400) + 1;
$i_days_old = ((time() - strtotime_ex($event->display_user->join_date)) / 86400) + 1;
$h_favorites_rate = sprintf("%.1f", ($i_favorites_count / $i_days_old));
$favorites_link = search_link(["favorited_by={$event->display_user->name}"]);
$event->add_stats("<a href='$favorites_link'>Posts favorited</a>: $i_favorites_count, $h_favorites_rate per day");

View file

@ -35,7 +35,7 @@ class Featured extends Extension
if (!is_null($image)) {
$page->set_mode(PageMode::DATA);
$page->set_mime($image->get_mime());
$page->set_data(file_get_contents($image->get_image_filename()));
$page->set_data(file_get_contents_ex($image->get_image_filename()));
}
}
if ($event->get_arg(0) == "view") {

View file

@ -82,7 +82,7 @@ class Forum extends Extension
$threads_count = $database->get_one("SELECT COUNT(*) FROM forum_threads WHERE user_id=:user_id", ['user_id' => $event->display_user->id]);
$posts_count = $database->get_one("SELECT COUNT(*) FROM forum_posts WHERE user_id=:user_id", ['user_id' => $event->display_user->id]);
$days_old = ((time() - strtotime($event->display_user->join_date)) / 86400) + 1;
$days_old = ((time() - strtotime_ex($event->display_user->join_date)) / 86400) + 1;
$threads_rate = sprintf("%.1f", ($threads_count / $days_old));
$posts_rate = sprintf("%.1f", ($posts_count / $days_old));

View file

@ -92,6 +92,8 @@ class GraphQL extends Extension
]);
$t2 = ftime();
$resp = $server->executeRequest();
assert(!is_array($resp));
assert(is_a($resp, \GraphQL\Executor\ExecutionResult::class));
if ($config->get_bool("graphql_debug")) {
$debug = DebugFlag::INCLUDE_DEBUG_MESSAGE | DebugFlag::RETHROW_INTERNAL_EXCEPTIONS;
$body = $resp->toArray($debug);
@ -105,13 +107,13 @@ class GraphQL extends Extension
// sleep(1);
$page->set_mode(PageMode::DATA);
$page->set_mime("application/json");
$page->set_data(\json_encode($body, JSON_UNESCAPED_UNICODE));
$page->set_data(json_encode_ex($body, JSON_UNESCAPED_UNICODE));
}
if ($event->page_matches("graphql_upload")) {
$this->cors();
$page->set_mode(PageMode::DATA);
$page->set_mime("application/json");
$page->set_data(\json_encode(self::handle_uploads()));
$page->set_data(json_encode_ex(self::handle_uploads()));
}
}
@ -200,7 +202,7 @@ class GraphQL extends Extension
$body['stats'] = get_debug_info_arr();
$body['stats']['graphql_schema_time'] = round($t2 - $t1, 2);
$body['stats']['graphql_execute_time'] = round($t3 - $t2, 2);
echo \json_encode($body, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
echo json_encode_ex($body, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
return Command::SUCCESS;
});
$event->app->register('graphql:schema')

View file

@ -31,6 +31,7 @@ class ArchiveFileHandler extends DataHandlerExtension
$cmd = $config->get_string('archive_extract_command');
$cmd = str_replace('%f', $event->tmpname, $cmd);
$cmd = str_replace('%d', $tmpdir, $cmd);
assert(is_string($cmd));
exec($cmd);
if (file_exists($tmpdir)) {
try {

View file

@ -39,7 +39,7 @@ class CBZFileHandler extends DataHandlerExtension
protected function check_contents(string $tmpname): bool
{
$fp = fopen($tmpname, "r");
$fp = false_throws(fopen($tmpname, "r"));
$head = fread($fp, 4);
fclose($fp);
return $head == "PK\x03\x04";
@ -53,7 +53,7 @@ class CBZFileHandler extends DataHandlerExtension
$za->open($archive);
$names = [];
for ($i = 0; $i < $za->numFiles;$i++) {
$file = $za->statIndex($i);
$file = false_throws($za->statIndex($i));
$names[] = $file['name'];
}
sort($names);

View file

@ -15,10 +15,10 @@ class IcoFileHandler extends DataHandlerExtension
$event->image->audio = false;
$event->image->image = ($event->image->get_mime() != MimeType::ANI);
$fp = fopen($event->image->get_image_filename(), "r");
$fp = false_throws(fopen($event->image->get_image_filename(), "r"));
try {
fseek($fp, 6); // skip header
$subheader = unpack("Cwidth/Cheight/Ccolours/Cnull/Splanes/Sbpp/Lsize/loffset", fread($fp, 16));
$subheader = false_throws(unpack("Cwidth/Cheight/Ccolours/Cnull/Splanes/Sbpp/Lsize/loffset", false_throws(fread($fp, 16))));
$width = $subheader['width'];
$height = $subheader['height'];
$event->image->width = $width == 0 ? 256 : $width;
@ -41,8 +41,8 @@ class IcoFileHandler extends DataHandlerExtension
protected function check_contents(string $tmpname): bool
{
$fp = fopen($tmpname, "r");
$header = unpack("Snull/Stype/Scount", fread($fp, 6));
$fp = false_throws(fopen($tmpname, "r"));
$header = false_throws(unpack("Snull/Stype/Scount", false_throws(fread($fp, 6))));
fclose($fp);
return ($header['null'] == 0 && ($header['type'] == 0 || $header['type'] == 1));
}

View file

@ -26,7 +26,7 @@ class SVGFileHandler extends DataHandlerExtension
$sanitizer = new Sanitizer();
$sanitizer->removeRemoteReferences(true);
$dirtySVG = file_get_contents(warehouse_path(Image::IMAGE_DIR, $hash));
$dirtySVG = file_get_contents_ex(warehouse_path(Image::IMAGE_DIR, $hash));
$cleanSVG = $sanitizer->sanitize($dirtySVG);
$page->set_data($cleanSVG);
}
@ -41,10 +41,10 @@ class SVGFileHandler extends DataHandlerExtension
// then sanitise it before touching it
$sanitizer = new Sanitizer();
$sanitizer->removeRemoteReferences(true);
$dirtySVG = file_get_contents($event->tmpname);
$cleanSVG = $sanitizer->sanitize($dirtySVG);
$dirtySVG = file_get_contents_ex($event->tmpname);
$cleanSVG = false_throws($sanitizer->sanitize($dirtySVG));
$event->hash = md5($cleanSVG);
$new_tmpname = tempnam(sys_get_temp_dir(), "shimmie_svg");
$new_tmpname = shm_tempnam("svg");
file_put_contents($new_tmpname, $cleanSVG);
$event->set_tmpname($new_tmpname);
@ -103,7 +103,7 @@ class MiniSVGParser
{
$xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, [$this, "startElement"], [$this, "endElement"]);
$this->valid = bool_escape(xml_parse($xml_parser, file_get_contents($file), true));
$this->valid = bool_escape(xml_parse($xml_parser, file_get_contents_ex($file), true));
xml_parser_free($xml_parser);
}

View file

@ -18,7 +18,7 @@ class HelpPageListBuildingEvent extends Event
class HelpPageBuildingEvent extends Event
{
public string $key;
/** @var array<string,array<Block>> */
/** @var array<int,Block> */
public array $blocks = [];
public function __construct(string $key)
@ -29,10 +29,10 @@ class HelpPageBuildingEvent extends Event
public function add_block(Block $block, int $position = 50): void
{
if (!array_key_exists("$position", $this->blocks)) {
$this->blocks["$position"] = [];
while (array_key_exists($position, $this->blocks)) {
$position++;
}
$this->blocks["$position"][] = $block;
$this->blocks[$position] = $block;
}
}
@ -65,16 +65,13 @@ class HelpPages extends Extension
$this->theme->display_help_page($title);
$hpbe = send_event(new HelpPageBuildingEvent($name));
asort($hpbe->blocks);
foreach ($hpbe->blocks as $key => $value) {
foreach ($value as $block) {
ksort($hpbe->blocks);
foreach ($hpbe->blocks as $block) {
$page->add_block($block);
}
}
}
}
}
public function onHelpPageListBuilding(HelpPageListBuildingEvent $event): void
{

View file

@ -28,7 +28,7 @@ class Home extends Extension
$counters = [];
$counters["None"] = "none";
$counters["Text-only"] = "text-only";
foreach (false_throws(glob("ext/home/counters/*")) as $counter_dirname) {
foreach (glob_ex("ext/home/counters/*") as $counter_dirname) {
$name = str_replace("ext/home/counters/", "", $counter_dirname);
$counters[ucfirst($name)] = $name;
}

View file

@ -150,7 +150,7 @@ class ImageIO extends Extension
{
$u_name = url_escape($event->display_user->name);
$i_image_count = Search::count_images(["user={$event->display_user->name}"]);
$i_days_old = ((time() - strtotime($event->display_user->join_date)) / 86400) + 1;
$i_days_old = ((time() - strtotime_ex($event->display_user->join_date)) / 86400) + 1;
$h_image_rate = sprintf("%.1f", ($i_image_count / $i_days_old));
$images_link = search_link(["user=$u_name"]);
$event->add_stats("<a href='$images_link'>Posts uploaded</a>: $i_image_count, $h_image_rate per day");
@ -202,7 +202,7 @@ class ImageIO extends Extension
public function onParseLinkTemplate(ParseLinkTemplateEvent $event): void
{
$fname = $event->image->get_filename();
$base_fname = str_contains($fname, '.') ? substr($fname, 0, strrpos($fname, '.')) : $fname;
$base_fname = basename($fname, '.' . $event->image->get_ext());
$event->replace('$id', (string)$event->image->id);
$event->replace('$hash_ab', substr($event->image->hash, 0, 2));
@ -241,7 +241,7 @@ class ImageIO extends Extension
} else {
$if_modified_since = "";
}
$gmdate_mod = gmdate('D, d M Y H:i:s', filemtime($file)) . ' GMT';
$gmdate_mod = gmdate('D, d M Y H:i:s', false_throws(filemtime($file))) . ' GMT';
if ($if_modified_since == $gmdate_mod) {
$page->set_mode(PageMode::DATA);

View file

@ -142,7 +142,7 @@ class IPBan extends Extension
$row_banner_id_int = intval($row['banner_id']);
$msg = $config->get_string("ipban_message_{$row['mode']}") ?? $config->get_string("ipban_message");
$msg = $config->get_string("ipban_message_{$row['mode']}") ?? $config->get_string("ipban_message") ?? "(no message)";
$msg = str_replace('$IP', $row["ip"], $msg);
$msg = str_replace('$DATE', $row['expires'] ?? 'the end of time', $msg);
$msg = str_replace('$ADMIN', User::by_id($row_banner_id_int)->name, $msg);
@ -153,6 +153,7 @@ class IPBan extends Extension
} else {
$msg = str_replace('$CONTACT', "", $msg);
}
assert(is_string($msg));
$msg .= "<!-- $active_ban_id / {$row["mode"]} -->";
if ($row["mode"] == "ghost") {

View file

@ -28,7 +28,7 @@ class LinkImage extends Extension
}
/**
* @return array{thumb_src: string, image_src: string, post_link: string, text_link: string}
* @return array{thumb_src: string, image_src: string, post_link: string, text_link: string|null}
*/
private function data(Image $image): array
{

View file

@ -7,7 +7,7 @@ namespace Shimmie2;
class LinkImageTheme extends Themelet
{
/**
* @param array{thumb_src:string,image_src:string,post_link:string,text_link:string} $data
* @param array{thumb_src:string,image_src:string,post_link:string,text_link:string|null} $data
*/
public function links_block(Page $page, array $data): void
{

View file

@ -79,10 +79,11 @@ class ActorColumn extends Column
}
/**
* @return array{0: string, 1: string}
* @return array{0: string|null, 1: string|null}
*/
public function modify_input_for_read(string|array $input): array
{
assert(is_array($input));
list($un, $ip) = $input;
if (empty($un)) {
$un = null;
@ -160,6 +161,7 @@ class MessageColumn extends Column
public function modify_input_for_read(array|string $input): mixed
{
assert(is_array($input));
list($m, $l) = $input;
if (empty($m)) {
$m = "%";

View file

@ -59,7 +59,7 @@ class LogLogstash extends Extension
if (!$fp) {
return;
}
fwrite($fp, json_encode($data));
fwrite($fp, json_encode_ex($data));
fclose($fp);
} catch (\Exception $e) {
// we can't log that logging is broken

View file

@ -332,7 +332,7 @@ class Media extends Extension
$ok = false;
$inname = $image->get_image_filename();
$tmpname = tempnam(sys_get_temp_dir(), "shimmie_ffmpeg_thumb");
$tmpname = shm_tempnam("ffmpeg_thumb");
try {
$outname = $image->get_thumb_filename();
@ -702,16 +702,17 @@ class Media extends Extension
$new_width = $width;
}
$image = imagecreatefromstring(file_get_contents($image_filename));
$image_resized = imagecreatetruecolor($new_width, $new_height);
try {
$image = imagecreatefromstring(file_get_contents_ex($image_filename));
if ($image === false) {
throw new MediaException("Could not load image: " . $image_filename);
}
$image_resized = imagecreatetruecolor($new_width, $new_height);
if ($image_resized === false) {
throw new MediaException("Could not create output image with dimensions $new_width c $new_height ");
throw new MediaException("Could not create output image with dimensions $new_width x $new_height ");
}
try {
// Handle transparent images
switch ($info[2]) {
case IMAGETYPE_GIF:
@ -849,7 +850,7 @@ class Media extends Extension
"-y", "-i", escapeshellarg($filename),
"-vstats"
]));
$output = shell_exec($cmd . " 2>&1");
$output = null_throws(false_throws(shell_exec($cmd . " 2>&1")));
// error_log("Getting size with `$cmd`");
$regex_sizes = "/Video: .* ([0-9]{1,4})x([0-9]{1,4})/";
@ -941,9 +942,9 @@ class Media extends Extension
public static function hex_color_allocate(mixed $im, string $hex): int
{
$hex = ltrim($hex, '#');
$a = hexdec(substr($hex, 0, 2));
$b = hexdec(substr($hex, 2, 2));
$c = hexdec(substr($hex, 4, 2));
$a = (int)hexdec(substr($hex, 0, 2));
$b = (int)hexdec(substr($hex, 2, 2));
$c = (int)hexdec(substr($hex, 4, 2));
$col = imagecolorallocate($im, $a, $b, $c);
assert($col !== false);
return $col;

View file

@ -159,7 +159,7 @@ class MimeType
*/
private static function compare_file_bytes(string $file_name, array $comparison): bool
{
$size = filesize($file_name);
$size = filesize_ex($file_name);
$cc = count($comparison);
if ($size < $cc) {
// Can't match because it's too small
@ -168,7 +168,7 @@ class MimeType
if (($fh = @fopen($file_name, 'rb'))) {
try {
$chunk = unpack("C*", fread($fh, $cc));
$chunk = false_throws(unpack("C*", false_throws(fread($fh, $cc))));
for ($i = 0; $i < $cc; $i++) {
$byte = $comparison[$i];
@ -231,12 +231,9 @@ class MimeType
$output = self::OCTET_STREAM;
$finfo = finfo_open(FILEINFO_MIME_TYPE);
try {
$finfo = false_throws(finfo_open(FILEINFO_MIME_TYPE));
$type = finfo_file($finfo, $file);
} finally {
finfo_close($finfo);
}
if ($type !== false && !empty($type)) {
$output = $type;

View file

@ -126,7 +126,7 @@ class Notes extends Extension
$page->set_mode(PageMode::DATA);
if (!$user->is_anonymous()) {
$note_id = $this->add_new_note();
$page->set_data(json_encode([
$page->set_data(json_encode_ex([
'status' => 'success',
'note_id' => $note_id,
]));
@ -136,14 +136,14 @@ class Notes extends Extension
$page->set_mode(PageMode::DATA);
if (!$user->is_anonymous()) {
$this->update_note();
$page->set_data(json_encode(['status' => 'success']));
$page->set_data(json_encode_ex(['status' => 'success']));
}
break;
case "delete_note":
$page->set_mode(PageMode::DATA);
if ($user->can(Permissions::NOTES_ADMIN)) {
$this->delete_note();
$page->set_data(json_encode(['status' => 'success']));
$page->set_data(json_encode_ex(['status' => 'success']));
}
break;
case "nuke_notes":
@ -256,7 +256,7 @@ class Notes extends Extension
{
global $database, $user;
$note = json_decode(file_get_contents('php://input'), true);
$note = json_decode(file_get_contents_ex('php://input'), true);
$database->execute(
"
@ -318,7 +318,7 @@ class Notes extends Extension
{
global $database;
$note = json_decode(file_get_contents('php://input'), true);
$note = json_decode(file_get_contents_ex('php://input'), true);
// validate parameters
if (empty($note['note'])) {
@ -337,7 +337,7 @@ class Notes extends Extension
{
global $user, $database;
$note = json_decode(file_get_contents('php://input'), true);
$note = json_decode(file_get_contents_ex('php://input'), true);
$database->execute("
UPDATE notes SET enable = :enable
WHERE image_id = :image_id AND id = :id
@ -369,11 +369,11 @@ class Notes extends Extension
global $database, $config;
$pageNumber = $event->try_page_num(1);
$notesPerPage = $config->get_int('notesNotesPerPage');
$totalPages = (int)ceil($database->get_one("SELECT COUNT(DISTINCT image_id) FROM notes") / $notesPerPage);
//$result = $database->get_all("SELECT * FROM pool_images WHERE pool_id=:pool_id", ['pool_id'=>$poolID]);
$result = $database->execute(
$image_ids = $database->get_col(
"
SELECT DISTINCT image_id
FROM notes
@ -382,11 +382,9 @@ class Notes extends Extension
['enable' => 1, 'offset' => $pageNumber * $notesPerPage, 'limit' => $notesPerPage]
);
$totalPages = (int)ceil($database->get_one("SELECT COUNT(DISTINCT image_id) FROM notes") / $notesPerPage);
$images = [];
while ($row = $result->fetch()) {
$images[] = [Image::by_id($row["image_id"])];
foreach($image_ids as $id) {
$images[] = Image::by_id($id);
}
$this->theme->display_note_list($images, $pageNumber + 1, $totalPages);
@ -414,7 +412,7 @@ class Notes extends Extension
$images = [];
while ($row = $result->fetch()) {
$images[] = [Image::by_id($row["image_id"])];
$images[] = Image::by_id($row["image_id"]);
}
$this->theme->display_note_requests($images, $pageNumber + 1, $totalPages);

View file

@ -74,22 +74,20 @@ class NotesTheme extends Themelet
];
}
$page->add_html_header("<script type='text/javascript'>
window.notes = ".json_encode($to_json).";
window.notes = ".json_encode_ex($to_json).";
window.notes_image_id = $image_id;
window.notes_admin = ".($adminOptions ? "true" : "false").";
</script>");
}
/**
* @param array<array{0:Image}> $images
* @param array<Image> $images
*/
public function display_note_list(array $images, int $pageNumber, int $totalPages): void
{
global $page;
$pool_images = '';
foreach ($images as $pair) {
$image = $pair[0];
foreach ($images as $image) {
$thumb_html = $this->build_thumb_html($image);
$pool_images .= '<span class="thumb">'.
@ -104,18 +102,15 @@ class NotesTheme extends Themelet
}
/**
* @param array<array{0:Image}> $images
* @param array<Image> $images
*/
public function display_note_requests(array $images, int $pageNumber, int $totalPages): void
{
global $page;
$pool_images = '';
foreach ($images as $pair) {
$image = $pair[0];
foreach ($images as $image) {
$thumb_html = $this->build_thumb_html($image);
$pool_images .= '<span class="thumb">'.
' <a href="$image_link">'.$thumb_html.'</a>'.
'</span>';

View file

@ -205,25 +205,25 @@ class NumericScore extends Extension
$totaldate = $year."/".$month."/".$day;
$sql = "SELECT id FROM images
WHERE EXTRACT(YEAR FROM posted) = :year
";
$sql = "SELECT id FROM images WHERE EXTRACT(YEAR FROM posted) = :year";
$args = ["limit" => $config->get_int(IndexConfig::IMAGES), "year" => $year];
if ($event->page_matches("popular_by_day")) {
$sql .=
"AND EXTRACT(MONTH FROM posted) = :month
AND EXTRACT(DAY FROM posted) = :day";
$sql .= " AND EXTRACT(MONTH FROM posted) = :month AND EXTRACT(DAY FROM posted) = :day";
$args = array_merge($args, ["month" => $month, "day" => $day]);
$dte = [$totaldate, date("F jS, Y", (strtotime($totaldate))), "\\y\\e\\a\\r\\=Y\\&\\m\\o\\n\\t\\h\\=m\\&\\d\\a\\y\\=d", "day"];
$current = date("F jS, Y", strtotime_ex($totaldate)).
$name = "day";
$fmt = "\\y\\e\\a\\r\\=Y\\&\\m\\o\\n\\t\\h\\=m\\&\\d\\a\\y\\=d";
} elseif ($event->page_matches("popular_by_month")) {
$sql .= "AND EXTRACT(MONTH FROM posted) = :month";
$sql .= " AND EXTRACT(MONTH FROM posted) = :month";
$args = array_merge($args, ["month" => $month]);
$dte = [$totaldate, date("F Y", (strtotime($totaldate))), "\\y\\e\\a\\r\\=Y\\&\\m\\o\\n\\t\\h\\=m", "month"];
$current = date("F Y", strtotime_ex($totaldate));
$name = "month";
$fmt = "\\y\\e\\a\\r\\=Y\\&\\m\\o\\n\\t\\h\\=m";
} elseif ($event->page_matches("popular_by_year")) {
$dte = [$totaldate, $year, "\\y\\e\\a\\r\=Y", "year"];
$current = "$year";
$name = "year";
$fmt = "\\y\\e\\a\\r\=Y";
} else {
// this should never happen due to the fact that the page event is already matched against earlier.
throw new \UnexpectedValueException("Error: Invalid page event.");
@ -234,7 +234,7 @@ class NumericScore extends Extension
$ids = $database->get_col($sql, $args);
$images = Search::get_images($ids);
$this->theme->view_popular($images, $dte);
$this->theme->view_popular($images, $totaldate, $current, $name, $fmt);
}
}

View file

@ -70,9 +70,8 @@ class NumericScoreTheme extends Themelet
/**
* @param Image[] $images
* @param string[] $dte
*/
public function view_popular(array $images, array $dte): void
public function view_popular(array $images, string $totaldate, string $current, string $name, string $fmt): void
{
global $page, $config;
@ -81,12 +80,12 @@ class NumericScoreTheme extends Themelet
$pop_images .= $this->build_thumb_html($image)."\n";
}
$b_dte = make_link("popular_by_".$dte[3], date($dte[2], (strtotime('-1 '.$dte[3], strtotime($dte[0])))));
$f_dte = make_link("popular_by_".$dte[3], date($dte[2], (strtotime('+1 '.$dte[3], strtotime($dte[0])))));
$b_dte = make_link("popular_by_$name", date($fmt, strtotime_ex("-1 $name", strtotime_ex($totaldate))));
$f_dte = make_link("popular_by_$name", date($fmt, strtotime_ex("+1 $name", strtotime_ex($totaldate))));
$html = "\n".
"<h3 style='text-align: center;'>\n".
" <a href='{$b_dte}'>&laquo;</a> {$dte[1]} <a href='{$f_dte}'>&raquo;</a>\n".
" <a href='{$b_dte}'>&laquo;</a> {$current} <a href='{$f_dte}'>&raquo;</a>\n".
"</h3>\n".
"<br/>\n".$pop_images;

View file

@ -69,7 +69,7 @@ class _SafeOuroborosImage
// meta
$this->change = intval($img->id); //DaFug is this even supposed to do? ChangeID?
// Should be JSON specific, just strip this when converting to XML
$this->created_at = ['n' => 123456789, 's' => strtotime($img->posted), 'json_class' => 'Time'];
$this->created_at = ['n' => 123456789, 's' => strtotime_ex($img->posted), 'json_class' => 'Time'];
$this->id = intval($img->id);
$this->parent_id = null;
@ -139,19 +139,19 @@ class OuroborosPost extends _SafeOuroborosImage
$this->rating = $post['rating'];
}
if (array_key_exists('source', $post)) {
$this->file_url = filter_var(
$this->file_url = filter_var_ex(
urldecode($post['source']),
FILTER_SANITIZE_URL
);
}
if (array_key_exists('sourceurl', $post)) {
$this->source = filter_var(
$this->source = filter_var_ex(
urldecode($post['sourceurl']),
FILTER_SANITIZE_URL
);
}
if (array_key_exists('description', $post)) {
$this->description = filter_var(
$this->description = filter_var_ex(
$post['description'],
FILTER_SANITIZE_STRING
);
@ -260,7 +260,7 @@ class OuroborosAPI extends Extension
if ($this->match('create')) {
// Create
if ($user->can(Permissions::CREATE_IMAGE)) {
$md5 = !empty($_REQUEST['md5']) ? filter_var($_REQUEST['md5'], FILTER_SANITIZE_STRING) : null;
$md5 = !empty($_REQUEST['md5']) ? filter_var_ex($_REQUEST['md5'], FILTER_SANITIZE_STRING) : null;
$this->postCreate(new OuroborosPost($_REQUEST['post']), $md5);
} else {
$this->sendResponse(403, 'You cannot create new posts');
@ -269,17 +269,17 @@ class OuroborosAPI extends Extension
throw new SCoreException("update not implemented");
} elseif ($this->match('show')) {
// Show
$id = !empty($_REQUEST['id']) ? (int)filter_var($_REQUEST['id'], FILTER_SANITIZE_NUMBER_INT) : null;
$id = !empty($_REQUEST['id']) ? (int)filter_var_ex($_REQUEST['id'], FILTER_SANITIZE_NUMBER_INT) : null;
$this->postShow($id);
} elseif ($this->match('index') || $this->match('list')) {
// List
$limit = !empty($_REQUEST['limit']) ? intval(
filter_var($_REQUEST['limit'], FILTER_SANITIZE_NUMBER_INT)
filter_var_ex($_REQUEST['limit'], FILTER_SANITIZE_NUMBER_INT)
) : 45;
$p = !empty($_REQUEST['page']) ? intval(
filter_var($_REQUEST['page'], FILTER_SANITIZE_NUMBER_INT)
filter_var_ex($_REQUEST['page'], FILTER_SANITIZE_NUMBER_INT)
) : 1;
$tags = !empty($_REQUEST['tags']) ? filter_var($_REQUEST['tags'], FILTER_SANITIZE_STRING) : [];
$tags = !empty($_REQUEST['tags']) ? filter_var_ex($_REQUEST['tags'], FILTER_SANITIZE_STRING) : [];
if (is_string($tags)) {
$tags = Tag::explode($tags);
}
@ -288,23 +288,23 @@ class OuroborosAPI extends Extension
} elseif ($event->page_matches('tag')) {
if ($this->match('index') || $this->match('list')) {
$limit = !empty($_REQUEST['limit']) ? intval(
filter_var($_REQUEST['limit'], FILTER_SANITIZE_NUMBER_INT)
filter_var_ex($_REQUEST['limit'], FILTER_SANITIZE_NUMBER_INT)
) : 50;
$p = !empty($_REQUEST['page']) ? intval(
filter_var($_REQUEST['page'], FILTER_SANITIZE_NUMBER_INT)
filter_var_ex($_REQUEST['page'], FILTER_SANITIZE_NUMBER_INT)
) : 1;
$order = (!empty($_REQUEST['order']) && ($_REQUEST['order'] == 'date' || $_REQUEST['order'] == 'count' || $_REQUEST['order'] == 'name')) ? filter_var(
$order = (!empty($_REQUEST['order']) && ($_REQUEST['order'] == 'date' || $_REQUEST['order'] == 'count' || $_REQUEST['order'] == 'name')) ? filter_var_ex(
$_REQUEST['order'],
FILTER_SANITIZE_STRING
) : 'date';
$id = !empty($_REQUEST['id']) ? intval(
filter_var($_REQUEST['id'], FILTER_SANITIZE_NUMBER_INT)
filter_var_ex($_REQUEST['id'], FILTER_SANITIZE_NUMBER_INT)
) : null;
$after_id = !empty($_REQUEST['after_id']) ? intval(
filter_var($_REQUEST['after_id'], FILTER_SANITIZE_NUMBER_INT)
filter_var_ex($_REQUEST['after_id'], FILTER_SANITIZE_NUMBER_INT)
) : null;
$name = !empty($_REQUEST['name']) ? filter_var($_REQUEST['name'], FILTER_SANITIZE_STRING) : '';
$name_pattern = !empty($_REQUEST['name_pattern']) ? filter_var(
$name = !empty($_REQUEST['name']) ? filter_var_ex($_REQUEST['name'], FILTER_SANITIZE_STRING) : '';
$name_pattern = !empty($_REQUEST['name_pattern']) ? filter_var_ex(
$_REQUEST['name_pattern'],
FILTER_SANITIZE_STRING
) : '';
@ -344,13 +344,13 @@ class OuroborosAPI extends Extension
$meta['rating'] = $post->rating;
}
// Check where we should try for the file
if (empty($post->file) && !empty($post->file_url) && filter_var(
if (empty($post->file) && !empty($post->file_url) && filter_var_ex(
$post->file_url,
FILTER_VALIDATE_URL
) !== false
) {
// Transload from source
$meta['file'] = tempnam(sys_get_temp_dir(), 'shimmie_transload_' . $config->get_string(UploadConfig::TRANSLOAD_ENGINE));
$meta['file'] = shm_tempnam('transload_' . $config->get_string(UploadConfig::TRANSLOAD_ENGINE));
$meta['filename'] = basename($post->file_url);
try {
fetch_url($post->file_url, $meta['file']);
@ -470,9 +470,6 @@ class OuroborosAPI extends Extension
}
$tags = [];
foreach ($tag_data as $tag) {
if (!is_array($tag)) {
continue;
}
$tags[] = new _SafeOuroborosTag($tag);
}
$this->sendData('tag', $tags, $start);
@ -517,7 +514,7 @@ class OuroborosAPI extends Extension
$response['location'] = $response['reason'];
unset($response['reason']);
}
$response = json_encode($response);
$response = json_encode_ex($response);
} elseif ($this->type == 'xml') {
// Seriously, XML sucks...
$xml = new \XMLWriter();
@ -546,7 +543,7 @@ class OuroborosAPI extends Extension
global $page;
$response = '';
if ($this->type == 'json') {
$response = json_encode($data);
$response = json_encode_ex($data);
} elseif ($this->type == 'xml') {
$xml = new \XMLWriter();
$xml->openMemory();
@ -575,7 +572,7 @@ class OuroborosAPI extends Extension
private function createItemXML(\XMLWriter $xml, string $type, _SafeOuroborosTag|_SafeOuroborosImage $item): void
{
$xml->startElement($type);
foreach (json_decode(json_encode($item)) as $key => $val) {
foreach (json_decode(json_encode_ex($item)) as $key => $val) {
if ($key == 'created_at' && $type == 'post') {
$xml->writeAttribute($key, $val['s']);
} else {

View file

@ -250,15 +250,6 @@ class Pools extends Extension
}
$this->list_pools($page, $page_num, $search);
} elseif ($event->page_matches("pool")) {
$pool_id = 0;
$pool = [];
// Check if we have pool id, since this is most often the case.
if (isset($_POST["pool_id"])) {
$pool_id = int_escape($_POST["pool_id"]);
$pool = $this->get_single_pool($pool_id);
}
// What action are we trying to perform?
switch ($event->get_arg(0)) {
case "new": // Show form for new pools
@ -305,6 +296,9 @@ class Pools extends Extension
break;
case "edit": // Edit the pool (remove images)
$pool_id = int_escape($_POST["pool_id"]);
$pool = $this->get_single_pool($pool_id);
if ($this->have_permission($user, $pool)) {
$result = $database->execute("SELECT image_id FROM pool_images WHERE pool_id=:pid ORDER BY image_order ASC", ["pid" => $pool_id]);
$images = [];
@ -319,6 +313,9 @@ class Pools extends Extension
break;
case "order": // Order the pool (view and change the order of images within the pool)
$pool_id = int_escape($_POST["pool_id"]);
$pool = $this->get_single_pool($pool_id);
if (isset($_POST["order_view"])) {
if ($this->have_permission($user, $pool)) {
$result = $database->execute(
@ -363,6 +360,9 @@ class Pools extends Extension
}
break;
case "reverse":
$pool_id = int_escape($_POST["pool_id"]);
$pool = $this->get_single_pool($pool_id);
if ($this->have_permission($user, $pool)) {
$database->with_savepoint(function () use ($pool_id) {
global $database;
@ -389,6 +389,9 @@ class Pools extends Extension
}
break;
case "import":
$pool_id = int_escape($_POST["pool_id"]);
$pool = $this->get_single_pool($pool_id);
if ($this->have_permission($user, $pool)) {
$images = Search::find_images(
limit: $config->get_int(PoolsConfig::MAX_IMPORT_RESULTS, 1000),
@ -401,6 +404,9 @@ class Pools extends Extension
break;
case "add_posts":
$pool_id = int_escape($_POST["pool_id"]);
$pool = $this->get_single_pool($pool_id);
if ($this->have_permission($user, $pool)) {
$image_ids = array_map('intval', $_POST['check']);
send_event(new PoolAddPostsEvent($pool_id, $image_ids));
@ -412,6 +418,9 @@ class Pools extends Extension
break;
case "remove_posts":
$pool_id = int_escape($_POST["pool_id"]);
$pool = $this->get_single_pool($pool_id);
if ($this->have_permission($user, $pool)) {
$images = "";
foreach ($_POST['check'] as $imageID) {
@ -435,6 +444,9 @@ class Pools extends Extension
break;
case "edit_description":
$pool_id = int_escape($_POST["pool_id"]);
$pool = $this->get_single_pool($pool_id);
if ($this->have_permission($user, $pool)) {
$database->execute(
"UPDATE pools SET description=:dsc,lastupdated=CURRENT_TIMESTAMP WHERE id=:pid",
@ -451,6 +463,9 @@ class Pools extends Extension
case "nuke":
// Completely remove the given pool.
// -> Only admins and owners may do this
$pool_id = int_escape($_POST["pool_id"]);
$pool = $this->get_single_pool($pool_id);
if ($user->can(Permissions::POOLS_ADMIN) || $user->id == $pool->user_id) {
send_event(new PoolDeletionEvent($pool_id));
$page->set_mode(PageMode::REDIRECT);
@ -575,7 +590,7 @@ class Pools extends Extension
}
if ($pool && $this->have_permission($user, $pool)) {
$image_order = ($matches[2] ?: 0);
$image_order = (int)($matches[2] ?: 0);
$this->add_post($pool->id, $event->image_id, true, $image_order);
}
}

View file

@ -19,7 +19,7 @@ class PoolsTheme extends Themelet
* Adds a block to the panel with information on the pool(s) the image is in.
* $navIDs = Multidimensional array containing pool id, info & nav IDs.
*
* @param array<int,array{nav:array{prev:?int,next:?int},info:Pool}> $navIDs
* @param array<int,array{info:Pool,nav:array{prev:?int,next:?int}|null}> $navIDs
*/
public function pool_info(array $navIDs): void
{
@ -30,12 +30,14 @@ class PoolsTheme extends Themelet
foreach ($navIDs as $poolID => $poolInfo) {
$div = DIV(SHM_A("pool/view/" . $poolID, $poolInfo["info"]->title));
if(!empty($poolInfo["nav"])) {
if (!empty($poolInfo["nav"]["prev"])) {
$div->appendChild(SHM_A("post/view/" . $poolInfo["nav"]["prev"], "Prev", class: "pools_prev_img"));
}
if (!empty($poolInfo["nav"]["next"])) {
$div->appendChild(SHM_A("post/view/" . $poolInfo["nav"]["next"], "Next", class: "pools_next_img"));
}
}
$linksPools->appendChild($div);
}

View file

@ -304,6 +304,7 @@ class Ratings extends Extension
$results = $database->get_col("SELECT DISTINCT rating FROM images ORDER BY rating");
$original_values = [];
foreach ($results as $result) {
assert(is_string($result));
if (array_key_exists($result, ImageRating::$known_ratings)) {
$original_values[$result] = ImageRating::$known_ratings[$result]->name;
} else {

View file

@ -12,7 +12,7 @@ use function MicroHTML\{A,P,TABLE,TD,TH,TR};
class RatingsTheme extends Themelet
{
/**
* @param array<string, ImageRating> $ratings
* @param array<string, string> $ratings
* @param string[] $selected_options
*/
public function get_selection_rater_html(string $name = "rating", array $ratings = [], array $selected_options = []): HTMLElement
@ -30,7 +30,7 @@ class RatingsTheme extends Themelet
}
/**
* @param ImageRating[] $current_ratings
* @param array<string,string> $current_ratings
*/
public function display_form(array $current_ratings): void
{

View file

@ -23,9 +23,9 @@ class RelationshipsTest extends ShimmiePHPUnitTestCase
$image_id_2 = $this->post_image("tests/bedroom_workshop.jpg", "pbx");
$image_id_3 = $this->post_image("tests/favicon.png", "pbx");
$image_1 = Image::by_id($image_id_1);
$image_2 = Image::by_id($image_id_2);
$image_3 = Image::by_id($image_id_3);
$image_1 = null_throws(Image::by_id($image_id_1));
$image_2 = null_throws(Image::by_id($image_id_2));
$image_3 = null_throws(Image::by_id($image_id_3));
$this->assertNull($image_1['parent_id']);
$this->assertNull($image_2['parent_id']);
@ -48,9 +48,9 @@ class RelationshipsTest extends ShimmiePHPUnitTestCase
send_event(new ImageRelationshipSetEvent($image_2->id, $image_1->id));
// refresh data from database
$image_1 = Image::by_id($image_1->id);
$image_2 = Image::by_id($image_2->id);
$image_3 = Image::by_id($image_3->id);
$image_1 = null_throws(Image::by_id($image_1->id));
$image_2 = null_throws(Image::by_id($image_2->id));
$image_3 = null_throws(Image::by_id($image_3->id));
$this->assertNull($image_1['parent_id']);
$this->assertEquals($image_1->id, $image_2['parent_id']);
@ -72,9 +72,9 @@ class RelationshipsTest extends ShimmiePHPUnitTestCase
send_event(new ImageRelationshipSetEvent($image_2->id, $image_3->id));
// refresh data from database
$image_1 = Image::by_id($image_1->id);
$image_2 = Image::by_id($image_2->id);
$image_3 = Image::by_id($image_3->id);
$image_1 = null_throws(Image::by_id($image_1->id));
$image_2 = null_throws(Image::by_id($image_2->id));
$image_3 = null_throws(Image::by_id($image_3->id));
$this->assertNull($image_1['parent_id']);
$this->assertEquals($image_3->id, $image_2['parent_id']);
@ -112,9 +112,9 @@ class RelationshipsTest extends ShimmiePHPUnitTestCase
// FIXME: send_event(new ImageRelationshipSetEvent($image_2->id, null));
// refresh data from database
$image_1 = Image::by_id($image_1->id);
$image_2 = Image::by_id($image_2->id);
$image_3 = Image::by_id($image_3->id);
$image_1 = null_throws(Image::by_id($image_1->id));
$image_2 = null_throws(Image::by_id($image_2->id));
$image_3 = null_throws(Image::by_id($image_3->id));
$this->assertNull($image_1['parent_id']);
$this->assertNull($image_2['parent_id']);
@ -138,9 +138,9 @@ class RelationshipsTest extends ShimmiePHPUnitTestCase
$image_id_2 = $this->post_image("tests/bedroom_workshop.jpg", "pbx");
$image_id_3 = $this->post_image("tests/favicon.png", "pbx");
$image_1 = Image::by_id($image_id_1);
$image_2 = Image::by_id($image_id_2);
$image_3 = Image::by_id($image_id_3);
$image_1 = null_throws(Image::by_id($image_id_1));
$image_2 = null_throws(Image::by_id($image_id_2));
$image_3 = null_throws(Image::by_id($image_id_3));
$this->assertNull($image_1['parent_id']);
$this->assertNull($image_2['parent_id']);
@ -163,9 +163,9 @@ class RelationshipsTest extends ShimmiePHPUnitTestCase
send_event(new TagSetEvent($image_2, ["pbx", "parent:{$image_1->id}"]));
// refresh data from database
$image_1 = Image::by_id($image_1->id);
$image_2 = Image::by_id($image_2->id);
$image_3 = Image::by_id($image_3->id);
$image_1 = null_throws(Image::by_id($image_1->id));
$image_2 = null_throws(Image::by_id($image_2->id));
$image_3 = null_throws(Image::by_id($image_3->id));
$this->assertEquals(["pbx"], $image_2->get_tag_array());
$this->assertNull($image_1['parent_id']);
@ -189,9 +189,9 @@ class RelationshipsTest extends ShimmiePHPUnitTestCase
send_event(new TagSetEvent($image_3, ["pbx", "child:{$image_1->id}"]));
// refresh data from database
$image_1 = Image::by_id($image_1->id);
$image_2 = Image::by_id($image_2->id);
$image_3 = Image::by_id($image_3->id);
$image_1 = null_throws(Image::by_id($image_1->id));
$image_2 = null_throws(Image::by_id($image_2->id));
$image_3 = null_throws(Image::by_id($image_3->id));
$this->assertEquals(["pbx"], $image_3->get_tag_array());
$this->assertEquals($image_3->id, $image_1['parent_id']);

View file

@ -29,7 +29,7 @@ class ReplaceFile extends Extension
$this->theme->display_replace_page($page, $image_id);
} elseif($event->method == "POST") {
if (!empty($_POST["url"])) {
$tmp_filename = tempnam(ini_get('upload_tmp_dir'), "shimmie_transload");
$tmp_filename = shm_tempnam("transload");
fetch_url($_POST["url"], $tmp_filename);
send_event(new ImageReplaceEvent($image, $tmp_filename));
} elseif (count($_FILES) > 0) {
@ -78,7 +78,7 @@ class ReplaceFile extends Extension
// update metadata and save metadata to DB
$event->image->hash = $event->new_hash;
$event->image->filesize = filesize($target);
$event->image->filesize = filesize_ex($target);
$event->image->set_mime(MimeType::get_for_file($target));
send_event(new MediaCheckPropertiesEvent($image));
$image->save_to_db();

View file

@ -23,7 +23,7 @@ class ReplaceFileTest extends ShimmiePHPUnitTestCase
// check that the image is original
$image = Image::by_id($image_id);
$old_hash = md5_file("tests/pbx_screenshot.jpg");
$old_hash = md5_file_ex("tests/pbx_screenshot.jpg");
//$this->assertEquals("pbx_screenshot.jpg", $image->filename);
$this->assertEquals("image/jpeg", $image->get_mime());
$this->assertEquals(19774, $image->filesize);
@ -32,9 +32,9 @@ class ReplaceFileTest extends ShimmiePHPUnitTestCase
// replace it
// create a copy because the file is deleted after upload
$tmpfile = tempnam(sys_get_temp_dir(), "shimmie_test");
$tmpfile = shm_tempnam("test");
copy("tests/favicon.png", $tmpfile);
$new_hash = md5_file($tmpfile);
$new_hash = md5_file_ex($tmpfile);
$_FILES = [
'data' => [
'name' => 'favicon.png',

View file

@ -40,6 +40,9 @@ class ImageReport
}
}
/**
* @phpstan-type Report array{id: int, image: Image, reason: string, reporter_name: string}
*/
class ReportImage extends Extension
{
/** @var ReportImageTheme */
@ -211,7 +214,7 @@ class ReportImage extends Extension
}
/**
* @return array<array<string, mixed>>
* @return array<Report>
*/
public function get_reported_images(): array
{

View file

@ -6,10 +6,13 @@ namespace Shimmie2;
use function MicroHTML\INPUT;
/**
* @phpstan-type Report array{id: int, image: Image, reason: string, reporter_name: string}
*/
class ReportImageTheme extends Themelet
{
/**
* @param array<array{id: int, image: Image, reason: string, reporter_name: string}> $reports
* @param array<Report> $reports
*/
public function display_reported_images(Page $page, array $reports): void
{

View file

@ -94,7 +94,7 @@ class ResizeImage extends Extension
if (($fh = @fopen($image_filename, 'rb'))) {
//check if gif is animated (via https://www.php.net/manual/en/function.imagecreatefromgif.php#104473)
while (!feof($fh) && $isanigif < 2) {
$chunk = fread($fh, 1024 * 100);
$chunk = false_throws(fread($fh, 1024 * 100));
$isanigif += preg_match_all('#\x00\x21\xF9\x04.{4}\x00[\x2C\x21]#s', $chunk, $matches);
}
}
@ -186,7 +186,7 @@ class ResizeImage extends Extension
[$new_width, $new_height] = get_scaled_by_aspect_ratio($event->image->width, $event->image->height, $max_width, $max_height);
if ($new_width !== $event->image->width || $new_height !== $event->image->height) {
$tmp_filename = tempnam(sys_get_temp_dir(), 'shimmie_resize');
$tmp_filename = shm_tempnam('resize');
if (empty($tmp_filename)) {
throw new ImageResizeException("Unable to save temporary image file.");
}
@ -240,7 +240,7 @@ class ResizeImage extends Extension
$hash = $image_obj->hash;
$image_filename = warehouse_path(Image::IMAGE_DIR, $hash);
$info = getimagesize($image_filename);
$info = false_throws(getimagesize($image_filename));
if (($image_obj->width != $info[0]) || ($image_obj->height != $info[1])) {
throw new ImageResizeException("The current image size does not match what is set in the database! - Aborting Resize.");
}
@ -248,7 +248,7 @@ class ResizeImage extends Extension
list($new_height, $new_width) = $this->calc_new_size($image_obj, $width, $height);
/* Temp storage while we resize */
$tmp_filename = tempnam(sys_get_temp_dir(), 'shimmie_resize');
$tmp_filename = shm_tempnam('resize');
if (empty($tmp_filename)) {
throw new ImageResizeException("Unable to save temporary image file.");
}

View file

@ -110,7 +110,7 @@ class RotateImage extends Extension
throw new ImageRotateException("$image_filename does not exist.");
}
$info = getimagesize($image_filename);
$info = false_throws(getimagesize($image_filename));
$memory_use = Media::calc_memory_use($info);
$memory_limit = get_memory_limit();
@ -121,7 +121,7 @@ class RotateImage extends Extension
/* Attempt to load the image */
$image = imagecreatefromstring(file_get_contents($image_filename));
$image = imagecreatefromstring(file_get_contents_ex($image_filename));
if ($image == false) {
throw new ImageRotateException("Could not load image: ".$image_filename);
}
@ -143,7 +143,7 @@ class RotateImage extends Extension
}
/* Temp storage while we rotate */
$tmp_filename = tempnam(ini_get('upload_tmp_dir'), 'shimmie_rotate');
$tmp_filename = shm_tempnam('rotate');
if (empty($tmp_filename)) {
throw new ImageRotateException("Unable to save temporary image file.");
}
@ -173,7 +173,7 @@ class RotateImage extends Extension
throw new ImageRotateException("Could not save image: ".$tmp_filename);
}
$new_hash = md5_file($tmp_filename);
$new_hash = md5_file_ex($tmp_filename);
/* Move the new image into the main storage location */
$target = warehouse_path(Image::IMAGE_DIR, $new_hash);
if (!@copy($tmp_filename, $target)) {

View file

@ -40,7 +40,7 @@ class RSSComments extends Extension
$comment_id = $comment['comment_id'];
$link = make_http(make_link("post/view/$image_id"));
$owner = html_escape($comment['user_name']);
$posted = date(DATE_RSS, strtotime($comment['posted']));
$posted = date(DATE_RSS, strtotime_ex($comment['posted']));
$comment = html_escape($comment['comment']);
$content = html_escape("$owner: $comment");

View file

@ -109,7 +109,7 @@ class RSSImages extends Extension
$tags = html_escape($image->get_tag_list());
$thumb_url = $image->get_thumb_link();
$image_url = $image->get_image_link();
$posted = date(DATE_RSS, false_throws(strtotime($image->posted)));
$posted = date(DATE_RSS, strtotime_ex($image->posted));
$content = html_escape(
"<div>" .
"<p>" . $this->theme->build_thumb_html($image) . "</p>" .

View file

@ -247,7 +247,7 @@ class S3 extends Extension
$client->putObject([
'Bucket' => $image_bucket,
'Key' => $key,
'Body' => file_get_contents($image->get_image_filename()),
'Body' => file_get_contents_ex($image->get_image_filename()),
'ACL' => 'public-read',
'ContentType' => $image->get_mime(),
'ContentDisposition' => "inline; filename=\"$friendly\"",

View file

@ -348,7 +348,7 @@ class Setup extends Extension
public function onSetupBuilding(SetupBuildingEvent $event): void
{
$themes = [];
foreach (false_throws(glob("themes/*")) as $theme_dirname) {
foreach (glob_ex("themes/*") as $theme_dirname) {
$name = str_replace("themes/", "", $theme_dirname);
$human = str_replace("_", " ", $name);
$human = ucwords($human);
@ -423,7 +423,7 @@ class Setup extends Extension
}
}
log_warning("setup", "Configuration updated");
foreach (glob("data/cache/*.css") as $css_cache) {
foreach (glob_ex("data/cache/*.css") as $css_cache) {
unlink($css_cache);
}
log_warning("setup", "Cache cleared");

View file

@ -29,7 +29,7 @@ class XMLSitemap extends Extension
file_put_contents($cache_path, $xml);
}
$xml = file_get_contents($cache_path);
$xml = file_get_contents_ex($cache_path);
$page->set_mode(PageMode::DATA);
$page->set_mime(MimeType::XML_APPLICATION);
$page->set_data($xml);
@ -67,7 +67,7 @@ class XMLSitemap extends Extension
"post/view/$image->id",
"weekly",
"0.8",
date("Y-m-d", strtotime($image->posted))
date("Y-m-d", strtotime_ex($image->posted))
);
}
@ -87,7 +87,7 @@ class XMLSitemap extends Extension
"post/view/$image->id",
"monthly",
"0.6",
date("Y-m-d", strtotime($image->posted))
date("Y-m-d", strtotime_ex($image->posted))
);
}

View file

@ -189,7 +189,7 @@ class SourceHistory extends Extension
}
if (isset($_POST['revert_ip']) && !empty($_POST['revert_ip'])) {
$revert_ip = filter_var($_POST['revert_ip'], FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE);
$revert_ip = filter_var_ex($_POST['revert_ip'], FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE);
if ($revert_ip === false) {
// invalid ip given.

View file

@ -48,7 +48,7 @@ class StaticFiles extends Extension
$page->add_http_header("Cache-control: public, max-age=600");
$page->add_http_header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 600) . ' GMT');
$page->set_mode(PageMode::DATA);
$page->set_data(file_get_contents($filename));
$page->set_data(file_get_contents_ex($filename));
$page->set_mime(MimeType::get_for_file($filename));
}

View file

@ -126,7 +126,7 @@ class TagCategories extends Extension
$tc_keyed_dict = [];
foreach ($tc_dict as $row) {
$tc_keyed_dict[$row['category']] = $row;
$tc_keyed_dict[(string)$row['category']] = $row;
}
return $tc_keyed_dict;

View file

@ -10,6 +10,6 @@ class TagEditCloudInfo extends ExtensionInfo
public string $key = self::KEY;
public string $name = "Tag EditCloud";
public array $authors = ["AtomicDryad", "Luana Latte" => "luana.latte.cat@gmail.com"];
public array $authors = ["AtomicDryad" => null, "Luana Latte" => "luana.latte.cat@gmail.com"];
public string $description = "Add or remove tags to the editor via clicking.";
}

View file

@ -163,7 +163,7 @@ class TagEditCloud extends Extension
}
$size = sprintf("%.2f", max($row['scaled'], 0.5));
$js = html_escape('tageditcloud_toggle_tag(this,'.json_encode($full_tag).')'); //Ugly, but it works
$js = html_escape('tageditcloud_toggle_tag(this,'.json_encode_ex($full_tag).')'); //Ugly, but it works
if (in_array($row['tag'], $image->get_tag_array())) {
if ($used_first) {

View file

@ -238,7 +238,7 @@ class TagHistory extends Extension
}
if (isset($_POST['revert_ip']) && !empty($_POST['revert_ip'])) {
$revert_ip = filter_var($_POST['revert_ip'], FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE);
$revert_ip = filter_var_ex($_POST['revert_ip'], FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE);
if ($revert_ip === false) {
// invalid ip given.

View file

@ -251,7 +251,7 @@ class TagList extends Extension
md5("tc" . $tags_min . $starts_with . VERSION)
);
if (file_exists($cache_key)) {
return file_get_contents($cache_key);
return file_get_contents_ex($cache_key);
}
$tag_data = $database->get_all("
@ -307,7 +307,7 @@ class TagList extends Extension
md5("ta" . $tags_min . $starts_with . VERSION)
);
if (file_exists($cache_key)) {
return file_get_contents($cache_key);
return file_get_contents_ex($cache_key);
}
$tag_data = $database->get_pairs("
@ -389,7 +389,7 @@ class TagList extends Extension
md5("tp" . $tags_min . VERSION)
);
if (file_exists($cache_key)) {
return file_get_contents($cache_key);
return file_get_contents_ex($cache_key);
}
$tag_data = $database->get_all("

View file

@ -121,7 +121,7 @@ class Tips extends Extension
$data_href = get_base_href();
$url = $data_href."/ext/tips/images/";
$dirPath = dir('./ext/tips/images');
$dirPath = dir_ex('./ext/tips/images');
$images = [];
while (($file = $dirPath->read()) !== false) {
if ($file[0] != ".") {

View file

@ -391,9 +391,9 @@ class TranscodeImage extends Extension
$q = $config->get_int(TranscodeConfig::QUALITY);
$tmp_name = tempnam(sys_get_temp_dir(), "shimmie_transcode");
$tmp_name = shm_tempnam("transcode");
$image = imagecreatefromstring(file_get_contents($source_name));
$image = false_throws(imagecreatefromstring(file_get_contents_ex($source_name)));
try {
$result = false;
switch ($target_mime) {
@ -467,7 +467,7 @@ class TranscodeImage extends Extension
break;
}
$tmp_name = tempnam(sys_get_temp_dir(), "shimmie_transcode");
$tmp_name = shm_tempnam("transcode");
$source_type = FileExtension::get_for_mime($source_mime);

View file

@ -211,7 +211,7 @@ class TranscodeVideo extends Extension
}
$original_file = warehouse_path(Image::IMAGE_DIR, $image->hash);
$tmp_filename = false_throws(tempnam(sys_get_temp_dir(), "shimmie_transcode_video"));
$tmp_filename = shm_tempnam("transcode_video");
$tmp_filename = $this->transcode_video($original_file, $image->video_codec, $target_mime, $tmp_filename);
send_event(new ImageReplaceEvent($image, $tmp_filename));
return true;

View file

@ -94,7 +94,7 @@ class Update extends Extension
$zip = new \ZipArchive();
if ($zip->open("./data/update_$commitSHA.zip") === true) {
for ($i = 1; $i < $zip->numFiles; $i++) {
$filename = $zip->getNameIndex($i);
$filename = false_throws($zip->getNameIndex($i));
if (substr($filename, -1) !== "/") {
copy("zip://".dirname(dirname(__DIR__)).'/'."./data/update_$commitSHA.zip"."#".$filename, substr($filename, 50));

View file

@ -45,8 +45,8 @@ class DataUploadEvent extends Event
{
assert(is_readable($tmpname));
$this->tmpname = $tmpname;
$this->hash = md5_file($tmpname);
$this->size = filesize($tmpname);
$this->hash = md5_file_ex($tmpname);
$this->size = filesize_ex($tmpname);
$mime = $mime ?? MimeType::get_for_file($tmpname, get_file_ext($this->metadata["filename"]) ?? null);
if (empty($mime)) {
throw new UploadException("Could not determine mime type");
@ -381,7 +381,7 @@ class Upload extends Extension
global $page, $config, $user, $database;
$results = [];
$tmp_filename = tempnam(ini_get('upload_tmp_dir'), "shimmie_transload");
$tmp_filename = shm_tempnam("transload");
try {
// Fetch file

View file

@ -80,7 +80,7 @@ class UploadTest extends ShimmiePHPUnitTestCase
public function testRejectHuge(): void
{
// FIXME: huge.dat is rejected for other reasons; manual testing shows that this works
file_put_contents("data/huge.jpg", file_get_contents("tests/pbx_screenshot.jpg") . str_repeat("U", 1024 * 1024 * 3));
file_put_contents("data/huge.jpg", file_get_contents_ex("tests/pbx_screenshot.jpg") . str_repeat("U", 1024 * 1024 * 3));
$e = $this->assertException(UploadException::class, function () {
$this->post_image("data/huge.jpg", "test");
});

View file

@ -40,7 +40,7 @@ class UploadTheme extends Themelet
$tl_enabled = ($config->get_string(UploadConfig::TRANSLOAD_ENGINE, "none") != "none");
$max_size = $config->get_int(UploadConfig::SIZE);
$max_kb = to_shorthand_int($max_size);
$max_total_size = parse_shorthand_int(ini_get('post_max_size'));
$max_total_size = parse_shorthand_int(ini_get('post_max_size') ?: "0");
$max_total_kb = to_shorthand_int($max_total_size);
$upload_list = $this->build_upload_list();
@ -253,7 +253,7 @@ class UploadTheme extends Themelet
$max_size = $config->get_int(UploadConfig::SIZE);
$max_kb = to_shorthand_int($max_size);
$max_total_size = parse_shorthand_int(ini_get('post_max_size'));
$max_total_size = parse_shorthand_int(ini_get('post_max_size') ?: "0");
$max_total_kb = to_shorthand_int($max_total_size);
// <input type='hidden' name='max_file_size' value='$max_size' />

View file

@ -831,7 +831,7 @@ class UserPage extends Extension
"You need to specify the account number to edit"
));
} else {
$uid = int_escape($_POST['id']);
$uid = int_escape((string)$_POST['id']);
$duser = User::by_id($uid);
log_warning("user", "Deleting user #{$uid} (@{$duser->name})");

View file

@ -1,6 +1,6 @@
parameters:
errorFormat: raw
level: 6
level: 7
paths:
- ../core
- ../ext

View file

@ -112,7 +112,7 @@ class CustomCommentListTheme extends CommentListTheme
$h_del = "";
if ($user->can(Permissions::DELETE_COMMENT)) {
$comment_preview = substr(html_unescape($tfe->stripped), 0, 50);
$j_delete_confirm_message = json_encode("Delete comment by {$comment->owner_name}:\n$comment_preview");
$j_delete_confirm_message = json_encode_ex("Delete comment by {$comment->owner_name}:\n$comment_preview");
$h_delete_script = html_escape("return confirm($j_delete_confirm_message);");
$h_delete_link = make_link("comment/delete/$i_comment_id/$i_image_id");
$h_del = " - <a onclick='$h_delete_script' href='$h_delete_link'>Del</a>";

View file

@ -112,7 +112,7 @@ class CustomCommentListTheme extends CommentListTheme
$h_del = "";
if ($user->can(Permissions::DELETE_COMMENT)) {
$comment_preview = substr(html_unescape($tfe->stripped), 0, 50);
$j_delete_confirm_message = json_encode("Delete comment by {$comment->owner_name}:\n$comment_preview");
$j_delete_confirm_message = json_encode_ex("Delete comment by {$comment->owner_name}:\n$comment_preview");
$h_delete_script = html_escape("return confirm($j_delete_confirm_message);");
$h_delete_link = make_link("comment/delete/$i_comment_id/$i_image_id");
$h_del = " - <a onclick='$h_delete_script' href='$h_delete_link'>Del</a>";

View file

@ -86,7 +86,7 @@ class CustomCommentListTheme extends CommentListTheme
$h_del = "";
if ($user->can(Permissions::DELETE_COMMENT)) {
$comment_preview = substr(html_unescape($tfe->stripped), 0, 50);
$j_delete_confirm_message = json_encode("Delete comment by {$comment->owner_name}:\n$comment_preview");
$j_delete_confirm_message = json_encode_ex("Delete comment by {$comment->owner_name}:\n$comment_preview");
$h_delete_script = html_escape("return confirm($j_delete_confirm_message);");
$h_delete_link = make_link("comment/delete/$i_comment_id/$i_image_id");
$h_del = " - <a onclick='$h_delete_script' href='$h_delete_link'>Del</a>";

View file

@ -87,7 +87,7 @@ EOD;
$generated = autodate(date('c'));
$footer_html = $this->footer_html();
$header_inc = file_get_contents("themes/rule34v2/header.inc");
$header_inc = file_get_contents_ex("themes/rule34v2/header.inc");
assert($header_inc !== false);
$header_inc = str_replace('$QUERY', $query, $header_inc);
return <<<EOD